钢管切割下料--python

该文章介绍了一个算法,用于解决如何从标准6米长的钢管中,以最小数量的切割次数,截出指定长度的需求。算法首先对需求进行排序,然后逐步选取最长的长度进行切割,并寻找剩余部分的最佳组合,直至所有需求满足。此方法可用于资源优化和生产计划等领域。
摘要由CSDN通过智能技术生成

'''
更新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)

        
 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值