'''
更新10根解的算法
标准钢管6米/根,需要截断成不同长度的料,比如:
(1.2m, 0.8m*5, 2.3m, 4.1m, 0.65m*10, 3m*2, 1.8m, 1.9m*6, 1.5m, 5.1m*2, 3.1m*3)
如何获取最优计划:需要多少根标准钢管,每一根怎么截
https://blog.csdn.net/wosind/article/details/97177918?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.base
'''
def GetBestPlan(dict_plan):
"""
分解相同规格的需求并排序
{1.2: 1, 0.8: 5, 2.3: 1} => [1.2,0.8,0.8,0.8,0.8,0.8,2.3]
"""
planLis = [y for y in dict_plan for x in range(0, dict_plan[y])]
planLis.sort(reverse=True)
res = [] # 计划表
n = -1 # 当前分割序号
while planLis :
res.append([])
n += 1
Longest = planLis[0] # 取当前最长的一根加入计划
res[n].append(Longest)
surplusBest = [] # 剩余长度的最优组合
surplusLong = 6 - Longest # 剩余长度
if surplusLong == 0: # 剩余长度surplusLong为0,跳到下一根计划
planLis.remove(Longest)
continue
# 过滤超过剩余长度的
rightPrepare = list(filter(lambda x: x <= surplusLong, planLis[1:]))
if not rightPrepare: # 无可以分割项,跳到下一根计划
planLis.remove(Longest)
continue
left,right = 0,1 # 剩余长度组合标记
currentComp = [] # 当前组合
while left < len(rightPrepare) - 1:
# 当前组合为空,添加左标记
if not currentComp : currentComp.append(rightPrepare[left])
t = surplusLong - sum(currentComp)
if t == 0 : # 最佳计划,退出循环
surplusBest = currentComp
break
t = surplusLong - sum(currentComp) - rightPrepare[right]
if t < 0 :
# 组合超出剩余长度
# 对比最佳计划,如果更佳则替换
# 左标记右移,又标记还原到到左标记+1
if sum(currentComp) > sum(surplusBest) : surplusBest = currentComp
left += 1
right = left + 1
currentComp = []
else:
currentComp.append(rightPrepare[right])
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[n].append(x)
planLis.remove(x)
planLis.remove(Longest)
return res
if __name__ == '__main__':
test = {1.2: 1, 0.8: 5, 2.3: 1, 4.1: 1, 0.65: 10, 3: 2, 1.8: 1, 1.9: 6, 1.5: 1, 5.1: 2, 3.1: 3}
res = GetBestPlan(test)
print("下料总数:%d" % len(res))
for inx, item in enumerate(res):
print("No:%2d used:%.2f" % (inx + 1, sum(item)), item)