关于用Python解决分支问题的了解

#整数约束(用于求解整数最优解,可能没有整数约束是最优解时小数,但是现实要求整数最优解)
import math
import scipy
import sys

def IntegerProblem(c, A_ub, B_ub, A_eq, B_eq):
    tmin = 1.0E-12  #设置爱一个很小的数,为了后面判断整数使用

    #先求解这个线性规划
    result = scipy.optimize.linprog(c=c, A_ub=A_ub, b_ub=B_ub, A_eq=A_eq, b_eq=B_eq)

    bestX = [sys.maxsize]*len(c)    #sys.maxsize是一个很大的值,这里创建一个和未知数一样大的数组
    if not (type(result.x) is float or result.status != 0):
        bestX = result.x    #如果不是浮点数就可以直接读取答案

    #这个是最优解
    bestVal = sum([x*y for x, y in zip(c, bestX)])

    #floor和ceil方法分别是取比一个小数小的最大整数和比一个小数大的最小整数,这里要想不小于,只有x为一个整数(浮点型整数?)
    if all(((x - math.floor(x) < tmin) or math.ceil(x) - x < tmin) for x in bestX):
        return [bestX, bestVal]
    else:   #分支定界
        ind = [i for i, x in enumerate(bestX) if x - math.floor(x) > tmin and math.ceil(x) - x > tmin][0]   #后面两个条件用来判断哪个位置的x是浮点数,enumerate返回的是某个元素的位置和其值
        newCon1 = [0]*len(A_ub[0])  #相当于创建了线性规划的不等式的右边,但是参数都是0
        newCon2 = [0]*len(A_ub[0]) #同样,这两步是为了后面添加条件x>=floor(x)和x<=ceil(x),这两个后面放在A_ub中判断到底是大好还是小号
        newCon1[ind] = -1   #这个是大于号,所以左右两边都取负号(x>=floor(x))
        newCon2[ind] = 1    #条件x<=ceil(x)
        new_A1_ub = A_ub.copy()
        new_A2_ub = A_ub.copy()
        new_A1_ub.append(newCon1)   #添加限制条件x>=ceil(x)
        new_A2_ub.append(newCon2)   #另一限制条件x<=floor(x),比较两者的大小
        new_B1_ub = B_ub.copy()
        new_B2_ub = B_ub.copy()
        new_B1_ub.append(-math.ceil(bestX[ind]))   #添加ceil(x),新的x的取值大于等于比x大的最小整数
        new_B2_ub.append(math.floor(bestX[ind]))

        #下面使用递归重新计算了不同的添加的两种限制条件下的极值,返回优的那一个
        result_1 = IntegerProblem(c, A_ub=new_A1_ub, B_ub=new_B1_ub, A_eq=A_eq, B_eq=B_eq)
        result_2 = IntegerProblem(c, A_ub=new_A2_ub, B_ub=new_B2_ub, A_eq=A_eq, B_eq=B_eq)

        if result_1[1] > result_2[1]:   #比较两者的bestVal
            return result_2
        else:
            return result_1

c = [3, 4, 1]
A = [[-1, -6, -2], [-2, 0, 0]]
b = [-5, -3]
Aeq = [[0, 0, 0]]
beq = [0]
print(IntegerProblem(c, A, b, Aeq, beq))
#[array([2., 0., 2.]), 8.0]

就是在不满足整数解的情况下添加条件(个人见解)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值