0/1整数规划-分枝界定法-python

#FOR MY LITTLE CUTE BABY You
import math
from scipy.optimize import linprog
import sys

#数据的输入,数据的输入部分因为要使用linprog函数,所以输入的格式要注意,在下面我把linprog函数的作用以及函数的参数输入方式写下来。

c= [-3,-4,-1,-2]
A = [[2,3,1,3]]
b=[4]
x0_bounds=(0,1)
x1_bounds=(0,1)
x2_bounds=(0,1)
x3_bounds=(0,1)

#定义一个可以利用分支界定法的函数
def mylove(c,A,b,bounds=(x0_bounds,x1_bounds,x2_bounds,x3_bounds),t=1.0E-12):
    res = linprog(c, A_ub=A, b_ub=b,bounds=(x0_bounds,x1_bounds,x2_bounds,x3_bounds))
    #因为会有超出界限的取法,所以定义一个最大值,向下继续循环
    if (type(res.x) is float):
        bestX=-1*[sys.maxsize]*len(c)
    else:
        bestX=res.x
    bestVal=sum([x*y for x,y in zip(c, bestX)])
    if all(((x-math.floor(x))t)  for x in bestX):
        return (bestVal,bestX)
    #如果不满足全部0-1之间整数输出的条件,就证明解里面有小数,这个时候需要把该小数化为0或者1
    else:
        ind = [i for i, x in enumerate(bestX) if (x-math.floor(x))>t and (x-math.ceil(x))
res = linprog(c, A_ub=A, b_ub=b, A_eq=Aeq, b_eq=beq,bounds=((0,1),(0,1)..))
函数各部分参数的作用:
比如我们要解决这样的一个问题:

max. 3x1+4x2+x3+2x4
s. t. 2x1+3x2+x3+3x4≦4,
x1, x2, x3, x4∈{1, 0}

这个函数只能求最小值,所以把目标等价替换成这个样子
min -3x1-4x2-x3-2x4
上述参数c代表的就是目标函数,输入格式为[-3,-4,-1,-2]

限制条件写成左边小于等于右边的形式
2x1+3x2+x3+3x4≦4
限制条件由A_ub,b_ub,A_eq,b_eq四个参数来表示,其中A_ub和b_ub表示的是不等条件的限制,A_eq和b_eq两个代表等式限制,例如这道题的输入格式就是这个样子:
A_ub=A=[[2,3,1,3]],因为或许会涉及到很多条件约束,所以采用两个[[条件1],[条件2],[条件3]]这种形式
b_ub=b=[4],b表示右边的数
然后因为这道题没有等式约束,所以A_eq,b_eq都不用写

每个参数的范围用bounds来表示
x1, x2, x3, x4∈{1, 0}
bounds代表的就是每个变量的范围,用bounds((0,1),(0,1),(0,1),(0,1))的形式


该函数返回的是一个非整数的最有规划,相当于ppt中的缓和形式的结果,需要利用我定义的函数来把说所有的结果限制在0-1之间。
使用的所有函数:

type(res.x) is float
type函数:
>>>type(1)


>>> type('runoob')


>>> type([2])


>>> type({0:'zero'})


这里使用type函数,就是为了判断一下res.x是否还是一个[]的形式,如果因为超过了限制条件,上面的函数返回的res.x的值就是nun,一个未识别的float,为了使得迭代能继续下去,就给 bestX=-1[sys.maxsize]*len(c)赋一个比较小的值,这样bestVal=sum([x*y for x,y in zip(c, bestX)])这个结果的值就会非常大,这个超过限制条件的结果我们就不采用。


zip(c, bestX)

zip函数:
>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b)     # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c)              # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped)          # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]


 

你可能感兴趣的:(python)