# -*- coding: utf-8 -*-
"""
Created on Mon Mar 18 16:25:16 2019
@author: zhangchaoyu
"""
import copy
import math
def show_1(C, D, A, B, X, vc, vd):
result = []
result.append(copy.deepcopy(C+vc))
result.append(copy.deepcopy(D+vd))
for i in range(len(A)):
result.append(copy.deepcopy(A[i]+[B[i]]))
for r in result:
print(r)
print("当前解:")
print("X="+str(X))
print()
def find_new_1(D, A, B):
idex_negative = -1
for i in range(len(D)):
if D[i] < 0 and (idex_negative == -1 or (idex_negative != -1 and D[i] < D[idex_negative])):
idex_negative = i
if idex_negative == -1:
print("第一阶段检验数无小于0项,已至最优")
return -1
flag = -1
row = -1
rate = -1
for i in range(len(B)):
if A[i][idex_negative] <= 0:
continue
if rate == -1 or (rate != -1 and rate > B[i]/A[i][idex_negative]):
flag = 1
row = i
rate = B[i]/A[i][idex_negative]
if flag == 1:
return [row, idex_negative]
else:
print("第一阶段检验数无小于0项,已至最优")
return -1
def adjust_1(idex_row, idex_col, A, B, C, D, idexs, X, vc, vd):
m = len(B)
n = len(D)
idexs[idex_row] = idex_col
rate = A[idex_row][idex_col]
for i in range(n):
A[idex_row][i] /= rate
B[idex_row] /= rate
for i in range(m):
if i == idex_row:
continue
rate = A[i][idex_col]/A[idex_row][idex_col]
B[i] -= rate*B[idex_row]
for j in range(n):
A[i][j] -= rate*A[idex_row][j]
rate = C[idex_col]/A[idex_row][idex_col]
for i in range(n):
C[i] -= rate*A[idex_row][i]
vc[0] -= rate*B[idex_row]
rate = D[idex_col]/A[idex_row][idex_col]
for i in range(n):
D[i] -= rate*A[idex_row][i]
vd[0] -= rate*B[idex_row]
for i in range(len(X)):
if i not in idexs:
X[i] = 0
else:
for j in range(len(idexs)):
if i == idexs[j]:
X[i] = B[j]
def find_new_2(C, A, B):
idex_positive = -1
for i in range(len(C)):
if C[i] > 0 and (idex_positive == -1 or (idex_positive != -1 and C[i] > C[idex_positive])):
idex_positive = i
if idex_positive == -1:
print("第二阶段检验数无大于0项,已至最优")
return -1
flag = -1
row = -1
rate = -1
flag_n = -1
for i in range(len(B)):
if A[i][idex_positive] < 0:
flag_n = 1
if A[i][idex_positive] <= 0:
continue
if rate == -1 or (rate != -1 and rate > B[i]/A[i][idex_positive]):
flag = 1
row = i
rate = B[i]/A[i][idex_positive]
if flag == 1:
return [row, idex_positive]
else:
if flag_n == 1:
print("第二阶段解无界")
return -3
else:
print("第二阶段检验数无大于0项,已至最优")
return -1
def adjust_2(idex_row, idex_col, A, B, C, idexs, X, v):
m = len(B)
n = len(C)
idexs[idex_row] = idex_col
rate = A[idex_row][idex_col]
for i in range(n):
A[idex_row][i] /= rate
B[idex_row] /= rate
for i in range(m):
if i == idex_row:
continue
rate = A[i][idex_col]/A[idex_row][idex_col]
B[i] -= rate*B[idex_row]
for j in range(n):
A[i][j] -= rate*A[idex_row][j]
rate = C[idex_col]/A[idex_row][idex_col]
for i in range(n):
C[i] -= rate*A[idex_row][i]
v[0] -= rate*B[idex_row]
for i in range(len(X)):
if i not in idexs:
X[i] = 0
else:
for j in range(len(idexs)):
if i == idexs[j]:
X[i] = B[j]
def show_2(C, A, B, X, v):
result = []
result.append(copy.deepcopy(C+v))
for i in range(len(A)):
result.append(copy.deepcopy(A[i]+[B[i]]))
for r in result:
print(r)
print("当前解:")
print("X="+str(X))
print()
def sub_data_integer(x):
if math.ceil(100*x)/100 - x <= 1e-10:
return math.ceil(100*x)/100
if x - math.floor(100*x)/100 <= 1e-10:
return math.floor(100*x)/100
return x
def data_integer(A, B, C, D, X, vc, vd):
for i in range(len(A)):
for j in range(len(A[i])):
A[i][j] = sub_data_integer(A[i][j])
for i in range(len(B)):
B[i] = sub_data_integer(B[i])
for i in range(len(C)):
C[i] = sub_data_integer(C[i])
for i in range(len(D)):
D[i] = sub_data_integer(D[i])
for i in range(len(X)):
X[i] = sub_data_integer(X[i])
vc[0] = sub_data_integer(vc[0])
vd[0] = sub_data_integer(vd[0])
def simplex(C0, A0, B0):
"""
返回值为[flag,X],flag=-2表示正常,flag=-3表示无界,flag=-4表示无解
"""
C = copy.deepcopy(C0)
A = copy.deepcopy(A0)
B = copy.deepcopy(B0)
for i in range(len(B)):
if B[i] >= 0:
continue
B[i] = -B[i]
for j in range(len(A[i])):
A[i][j] = -A[i][j]
C = C + [0 for i in range(len(B0))]
for i in range(len(A)):
temp = [0 for j in range(len(A))]
temp[i] = 1
A[i] = A[i] + copy.deepcopy(temp)
D = [sum([-A[j][i] for j in range(len(B))]) for i in range(len(C0))] + [0 for i in range(len(B0))]
vc = [0]
vd = [sum([-B[i] for i in range(len(B))])]
idexs = [len(C0)+i for i in range(len(A))]
X = [0 for i in range(len(C0))] + copy.deepcopy(B)
#开始第一阶段迭代计算
loop = 0
print("第一阶段第"+str(loop)+"次迭代后:")
show_1(C, D, A, B, X, vc, vd)
idex = find_new_1(D, A, B)
while True:
if idex == -1:
break
idex_row = idex[0]
idex_col = idex[1]
adjust_1(idex_row, idex_col, A, B, C, D, idexs, X, vc, vd)
data_integer(A, B, C, D, X, vc, vd)
loop += 1
print("第一阶段第"+str(loop)+"次迭代后:")
show_1(C, D, A, B, X, vc, vd)
idex = find_new_1(D, A, B)
#统计第一阶段结果,判断是否有可行解
#planC:综合考虑
if vd[0] != 0:
print("无可行解,当前近似解X="+str(X[:len(C0)]))
return [-4,X[:len(C0)]]
tests = [len(C0)+i for i in range(len(A))]
idexs_del = []
for i in range(len(idexs)):
if idexs[i] in tests:
if B[i] > 0:
print("无可行解,当前近似解X="+str(X[:len(C0)]))
return [-4,X[:len(C0)]]
idex_row = 0
for j in range(len(A)):
if A[j][idexs[i]] != 0:
idex_row = j
if sum([abs(A[idex_row][j]) for j in range(len(C0))]) == 0:
idexs_del.append(i)
else:
idex_col = 0
for i in range(len(C0)):
if A[idex_row][i] != 0:
idex_col = i
break
adjust_1(idex_row, idex_col, A, B, C, D, idexs, X, vc, vd)
data_integer(A, B, C, D, X, vc, vd)
B1 = []
A1 = []
for i in range(len(A)):
if i in idexs_del:
continue
B1.append(copy.deepcopy(B[i]))
A1.append(copy.deepcopy(A[i]))
B = B1
A = A1
#有可行解后,重新建立单纯形表
C = C[:len(C0)]
for i in range(len(A)):
A[i] = A[i][:len(C0)]
X = X[:len(C0)]
v = vc
#开始第二阶段迭代计算
loop = 0
print("第二阶段第"+str(loop)+"次迭代后:")
show_2(C, A, B, X, v)
idex = find_new_2(C, A, B)
while True:
if idex == -1 or idex == -3:
break
idex_row = idex[0]
idex_col = idex[1]
adjust_2(idex_row, idex_col, A, B, C, idexs, X, v)
data_integer(A, B, C, D, X, vc, vd)
loop += 1
print("第二阶段第"+str(loop)+"次迭代后:")
show_2(C, A, B, X, v)
idex = find_new_2(C,A,B)
print("当前解:")
print("X="+str(X))
print("最优值:")
print(sum([C0[i]*X[i] for i in range(len(X))]))
if idex == -3:
return [idex, X]
else:
return [-2,X,A,B]
def sub_Grmory(C0, A0, B0, I0):
C00 = copy.deepcopy(C0)
A00 = copy.deepcopy(A0)
B00 = copy.deepcopy(B0)
X = simplex(C00, A00, B00)
if X[0] <= -3:
return X
idex = -1
for i in range(I0):
if X[1][i] != int(X[1][i]):
idex = i
break
if idex == -1:
return X
C01 = copy.deepcopy(C00+[0 for i in range(len(A00))])
A01 = []
for j in range(len(A00)):
A01.append(copy.deepcopy(X[2][j]+[0 for i in range(len(A00))]))
for j in range(len(A00)):
temp1 = [math.floor(X[2][j][k]) for k in range(len(A00[j]))]
temp2 = [0 for i in range(len(A00))]
temp2[j] = 1
A01.append(copy.deepcopy(temp1+temp2))
B01 = copy.deepcopy(X[3]+[math.floor(X[3][j]) for j in range(len(B00))])
X1 = sub_Grmory(C01, A01, B01, I0)
return [X1[0],X1[1][:-len(A00)]]
def Grmory(C0, A0, B0, I0):
X = sub_Grmory(C0, A0, B0, I0)
if X[0] == -2:
print("正常解X:"+str(X[1]))
print(X[1])
print("最优值:")
print(sum([C0[i]*X[1][i] for i in range(len(X[1]))]))
elif X[0] == -3:
print("无界解,其中一个可行解X:")
print(X[1])
else:
print("无可行解")
return X[1]
examples = []
examples.append([[1,1,0,0],[[-1,1,1,0],[3,1,0,1]],[1,4],2])
C0 = examples[-1][0]
A0 = examples[-1][1]
B0 = examples[-1][2]
I0 = examples[-1][3]
X = Grmory(C0, A0, B0, I0)