python,线材切割优化,如何计算切割后的剩余材料拼接问题?
本帖最后由 快乐的小驹 于 2024-2-5 12:23 编辑代码来源于CSDN--孤独半生的代码(不敢贴地址,怕管理员删帖)
如何计算切割后的剩余材料拼接问题?
当前计算结果:(浪费太严重了)
下料总数:5
序号: 1 使用长度:3500 最优切割方案:
序号: 2 使用长度:3500 最优切割方案:
序号: 3 使用长度:3500 最优切割方案:
序号: 4 使用长度:5000 最优切割方案:
序号: 5 使用长度:2500 最优切割方案:
我想要的结果:
下料总数:4
序号: 1 使用长度:3500 最优切割方案: 剩余材料
序号: 2 使用长度:3500 最优切割方案: 剩余材料[
序号: 3 使用长度:5000 最优切割方案: 剩余材料
序号: 4 使用长度:2500 最优切割方案: 剩余材料
拼接方案 使用长度:3500 最优切割方案: 序号: 1[+序号: 2[最优切割方案: 剩余材料
def GetBestPlan(dict_plan):
planLis = )]
planLis.sort(reverse=True)
res = []# 计划表
n = -1# 当前分割序号
while planLis:
res.append([])
n += 1
Longest = planLis# 取当前最长的一根加入计划
res.append(Longest)
yuancl = 6000
qixie = 6
qiefen = 3
surplusBest = []# 剩余长度的最优组合
surplusLong = yuancl- qixie - Longest# 原材料长度减斜头
if surplusLong == 0:# 剩余长度surplusLong为0,跳到下一根计划
planLis.remove(Longest)
continue
rightPrepare = list(filter(lambda x: x <= surplusLong, planLis))
if not rightPrepare:# 无可以分割项,跳到下一根计划
planLis.remove(Longest)
continue
left, right = 0, 1# 剩余长度组合标记
currentComp = []# 当前组合
while left < len(rightPrepare):
if not currentComp: currentComp.append(rightPrepare)
t = surplusLong - sum(currentComp)
if t == 0:# 最佳计划,退出循环
surplusBest = currentComp
break
if right < len(rightPrepare):
t = surplusLong - sum(currentComp) - rightPrepare
if t < 0:
# 组合超出剩余长度
# 对比最佳计划,如果更佳则替换
# 左标记右移,右标记还原到到左标记+1
if sum(currentComp) > sum(surplusBest): surplusBest = currentComp
left += 1
right = left + 1
currentComp = []
else:
currentComp.append(rightPrepare)
if right == len(rightPrepare) - 1:
# 如果右标记已经到末尾,对比最佳计划,如果更佳则替换
# 左标记右移1,右标记还原到左标记+1
if sum(currentComp) > sum(surplusBest): surplusBest = currentComp
left += 1
right = left + 1
currentComp = []
else:
# 右标记右移1
right += 1
else:
if sum(currentComp) > sum(surplusBest): surplusBest = currentComp
left += 1
right = left + 1
currentComp = []
# 添加到计划,并删除已添加项
for x in surplusBest:
res.append(x)
planLis.remove(x)
planLis.remove(Longest)
return res
test = {3500: 3, 2500: 3}
res = GetBestPlan(test)
print("下料总数:%d" % len(res))
for inx, item in enumerate(res):
print("序号:%2d 使用长度:%.0f 最优切割方案:" % (inx + 1, sum(item)), item)
优化切割出来后的线材,干吗用 sai609 发表于 2024-2-3 15:14
优化切割出来后的线材,干吗用
计算钢管一类的线条状材料怎么样切割不浪费材料~特别是切割量很大、切割的尺寸很多的时候~
快乐的小驹 发表于 2024-2-3 16:13
计算钢管一类的线条状材料怎么样切割不浪费材料~特别是切割量很大、切割的尺寸很多的时候~
我有个类似的EXCEL表格,你需要的话可以参考下 挺好一男的 发表于 2024-2-3 17:51
我有个类似的EXCEL表格,你需要的话可以参考下
非常感谢你~我编程的水平实在是太糟糕了~应该看不出什么来~再次感谢~ 代码没错啊,不过要稍微改下,那个类都没用,没必要。
输出结果:
下料总数:3
No: 1 used:5900
No: 2 used:800
No: 3 used:800
代码:
def GetBestPlan(dict_plan):
planLis = )]
planLis.sort(reverse=True)
res = []# 计划表
n = -1# 当前分割序号
while planLis :
res.append([])
n += 1
Longest = planLis# 取当前最长的一根加入计划
res.append(Longest)
surplusBest = []# 剩余长度的最优组合
surplusLong = 6000 - Longest# 6000是原材料长度
if surplusLong == 0:# 剩余长度surplusLong为0,跳到下一根计划
planLis.remove(Longest)
continue
# 过滤超过剩余长度的
rightPrepare = list(filter(lambda x: x <= surplusLong, planLis))
if not rightPrepare: # 无可以分割项,跳到下一根计划
planLis.remove(Longest)
continue
left,right = 0,1 # 剩余长度组合标记
currentComp = [] # 当前组合
while left < len(rightPrepare) - 1:
# 当前组合为空,添加左标记
if not currentComp : currentComp.append(rightPrepare)
t = surplusLong - sum(currentComp)
if t == 0 : # 最佳计划,退出循环
surplusBest = currentComp
break
t = surplusLong - sum(currentComp) - rightPrepare
if t < 0 :
# 组合超出剩余长度
# 对比最佳计划,如果更佳则替换
# 左标记右移,又标记还原到到左标记+1
if sum(currentComp) > sum(surplusBest) : surplusBest = currentComp
left += 1
right = left + 1
currentComp = []
else:
currentComp.append(rightPrepare)
if right == len(rightPrepare) - 1 :
# 如果右标记已经到末尾,对比最佳计划,如果更佳则替换
# 左标记右移1,右标记还原到左标记+1
if sum(currentComp) > sum(surplusBest): surplusBest = currentComp
left += 1
right = left + 1
currentComp = []
else:
# 右标记右移1
right += 1
# 添加到计划,并删除已添加项
for x in surplusBest:
res.append(x)
planLis.remove(x)
planLis.remove(Longest)
return res
test = {1200: 1, 800: 5, 2300: 1}#要切割的长度及数量
res = GetBestPlan(test)
print("下料总数:%d" % len(res))
for inx, item in enumerate(res):
print("No:%2d used:%.0f" % (inx + 1, sum(item)), item)#输出切割方法 如果要留着类GUI,修改下:
class GUI:
def GetBestPlan(dict_plan):
planLis = )]
planLis.sort(reverse=True)
res = []# 计划表
n = -1# 当前分割序号
while planLis :
res.append([])
n += 1
Longest = planLis# 取当前最长的一根加入计划
res.append(Longest)
surplusBest = []# 剩余长度的最优组合
surplusLong = 6000 - Longest# 6000是原材料长度
if surplusLong == 0:# 剩余长度surplusLong为0,跳到下一根计划
planLis.remove(Longest)
continue
# 过滤超过剩余长度的
rightPrepare = list(filter(lambda x: x <= surplusLong, planLis))
if not rightPrepare: # 无可以分割项,跳到下一根计划
planLis.remove(Longest)
continue
left,right = 0,1 # 剩余长度组合标记
currentComp = [] # 当前组合
while left < len(rightPrepare) - 1:
# 当前组合为空,添加左标记
if not currentComp : currentComp.append(rightPrepare)
t = surplusLong - sum(currentComp)
if t == 0 : # 最佳计划,退出循环
surplusBest = currentComp
break
t = surplusLong - sum(currentComp) - rightPrepare
if t < 0 :
# 组合超出剩余长度
# 对比最佳计划,如果更佳则替换
# 左标记右移,又标记还原到到左标记+1
if sum(currentComp) > sum(surplusBest) : surplusBest = currentComp
left += 1
right = left + 1
currentComp = []
else:
currentComp.append(rightPrepare)
if right == len(rightPrepare) - 1 :
# 如果右标记已经到末尾,对比最佳计划,如果更佳则替换
# 左标记右移1,右标记还原到左标记+1
if sum(currentComp) > sum(surplusBest): surplusBest = currentComp
left += 1
right = left + 1
currentComp = []
else:
# 右标记右移1
right += 1
# 添加到计划,并删除已添加项
for x in surplusBest:
res.append(x)
planLis.remove(x)
planLis.remove(Longest)
return res
test = {1200: 1, 800: 5, 2300: 1}#要切割的长度及数量
res = GUI.GetBestPlan(test)
print("下料总数:%d" % len(res))
for inx, item in enumerate(res):
print("No:%2d used:%.0f" % (inx + 1, sum(item)), item)#输出切割方法
helian147 发表于 2024-2-4 04:43
代码没错啊,不过要稍微改下,那个类都没用,没必要。
输出结果:
最后切割的两个800是错的,应该在一根上切割1600 快乐的小驹 发表于 2024-2-4 12:02
最后切割的两个800是错的,应该在一根上切割1600
哦那是我理解问题错了,还以为是代码无法运行。
你这问题是算法有问题。
页:
[1]