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)