吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 732|回复: 8
收起左侧

[求助] python,线材切割优化,如何计算切割后的剩余材料拼接问题?

[复制链接]
快乐的小驹 发表于 2024-2-3 13:24
本帖最后由 快乐的小驹 于 2024-2-5 12:23 编辑

代码来源于CSDN--孤独半生的代码(不敢贴地址,怕管理员删帖)
如何计算切割后的剩余材料拼接问题?
当前计算结果:(浪费太严重了)

下料总数:5
序号: 1 使用长度:3500 最优切割方案: [3500]
序号: 2 使用长度:3500 最优切割方案: [3500]
序号: 3 使用长度:3500 最优切割方案: [3500]
序号: 4 使用长度:5000 最优切割方案: [2500, 2500]
序号: 5 使用长度:2500 最优切割方案: [2500]

我想要的结果:
下料总数:4
序号: 1 使用长度:3500 最优切割方案: [3500]剩余材料[2494]
序号: 2 使用长度:3500 最优切割方案: [3500]剩余材料[[2494]
序号: 3 使用长度:5000 最优切割方案: [2500, 2500]剩余材料[994]
序号: 4 使用长度:2500 最优切割方案: [2500]剩余材料[3494]

拼接方案 使用长度:3500 最优切割方案: 序号: 1[[2494]+序号: 2[[2494]最优切割方案:[3500] 剩余材料[2488]



[Python] 纯文本查看 复制代码
def GetBestPlan(dict_plan):
    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)
        
        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[1:]))

        if not rightPrepare:  # 无可以分割项,跳到下一根计划
            planLis.remove(Longest)
            continue

        left, right = 0, 1  # 剩余长度组合标记
        currentComp = []  # 当前组合
        while left < len(rightPrepare):
            if not currentComp: currentComp.append(rightPrepare[left])
            t = surplusLong - sum(currentComp)
            if t == 0:  # 最佳计划,退出循环
                surplusBest = currentComp
                break
            if right < len(rightPrepare):
                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
            else:
                if sum(currentComp) > sum(surplusBest): surplusBest = currentComp
                left += 1
                right = left + 1
                currentComp = []

        # 添加到计划,并删除已添加项
        for x in surplusBest:
            res[n].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)

QQ截图20240203161141.png

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

sai609 发表于 2024-2-3 15:14
优化切割出来后的线材,干吗用
 楼主| 快乐的小驹 发表于 2024-2-3 16:13
sai609 发表于 2024-2-3 15:14
优化切割出来后的线材,干吗用

计算钢管一类的线条状材料怎么样切割不浪费材料~特别是切割量很大、切割的尺寸很多的时候~
QQ截图20240203161141.png
挺好一男的 发表于 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
代码没错啊,不过要稍微改下,那个类都没用,没必要。

输出结果:
[Bash shell] 纯文本查看 复制代码
下料总数:3
No: 1 used:5900 [2300, 1200, 800, 800, 800]
No: 2 used:800 [800]
No: 3 used:800 [800]


代码:
[Python] 纯文本查看 复制代码
def GetBestPlan(dict_plan):

    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 = 6000 - Longest  # 6000是原材料长度

        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
 
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,修改下:

[Asm] 纯文本查看 复制代码
class GUI:
    def GetBestPlan(dict_plan):

        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 = 6000 - Longest  # 6000是原材料长度

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

哦那是我理解问题错了,还以为是代码无法运行。
你这问题是算法有问题。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止回复与主题无关非技术内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-12 06:15

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表