python实现分支定界法

使用python实现了一个分支定界法。

import gurobipy as gp
from gurobipy import GRB

#声明原始问题
model = gp.Model("model_parent1")
x = model.addVars(2, name = 'x', vtype = GRB.CONTINUOUS)

#声明原始方程和约束
model.setObjective(10*x[0] + 20*x[1] , GRB.MAXIMIZE)
model.addConstr(5*x[0] + 8*x[1] <= 60, "c0")
model.addConstr(x[0] <= 8, "c1")
model.addConstr(x[1] <= 4, "c2")
model.addConstr(x[0] >= 0, "c3")
model.addConstr(x[1] >= 0, "c4")
#model.optimize()
#model.write("model_integer.lp")

#定义解题函数
def branch_and_bound(model):
    
    # 初始化下限值
    #best_solution = None
    best_value = -1
    
    #声明count用来计数
    count=0
    
    # 初始化搜索队列,用对列实现分支循环
    queue = [model]
    
    print('\n开始运行--------------------------------------------------\n')
    # 开始搜索
    while queue:
        # 取出队列中的第一个元素
        sub_model = queue.pop(0)
        
        count=count+1
        
        print('--------------------------------------------------')
        print('第'+str(count)+'次:')
        # 求解子问题
        model.setParam(GRB.Param.LogToConsole, 0)
        sub_model.optimize()
        #print('\n求解完毕--------------------------------------------------\n')

        if sub_model.status == GRB.Status.OPTIMAL:
            print('打印该子问题的最优解和最优函数值:')
            print(sub_model.getObjective().getValue())
            print(sub_model.getAttr('X', x))
            print('\n')
        
        
        # 如果model可行且下限值更优,则更新最优解和最优值
        
            
    
        # 如果model不可行,则跳过
        if sub_model.status != GRB.Status.OPTIMAL:
            print('进入第1种情况,问题不可行\n')
            continue
                        
        elif sub_model.status == GRB.Status.OPTIMAL and sub_model.getObjective().getValue() >= best_value and sub_model.getAttr('X', x)[0] %1 ==0 and sub_model.getAttr('X', x)[1] %1 ==0:
            print('进入第2种情况,函数值为整数,且目标值大于下限值\n')
            #更新最优值
            best_value=sub_model.getObjective().getValue()
            #打印当前的函数值和最优值:
            print('该子问题的目标值和最优函数值为:')
            print(sub_model.getObjective().getValue())
            print(sub_model.getAttr('X', x))
            print('\n')
            
            
        # 如果model的值小于当前下限值,则跳过
        elif sub_model.getObjective().getValue() < best_value:
            print('进入第3种情况,目标值小于下限值,不再分支\n')
            continue
        
        # 函数值非整数,进行分支操作
        else:
            print('进入第4种情况,目标值不小于下限值,但函数不为整数,进行分支\n')
            i=0
            # 找到一个非整数变量
            for var in sub_model.getVars():
                #if var.vType != GRB.INTEGER:
                #print(i)
                #print(sub_model.getAttr('x', x)[i])
                if sub_model.getAttr('x', x)[i] %1 != 0:                

                # 取整数部分
                    val = int(var.x)
                    # 将变量取值限制为小于等于整数部分,然后将model加入到队列中。

                    
                    sub_model_left = sub_model.copy()
                    varleft = sub_model_left.getVars()
                    #print(varleft)
                    
                    sub_model_left.addConstr( varleft[i] <= val)
                    
                    sub_model_left.write("model_integer.lp")
                    queue.append(sub_model_left)

                    
                    # 将变量取值限制为大于等于整数部分+1,然后将model加入到队列中。
                    
                    sub_model_right = sub_model.copy()
                    varright = sub_model_right.getVars()
                    sub_model_right.addConstr(varright[i] >= val + 1)
                    
                    sub_model_right.write("right.lp")
                    queue.append(sub_model_right)
                i=i+1
   
   

branch_and_bound(model)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值