# -*- coding: utf-8 -*-
"""
Created on Fri Mar 15 10:12:59 2019
@author: zhangchaoyu
"""
"""
这里特用来处理供给平衡的运输问题
"""
def value_idex(e):
return e[-1]
def minimum_element(C, Br, Bc):
X = [[0 for j in range(len(C[i]))] for i in range(len(C))]
idexs = []
for i in range(len(C)):
for j in range(len(C[i])):
idexs.append([i,j,C[i][j]])
idexs.sort(key = value_idex)
for i in range(len(idexs)):
row = idexs[i][0]
col = idexs[i][1]
row_left = Br[row]
for k in range(len(X[row])):
if k != col:
row_left -= X[row][k]
col_left = Bc[col]
for k in range(len(X)):
if k != row:
col_left -= X[k][col]
X[row][col] = min(row_left,col_left)
print("最小元素法:"+ str(sum([sum([C[i][j]*X[i][j] for j in range(len(X[i]))]) for i in range(len(X))])))
return X
def vogel_1(C, Br, Bc):
row_used = []
col_used = []
X = [[0 for j in range(len(C[i]))] for i in range(len(C))]
while True:
row_can = []
col_can = []
for i in range(len(C)):
if i not in row_used:
row_can.append(i)
for i in range(len(C[0])):
if i not in col_used:
col_can.append(i)
if len(C) == len(row_used)+1:
idex_row = row_can[0]
for i in range(len(col_can)):
col_left = Bc[col_can[i]]
for j in range(len(X)):
if j != idex_row:
col_left -= X[j][col_can[i]]
X[idex_row][col_can[i]] = col_left
break
if len(C[0]) == len(col_used)+1:
idex_col = col_can[0]
for i in range(len(row_can)):
row_left = Br[row_can[i]]
for j in range(len(X[0])):
if j != idex_col:
row_left -= X[row_can[i]][j]
X[row_can[i]][idex_col] = row_left
break
Dr = []
Dc = []
for i in range(len(row_can)):
first = min(C[row_can[i]][col_can[0]],C[row_can[i]][col_can[1]])
second = max(C[row_can[i]][col_can[0]],C[row_can[i]][col_can[1]])
for j in range(2,len(col_can)):
if second > C[row_can[i]][col_can[j]]:
second = C[row_can[i]][col_can[j]]
first,second = min(first,second),max(first,second)
Dr.append(second-first)
for i in range(len(col_can)):
first = min(C[row_can[0]][col_can[i]],C[row_can[1]][col_can[i]])
second = max(C[row_can[0]][col_can[i]],C[row_can[1]][col_can[i]])
for j in range(2,len(row_can)):
if second > C[row_can[j]][col_can[i]]:
second = C[row_can[j]][col_can[i]]
first,second = min(first,second),max(first,second)
Dc.append(second-first)
row_max = Dr[0]
row_idex_max = row_can[0]
for i in range(1,len(Dr)):
if row_max < Dr[i]:
row_max = Dr[i]
row_idex_max = row_can[i]
col_max = Dc[0]
col_idex_max = col_can[0]
for i in range(1,len(Dc)):
if col_max < Dc[i]:
col_max = Dc[i]
col_idex_max = col_can[i]
if col_max > row_max:
idex_row = row_can[0]
for i in range(1,len(row_can)):
if C[idex_row][col_idex_max] > C[row_can[i]][col_idex_max]:
idex_row = row_can[i]
row_left = Br[idex_row]
for i in range(len(X[idex_row])):
if i != col_idex_max:
row_left -= X[idex_row][i]
col_left = Bc[col_idex_max]
for i in range(len(X)):
if i != idex_row:
col_left -= X[i][col_idex_max]
if row_left <= col_left:
X[idex_row][col_idex_max] = row_left
row_used.append(idex_row)
else:
X[idex_row][col_idex_max] = col_left
col_used.append(col_idex_max)
else:
idex_col = col_can[0]
for i in range(1,len(col_can)):
if C[row_idex_max][idex_col] > C[row_idex_max][col_can[i]]:
idex_col = col_can[i]
row_left = Br[row_idex_max]
for i in range(len(X[row_idex_max])):
if i != idex_col:
row_left -= X[row_idex_max][i]
col_left = Bc[idex_col]
for i in range(len(X)):
if i != row_idex_max:
col_left -= X[i][idex_col]
if row_left <= col_left:
X[row_idex_max][idex_col] = row_left
row_used.append(row_idex_max)
else:
X[row_idex_max][idex_col] = col_left
col_used.append(idex_col)
print(X)
print(X)
print("vogel法:"+ str(sum([sum([C[i][j]*X[i][j] for j in range(len(X[i]))]) for i in range(len(X))])))
return X
def vogel_2(C, Br, Bc):
idexs = []
for i in range(len(C)):
for j in range(len(C[i])):
dis_row = -1
for k in range(len(C[i])):
if C[i][k] - C[i][j] >= 0 and k != j:
if dis_row == -1:
dis_row = C[i][k] - C[i][j]
elif dis_row > C[i][k] - C[i][j]:
dis_row = C[i][k] - C[i][j]
dis_col = -1
for k in range(len(C)):
if C[k][j] - C[i][j] >= 0 and k != i:
if dis_col == -1:
dis_col = C[k][j] - C[i][j]
elif dis_col > C[k][j] - C[i][j]:
dis_col = C[k][j] - C[i][j]
if dis_row >= dis_col:
flag = 1
else:
flag = 2
idexs.append([i,j,C[i][j],flag,max(dis_row,dis_col)])
idexs.sort(key = value_idex, reverse = True)
X = [[0 for j in range(len(C[i]))] for i in range(len(C))]
for i in range(len(idexs)):
row = idexs[i][0]
col = idexs[i][1]
row_left = Br[row]
for k in range(len(X[row])):
if k != col:
row_left -= X[row][k]
col_left = Bc[col]
for k in range(len(X)):
if k != row:
col_left -= X[k][col]
X[row][col] = min(row_left,col_left)
print("最小元素法:"+ str(sum([sum([C[i][j]*X[i][j] for j in range(len(X[i]))]) for i in range(len(X))])))
return X
def examples_test(examples, test):
result1 = []
result2 = []
for i in range(len(examples)):
C = examples[i][0]
Br = examples[i][1]
Bc = examples[i][2]
X1 = minimum_element(C, Br, Bc)
result1.append(sum([sum([C[i][j]*X1[i][j] for j in range(len(X1[i]))]) for i in range(len(X1))]))
X2 = vogel_1(C, Br, Bc)
result2.append(sum([sum([C[i][j]*X2[i][j] for j in range(len(X1[i]))]) for i in range(len(X2))]))
for i in range(len(result1)):
print(str(result1[i]) + " " + str(result2[i]) + " " + str(test[i]))
examples = []
examples.append([[[3,11,3,10],[1,9,2,8],[7,4,10,5]],[7,4,9],[3,6,5,6]])
examples.append([[[10.8,1e10,1e10,1e10],[10.8,11.1,1e10,1e10],[10.8,11.1,11,1e10],[10.8,11.1,11,11.3],[10.8,11.1,11,11.3]],[10,15,25,20,30],[25,35,30,10]])
examples.append([[[10.8,1e10,1e10,1e10],[10.95,11.1,1e10,1e10],[11.1,11.25,11,1e10],[11.25,11.4,11.15,11.3],[10.8,11.1,11,11.3]],[10,15,25,20,30],[25,35,30,10]])
examples.append([[[2,3,5],[14,13,17],[7,8,3]],[2,2,1],[1,1,3]])
examples.append([[[2,15,13,4],[10,4,14,15],[9,14,16,13],[7,8,11,9]],[1,1,1,1],[1,1,1,1]])
test = [85, 1101.5, 1103.75, 40, 28]
#检验所有例子和结果
examples_test(examples, test)
C = examples[-1][0]
Br = examples[-1][1]
Bc = examples[-1][2]
X0 = minimum_element(C, Br, Bc)
X1= vogel_1(C, Br, Bc)