列生成算法的python实现_gurobi求解器

20 篇文章 0 订阅
6 篇文章 0 订阅

问题:Cutting Stock Problem

讲解列生成算法的标配问题。可以百度,一百度一大把。
在这里插入图片描述

模型建立

在这里插入图片描述

代码实现

ref:改代码引用自gurobi官方示例。
个人感觉这个实现结构还是非常优秀的。


from gurobipy import *
TypesDemand = [3, 7, 9, 16]           		# 需求长度
QuantityDemand = [25, 30, 14, 8]      		# 需求的量
LengthUsable = 20                    		# 钢管长度
try:
    MainProbRelax = Model()                 # 松弛后的列生成主问题
    SubProb = Model()                       # 子问题

    # 构造主问题模型,选择的初始切割方案 每根钢管只切一种长度 
    # 添加变量
    Zp = MainProbRelax.addVars(len(TypesDemand), obj=1.0, vtype=GRB.CONTINUOUS, name = 'z')
    # 添加约束    
    ColumnIndex = MainProbRelax.addConstrs(quicksum(Zp[p] * (LengthUsable//TypesDemand[i]) \
    for p in range(len(TypesDemand)) if p==i) >= QuantityDemand[i] for i in range(len(TypesDemand)))  
    MainProbRelax.optimize()                # 求解


    # 构造子问题模型
    # 获得对偶值
    Dualsolution = MainProbRelax.getAttr(GRB.Attr.Pi, MainProbRelax.getConstrs())
    # 添加变量
    Ci = SubProb.addVars(len(TypesDemand), obj=Dualsolution, vtype=GRB.INTEGER, name = 'c')
    # 添加约束
    SubProb.addConstr(quicksum(Ci[i] * TypesDemand[i] for i in range(len(TypesDemand))) <= LengthUsable)
    SubProb.setAttr(GRB.Attr.ModelSense, -1) 	    # 设定优化方向             
    SubProb.optimize()                       		# 求解
    
    # 判断Reduced Cost是否小于零
    while SubProb.objval > 1:
           # 获取变量取值
           columnCoeff = SubProb.getAttr("X", SubProb.getVars())
           column = Column(columnCoeff, MainProbRelax.getConstrs())
           # 添加变量
           MainProbRelax.addVar(obj=1.0, vtype=GRB.CONTINUOUS, name="CG", column=column)
           MainProbRelax.optimize() 		# 求解
           # 修改子问题目标函数系数
           for i in range(len(TypesDemand)):
                Ci[i].obj = ColumnIndex[i].pi
           SubProb.optimize()
        
    # 将CG后的模型转为整数,并求解
    for v in MainProbRelax.getVars():
         v.setAttr("VType", GRB.INTEGER)
    MainProbRelax.optimize()
    for v in MainProbRelax.getVars():
         if v.X != 0.0:
              print('%s %g' % (v.VarName, v.X))

except GurobiError as e:
    print('Error code ' + str(e.errno) + ": " + str(e))

except AttributeError:
    print('Encountered an attribute error')     




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值