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()