表格法求解线性规划问题代码实现
最近组合优化课程布置的课程作业,记录一下,也方便有需要的同学。 如果是要交作业的亲们,改下代码逻辑哈,加点没用的循环之类的,怕查重😅
代码实现
import numpy as np
# 获取目标函数 y = 2x1 + 3x2 即输入 2 3
def gettarget(column):
y = []
print("请输入目标函数:")
for i in range(0, column):
para = int(input())
y = y + [para]
return y
# 判断y系数是否全小于0
def belowzero(y):
flag = 0
for i in range(0, len(y)):
if y[i] < 0 :
flag = 1
break
return flag
if __name__ == '__main__':
# 获取约束条件:
# 例如:2x1 + x3 <= 4
# 则依次输入 2 0(x2的系数) 1 4
print("请输入问题相关信息:")
print("请输入变量个数:")
column = int(input()) # 原变量个数(不算松弛变量)即为列数
print("请输入约束条件个数:")
row = int(input()) # 约束条件数即为行数,也为即将添加的松弛变量个数
# 系数矩阵初始化
matrix = np.ones((row, column + 1))
print("请输入约束条件(系数为零的变量也需要输入):")
for r in range(0, row):
for c in range(0, column+1):
print("请输入第{.d}个约束条件中第{.d}个变量的系数")
matrix[r,c] = int(input())
y = gettarget(column)
print("y: ")
print(y)
print("s.t.: ")
print(matrix)
print("\n")
for i in range(0, len(y)):
y[i] = -y[i] # 目标函数系数取反
# 换个变量名方便阅读= =
stnum = row
vanum = column
# new[]矩阵为解决问题的变换矩阵
# 第0行: 非松弛变量角标,第0列:松弛变量角标
# 最后一行:目标函数系数,最后一列:约束条件系数以及目标函数极值
newrow = stnum
newcolumn = vanum
newvanum = vanum + stnum
new = np.zeros((newrow+2, newcolumn+2))
for i in range(1, vanum+1):
new[0][i] = i
for i in range(1, stnum+1):
new[i][0] = i + vanum
for i in range(1, vanum+2):
for j in range(1, stnum+1):
new[i][j] = st[i-1][j-1]
new[i][0] = i + vanum
print("表格:")
print(new)
# solve
target = 0 # 目标函数值
time = 1 # 循环次数
while(belowzero(y)):
print("第"+str(time)+"轮迭代:")
if time > vanum+stnum:
break
# 寻找关键元素
minratio = new[1][vanum+1]/new[1][1]
newretio = -1.0
position = [1, 1] # 关键元素的位置
for i in range(1, stnum+1):
for j in range(1, vanum+1):
newretio = new[i][vanum+1]/new[i][j]
if newretio>0:
if minratio<0:
minratio = newretio
if newretio<=minratio:
minratio = newretio
position[0] = i
position[1] = j
# 关键元素
key = new[position[0], position[1]]
print("key"+str(key))
# 用remain记录原new,再对new进行操作
remain = new.copy()
# 关键元素取倒
new[position[0], position[1]] = 1 / key
# 关键元素所在行变化
for i in range(1, vanum+2):
if i!= position[1]:
new[position[0], i] = remain[position[0], i] / key
# 关键元素所在列变化
for i in range(1, stnum+2):
if i != position[0]:
new[i, position[1]] = -1 * (remain[i, position[1]] / key)
# 非最后一列的其他位置变化
for i in range(1, stnum+2):
for j in range(1, vanum+1):
if((i!=position[0])&(j!=position[1])):
new[i][j] = remain[i][j] - (remain[i, position[1]] * remain[position[0], j] / key)
# 最后一列变化
for i in range(1, stnum+2):
if i != position[0]:
new[i][vanum+1] = new[i][vanum+1] - (remain[i, position[1]] * remain[position[0], vanum+1]/ key)
# 交换该次松弛变量与非松弛变量
xnum = remain[0, position[1]]
new[0, position[1]] = new[position[0], 0]
new[position[0], 0] = xnum
# 记录当前目标函数
for i in range(0, len(y)):
y[i] = new[stnum+1, i+1]
target = new[stnum+1][vanum+1]
print("new: ")
print(new)
print("\n")
time = time + 1
# 打印最终target值
print(target)