目录
1.简介
2.程序设计思路
3.程序代码
4.测试样例
1.简介
采用表格形式的单纯形方法类似的解题步骤,用python编程实现,该程序以最小化问题的求解过程为方法,做到输入约束条件以及初始判别数(当目标函数为最小化问题时,输入值为目标函数系数的相反数;当目标函数为最大化问题时,输入值为目标函数系数),输出单纯形表和最优解以及最优值
2.程序设计思路
表格形单纯形法(以极小化为例)的步骤:
- 选取基变量(找单位矩阵)
- 计算各变量对应的判别数(基变量的判别数均为0)
- 找入基变量:判别数>0且为所有判别数中最大值所在列为对应的入基变量Xj
- 找出基变量:最右列(b)除以入基变量列对应值(>0)结果最小的所在行为出基变量Xi
- 把入基变量Xj替换出基变量Xi: 入基变量Xj列通过矩阵行变换使得第i行第j列为1,i行其他列为0
- 重复2)至5)步,直至所有判别数均≤0,则找到最优解和最优值
3.程序代码
'''
标准单纯形法
'''
from fractions import Fraction as f
import numpy as np
def getinput():
global m,n,h
string = input('''
输入初始单纯形表形如
3 2 1 0 18;-1 4 0 1 8;-2 1 0 0 0
前m行表示m个约束的增广矩阵,最后一行表示判别数(
当目标函数为最小化问题时,输入值为目标函数系数的相反数;
当目标函数为最大化问题时,输入值为目标函数系数)
输入:''')
a = [list(map(eval,row.split())) for row in string.split(';')]
matrix = np.mat(a)
m,n = matrix.shape
h=input('''
若目标函数为极小化问题,则输入0;极大化问题,输入1
''')
x = []
if h == '1':
print('\n\n输入的目标函数为')
for j in range(n):
if matrix[-1, j] != 0:
x.append(f'{matrix[-1, j]}*x_{j + 1}')
print('max z = ' + ' + '.join(x))
else:
print('\n\n输入的目标函数为')
for j in range(n):
if matrix[-1, j] != 0:
x.append(f'{-matrix[-1, j]}*x_{j + 1}')
print('min z = ' + ' + '.join(x))
print('\n\n输入的方程为')
for i in range(m - 1):
x = [f'{matrix[i, j]}*x_{j + 1}' for j in range(n-1)]
print(' + '.join(x), f'={matrix[i, -1]}')
return matrix
def judge(matrix):
global maxj,index
maxj = matrix[-1][0]
index = 0
for j in range(n-1):
if matrix[-1][j] > maxj:
maxj= matrix[-1][j]
index = j
if matrix[-1][index] <= 0: # 最后一行除了b列的所有检验数
flag = False
else:
flag = True
return flag
def pr(matrix,vect): #输出单纯形表
print('*' * 20)
print(' ', end='\t')
for i in range(n - 1):
print('X_{}'.format(i + 1), end='\t')
print('b')
for i in range(m):
if i <= m - 2:
print('x_{}'.format(vect[i]), end='\t')
elif i == m - 1:
print('z-c', end='\t')
for j in range(n):
print(f(str(matrix[i][j])).limit_denominator(), end='\t') # 输出分数形式
print(end='\n')
def trans(a,matrix,vect): #转轴
l = {}
for i in range(m-1):
if matrix[i][index]>0:
l[matrix[i][-1]/matrix[i][index]]=i
pivot=l[min(l)]#出基变量的足标i(行)
matrix[pivot] = matrix[pivot] / matrix[pivot][index]
for i in range(m):
if i != pivot:
matrix[i] = matrix[i] - matrix[i][index] * matrix[pivot]
vect[pivot] = index + 1
return a,matrix,vect
def print_solution(matrix,vect):
print('*'*20)
for i in range(1,n+1):
if i in vect:
print('x{}*={}'.format(i,f(str(matrix[vect.index(i)][-1])).limit_denominator()),end=',')
else:
print('x{}*={}'.format(i,0),end=',')
if h == '1':
print('\nz*={}'.format(f(str(-matrix[-1][-1])).limit_denominator()))
else:
print('\nz*={}'.format(f(str(matrix[-1][-1])).limit_denominator()))
def main():
a = getinput()
matrix = np.array(a, dtype=np.float64) #array可以方便地进行整行的操作,而列表可以方便索引
vect=[]
h=n-1
for i in range(m):
h=h-i
vect.append(h)
pr(matrix,vect)
while judge(matrix):
a,matrix,vect = trans(a,matrix,vect)
pr(matrix,vect)
print_solution(matrix,vect)
if __name__ == '__main__':
main()
4.测试样例