标准单纯形法Python实现

目录

1.简介

2.程序设计思路

3.程序代码

4.测试样例​


1.简介

采用表格形式的单纯形方法类似的解题步骤,用python编程实现,该程序以最小化问题的求解过程为方法,做到输入约束条件以及初始判别数(当目标函数为最小化问题时,输入值为目标函数系数的相反数;当目标函数为最大化问题时,输入值为目标函数系数),输出单纯形表和最优解以及最优值

2.程序设计思路

表格形单纯形法(以极小化为例)的步骤:

  1. 选取基变量(找单位矩阵)
  2. 计算各变量对应的判别数(基变量的判别数均为0)
  3. 找入基变量:判别数>0且为所有判别数中最大值所在列为对应的入基变量Xj
  4. 找出基变量:最右列(b)除以入基变量列对应值(>0)结果最小的所在行为出基变量Xi
  5. 把入基变量Xj替换出基变量Xi: 入基变量Xj列通过矩阵行变换使得第i行第j列为1,i行其他列为0
  6. 重复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.测试样例

 

 

  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别管我啦就是说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值