快乐的小驹 发表于 2024-2-3 13:24

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

sai609 发表于 2024-2-3 15:14
优化切割出来后的线材,干吗用

计算钢管一类的线条状材料怎么样切割不浪费材料~特别是切割量很大、切割的尺寸很多的时候~

挺好一男的 发表于 2024-2-3 17:51

快乐的小驹 发表于 2024-2-3 16:13
计算钢管一类的线条状材料怎么样切割不浪费材料~特别是切割量很大、切割的尺寸很多的时候~

我有个类似的EXCEL表格,你需要的话可以参考下

快乐的小驹 发表于 2024-2-3 18:13

挺好一男的 发表于 2024-2-3 17:51
我有个类似的EXCEL表格,你需要的话可以参考下

非常感谢你~我编程的水平实在是太糟糕了~应该看不出什么来~再次感谢~

helian147 发表于 2024-2-4 04:43

代码没错啊,不过要稍微改下,那个类都没用,没必要。

输出结果:
下料总数: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)#输出切割方法

helian147 发表于 2024-2-4 04:47

如果要留着类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)#输出切割方法

快乐的小驹 发表于 2024-2-4 12:02

helian147 发表于 2024-2-4 04:43
代码没错啊,不过要稍微改下,那个类都没用,没必要。

输出结果:


最后切割的两个800是错的,应该在一根上切割1600

helian147 发表于 2024-2-4 12:28

快乐的小驹 发表于 2024-2-4 12:02
最后切割的两个800是错的,应该在一根上切割1600

哦那是我理解问题错了,还以为是代码无法运行。
你这问题是算法有问题。
页: [1]
查看完整版本: python,线材切割优化,如何计算切割后的剩余材料拼接问题?