wood_cutting / app.py
rthvik07's picture
Upload 2 files
afce909
import numpy as np
from copy import deepcopy
from math import *
from collections import *
import sys
import streamlit as st
import time
def main():
st.set_page_config(page_title="Wood Cutting Algorithm")
start_time = time.time()
lst = []
n = st.number_input(
"Enter number of different types of wood sizes: ", min_value=1, step=1
)
for i in range(0, n):
ele = [
st.number_input(
"Enter number " + str(i) + " wood size: ", min_value=1, step=1
),
st.number_input(
"Enter number " + str(i) + " quantity: ", min_value=1, step=1
),
]
lst.append(ele)
cuts_dict = dict(lst)
cuts = list(cuts_dict.keys())
def getDesired(des_dict, Bo="No"):
if Bo == "No":
return des_dict
exis = st.selectbox("Is there existing inventory?", ["Yes", "No"])
if exis == "Yes":
for i in des_dict.keys():
val = st.number_input(
"How many boards of %d size are in existing inventory: " % i,
min_value=0,
step=1,
)
des_dict[i] = (des_dict[i] - val) if des_dict[i] >= val else 0
st.write(des_dict)
return des_dict
def getMin(des, prov):
minQua = sum([(k * v) for k, v in des.items()]) / prov
return dict(minQua)
def expansion(des):
cutlist = []
for k, v in des.items():
cutlist += [k] * v
return cutlist
def simplify(des, prov):
for i in des.keys():
val = prov // i
des[i] = val if val <= des[i] else des[i]
return des
def optimization(sols, des, prov):
des_keys = list(des.keys())
min_c = []
for i in range(len(prov)):
min_c += [prov[i]] * len(sols[i])
c = np.array(min_c)
A = [[] for i in range(len(des))]
for i in range(len(sols)):
for j in range(len(sols[0])):
for k in range(len(des)):
A[k].append(sols[i][j][des_keys[k]])
B = [((-1) * des[k]) for k in des.keys()]
print(B)
pass
def modulize(des, prov1, prov2, res, res_complete):
if len(des.keys()) == 0:
return res_complete
if min(des.keys()) > prov2:
return res_complete
des2 = deepcopy(des)
for i in des.keys():
des2.pop(i)
if prov2 % i == 0:
cnt = prov2 // i
if cnt > des[i]:
continue
res += [i] * cnt
if sum(res) == prov1:
res_complete.append(res)
res = []
if prov2 >= i:
cnt = prov2 // i
if cnt > des[i]:
cnt = des[i]
for coun in range(1, cnt + 1):
remain = prov2 - (coun * i)
res_min = [i] * coun
res_complete = modulize(
des2, prov1, remain, res + res_min, res_complete
)
return res_complete
def generate_cut_list(cut_dict):
cut_list = []
for key, value in cut_dict.items():
for i in range(value):
cut_list.append(int(key))
return cut_list
def wood_cutting(cut_list, sheet_size, max_sheets):
sheets = 0
rem_sheets = [0] * max_sheets
cuts_per_sheet = []
# loops through all cuts
for i in range(len(cut_list)):
j = 0
# Algorithm to find the best sheet to assign the cut
min_waste = sheet_size + 1
best_index = 0
for j in range(sheets):
if (
rem_sheets[j] >= cut_list[i]
and rem_sheets[j] - cut_list[i] < min_waste
):
best_index = j
min_waste = rem_sheets[j] - cut_list[i]
# If no sheet can accommodate the cut, then we create new sheet
if min_waste == sheet_size + 1:
rem_sheets[sheets] = sheet_size - cut_list[i]
cuts_per_sheet.append([cut_list[i]])
sheets += 1
# Assign the cut to best sheet
else:
rem_sheets[best_index] -= cut_list[i]
cuts_per_sheet[best_index].append(cut_list[i])
return (sheets, cuts_per_sheet, rem_sheets[:sheets])
def print_patterns(final, fid):
fin = []
for i in final:
fin.append(dict(Counter(i)))
print(dict(Counter(i)), file=fid)
return fin
def usable(waste):
if 0 in list(waste.keys()):
waste.pop(0)
usable_w = dict()
unusable_w = dict()
for k in waste.keys():
if k >= min(cuts):
usable_w[k] = waste[k]
else:
unusable_w[k] = waste[k]
return [usable_w, unusable_w]
def outPrint(final):
for i in final:
print(Counter(i))
return
def outComp(final1, final2):
for i in final1:
if i not in final2:
print(i)
for x in final2:
if x not in final1:
print(x)
return
def dictComp(dict1, dict2):
for key in list(dict1.keys()):
try:
if dict1[key] < dict2.get(key, 0):
return -1
except:
return -1
return 1
def dictSub(dict1, dict2):
dict3 = {key: dict1[key] - dict2.get(key, 0) for key in dict1.keys()}
return dict3
def mod_key(key, res):
key_c = []
for dict_res in res:
if key in dict_res.keys():
key_c.append(dict_res)
return key_c
def list_to_dict(final, target):
fin = []
for i in final:
if sum(i) == target:
if dict(Counter(i)) not in fin:
fin.append(dict(Counter(i)))
return fin
des = getDesired(cuts_dict, "Yes")
prov = st.number_input("Enter sheet size (in cm): ", min_value=1, step=1)
sols = []
des = simplify(des, prov)
sols.append(modulize(des, prov, prov, [], []))
sols = [x for x in sols if x]
sols = [expansion(des) + x for x in sols]
waste = []
for i in sols:
waste.append(prov - sum(i))
min_waste = min(waste)
sols_waste = [sols[x] for x in range(len(waste)) if waste[x] == min_waste]
final = []
for sol in sols_waste:
sheets, cuts_per_sheet, waste_per_sheet = wood_cutting(
generate_cut_list(cuts_dict), prov, len(sol)
)
if not waste_per_sheet:
final.append(sol)
else:
for i in range(len(sol)):
if waste_per_sheet[i] == 0:
continue
else:
temp_sol = deepcopy(sol)
temp_sol.remove(sol[i])
temp_sol += [waste_per_sheet[i]]
temp_sol = sorted(temp_sol)
if temp_sol not in final:
final.append(temp_sol)
st.write("Output:")
out = print_patterns(final, sys.stdout)
st.write(out)
if __name__ == "__main__":
main()