分支界定法求整数线性规划

import math
from scipy.optimize import linprog
import sys
import numpy as np
import time

class BinTree(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
"""
停止条件:
尚未设置子节点的节点列表为0
层次建树:
先做线性规划,如果高度和已经达到最高值或者无解则停止
"""

LvFW = [150, 200, 300]
a = [150, 150, 150, 150, 150, 150, 150, 150, 150, 150,
     150, 150, 150, 150, 150, 150, 150, 150, 150, 150,
     150, 150, 150, 150, 150, 150, 150, 150, 150, 150,
     150, 150, 150, 150, 150, 150, 150, 150,
     200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
     200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
     200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
     200, 200,
     300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
     300, 300, 300]

HighBin = 1800
asum = sum(a)

n = math.ceil(asum / HighBin)
L = [(38/9), (32/9), (13/9)]

C = ([150,150,150,150,150,150,150,150,150,200,200,200,200,200,200,200,200,200,300,300,300,300,300,300,300,300,300])
A = ([[1,1,1,1,1, 1,1,1,1,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0],
    [0,0,0,0,0, 0,0,0,0,1, 1,1,1,1,1, 1,1,1,0,0, 0,0,0,0,0, 0,0],
    [0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,1,1, 1,1,1,1,1, 1,1],
    [150,0,0,0,0, 0,0,0,0,200, 0,0,0,0,0, 0,0,0,300,0, 0,0,0,0,0, 0,0],
    [0,150,0,0,0, 0,0,0,0,0, 200,0,0,0,0, 0,0,0,0,300, 0,0,0,0,0, 0,0],
    [0,0,150,0,0, 0,0,0,0,0, 0,200,0,0,0, 0,0,0,0,0, 300,0,0,0,0, 0,0],
    [0,0,0,150,0, 0,0,0,0,0, 0,0,200,0,0, 0,0,0,0,0, 0,300,0,0,0, 0,0],
    [0,0,0,0,150, 0,0,0,0,0, 0,0,0,200,0, 0,0,0,0,0, 0,0,300,0,0, 0,0],
    [0,0,0,0,0, 150,0,0,0,0, 0,0,0,0,200, 0,0,0,0,0, 0,0,0,300,0, 0,0],
    [0,0,0,0,0, 0,150,0,0,0, 0,0,0,0,0, 200,0,0,0,0, 0,0,0,0,300, 0,0],
    [0,0,0,0,0, 0,0,150,0,0, 0,0,0,0,0, 0,200,0,0,0, 0,0,0,0,0, 300,0],
    [0,0,0,0,0, 0,0,0,150,0, 0,0,0,0,0, 0,0,200,0,0, 0,0,0,0,0, 0,300]
     ])
b = ([38, 32, 13, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800])

x151 = np.array([2, 6])
x152 = np.array([2, 6])
x153 = np.array([2, 6])
x154 = np.array([2, 6])
x155 = np.array([2, 6])
x156 = np.array([2, 6])
x157 = np.array([2, 6])
x158 = np.array([2, 6])
x159 = np.array([2, 6])
x201 = np.array([1, 5])
x202 = np.array([1, 5])
x203 = np.array([1, 5])
x204 = np.array([1, 5])
x205 = np.array([1, 5])
x206 = np.array([1, 5])
x207 = np.array([1, 5])
x208 = np.array([1, 5])
x209 = np.array([1, 5])
x301 = np.array([0, 4])
x302 = np.array([0, 4])
x303 = np.array([0, 4])
x304 = np.array([0, 4])
x305 = np.array([0, 4])
x306 = np.array([0, 4])
x307 = np.array([0, 4])
x308 = np.array([0, 4])
x309 = np.array([0, 4])
t=1.0E-5
now_Value_down = 0
best_value = 0 # 目标函数最大值
Lbest = [] # 最优结果对应的参数集合

# 按层次建立二叉树
# 尚未设置子节点的节点列表
nodeList = []
time1 = time.time()
res = linprog(-np.array(C), A, b, bounds=(x151, x152, x153, x154, x155, x156, x157, x158, x159, x201, x202, x203, x204,\
                                          x205, x206, x207, x208, x209, x301, x302, x303, x304, x305, x306, x307, x308,\
                                          x309))
time2 = time.time()
print(time2 - time1)
if (type(res.x) is not float):
    L_x = res.x
    Valsum = sum([x * y for x, y in zip(C, L_x)])
    print(Valsum)
    if all(((x-math.floor(x)) < t or (math.ceil(x)-x) < t) for x in L_x):
        if Valsum == asum:
            best_value = Valsum
            Lbest = L_x
        else:
            now_Value_down = Valsum
    else:
        value = [A,b,L_x]
        root = BinTree(value)
        nodeList.append(root)
else:
    print("别逗我,无解!!!!!")
newA1 = A.copy()
newA2 = A.copy()
newB1 = b.copy()
newB2 = b.copy()

while len(nodeList) != 0:
    tempvalue = nodeList[0].val[2]
    ind = [i for i, x in enumerate(tempvalue) if (x - math.floor(x)) > t and (math.ceil(x) - x) > t][0]
    newCon1 = [0] * len(tempvalue)
    newCon2 = [0] * len(tempvalue)
    newCon1[ind] = -1
    newCon2[ind] = 1
    tempnewA = nodeList[0].val[0]

    newA1 = tempnewA.copy()
    newA1.append(newCon1)

    newA2 = tempnewA.copy()
    newA2.append(newCon2)

    tempnewB = nodeList[0].val[1]
    newB1 = tempnewB.copy()
    newB1.append(-math.ceil(nodeList[0].val[2][ind]))
    newB2 = tempnewB.copy()
    newB2.append(math.floor(nodeList[0].val[2][ind]))
    nodeList.pop(0)

    r1 = linprog(-np.array(C), newA1, newB1, bounds=(x151, x152, x153, x154, x155, x156, x157, x158, x159, x201, x202, x203, x204,\
                                          x205, x206, x207, x208, x209, x301, x302, x303, x304, x305, x306, x307, x308,\
                                          x309))
    if (type(r1.x) is not float):
        L_x = r1.x
        Valsum = sum([x * y for x, y in zip(C, L_x)])
        #print(Valsum)
        if all(((x - math.floor(x)) < t or (math.ceil(x) - x) < t) for x in L_x):
            if Valsum == asum:
                best_value = Valsum
                Lbest = L_x
                nodeList = []
            elif Valsum > now_Value_down:
                now_Value_down = Valsum
                best_value = now_Value_down
                Lbest = L_x

        else:
            if Valsum > now_Value_down:
                value = [newA1, newB1, L_x]
                lefttree = BinTree(value)
                nodeList.append(lefttree)

    r2 = linprog(-np.array(C), newA2, newB2, bounds=(x151, x152, x153, x154, x155, x156, x157, x158, x159, x201, x202, x203, x204,\
                                          x205, x206, x207, x208, x209, x301, x302, x303, x304, x305, x306, x307, x308,\
                                          x309))

    if (type(r2.x) is not float):
        L_x = r2.x
        Valsum = sum([x * y for x, y in zip(C, L_x)])
        #print(Valsum)
        if all(((x - math.floor(x)) < t or (math.ceil(x) - x) < t) for x in L_x):
            if Valsum == asum:
                best_value = Valsum
                Lbest = L_x
                nodeList = []
            elif Valsum > now_Value_down:
                now_Value_down = Valsum
                best_value = now_Value_down
                Lbest = L_x

        else:
            if Valsum > now_Value_down:
                value = [newA2, newB2, L_x]
                lefttree = BinTree(value)
                nodeList.append(lefttree)
    #print(best_value)
time2 = time.time()
print(best_value)
print(Lbest)
print(time2 - time1)


猜你喜欢

转载自blog.csdn.net/lidongxx/article/details/88799392