python 实现对偶单纯形法

昨天熬了一个通宵,女朋友写运筹学作业有个对偶单纯形法的题,据说是算了一天,感觉题无解,但是想确定一下,就很烦躁。我开始搜了一下,但是网上的代码都用不了,所以咱就研究了一下单纯形法和对偶单纯形法,用python写了个程序,百分百可用!用不了私信我!

对偶单纯形法

对偶单纯形法是指从对偶可行性逐步搜索出原始问题最优解的方法。由线性规划问题的对偶理论,原始问题的检验数对应于对偶问题的一组基本可行解或最优解;原始问题的一组基本可行解或最优解对应于对偶问题的检验数;原始问题约束方程的系数矩阵的转置是对偶问题约束条件方程的系数矩阵。所以,在求解常数项小于零的线性规划问题时,可以把原始问题的常数项视为对偶问题的检验数,原始问题的检验数视为对偶问题的常数项。

原理就不说了,直接上代码

from fractions import Fraction
# print(Fraction(2,2))
Cj=[-15,Fraction(3,4),-5,0,0] #要求的函数
list1=[[-2,0,-6,-1,1,0],[-1,-5,-2,-1,0,1]] #每个子列表第一位为b
z=[0,-15,-24,-5,0,0]#
Xb=[4,5]#
Cb=[0,0]
def show():

    print("--" * 50)
    print("|               Cj               ",end='|')
    for i in Cj:
        print(str(i).center(10),end='|')
    print(" "*10+"|")
    print("--"*50)
    print("|    Cb    |    Xb    |    b     ",end='|')
    for i in range(len(Cj)):
        print(("X"+str(i+1)).center(10),end='|')
    print(" "*10+"|")
    print("--" * 50)
    for i in range(len(list1)):
        print("|",end="")
        print(str(Cb[i]).center(10),end='|')
        print(("X"+str(Xb[i])).center(10),end='|')
        print(str(list1[i][0]).center(10),end="|")
        for j in range(1,len(list1[1])):
            print(str(list1[i][j]).center(10),end="|")
        print(" " * 10 + "|")
        print("--" * 50)
    print("|          Z          ",end='|')
    for i in range(len(z)):
        if i==0:
            print(str(z[i]).center(10),end='|')
        else:
            print(str(z[i]).center(10), end='|')
    print(" "*10+"|")
    print("--" * 50)
    print("**" * 50)
def fu():
    min_=0
    for i in range(len(list1)):
        if list1[i][0]<list1[min_][0]:
            min_=i

    min_2=1
    for i in range(1,len(list1[1])):
        if list1[min_][i]<0 :
            min_2=i
            break
    for i in range(min_2+1,len(list1[1])):
        if list1[min_][i]<0:
            if Fraction(z[i],list1[min_][i])<Fraction(z[min_2],list1[min_][min_2]):
                min_2=i
    temp=list1[min_][min_2]

    for i in range(len(list1[1])):
        list1[min_][i]=Fraction(list1[min_][i],temp)
    Xb[min_]=min_2
    Cb[min_]=Cj[min_2-1]

    for i in range(len(list1)):
        temp1 = 0 - list1[i][min_2]
        for j in range(len(list1[1])):
            if i !=min_:
                list1[i][j]=Fraction(list1[i][j],1)+list1[min_][j]*temp1



    for i in range(1,len(z)):
        z[i] = Cj[i-1]
        for j in range(len(list1)):
            z[i]=z[i]-Cb[j]*list1[j][i]

    z[0]=0
    for i in range(len(list1)):
        z[0]=z[0]+list1[i][0]*Cb[i]
show()
while True:
    flag = 1
    for i in range(len(list1)):
        if(list1[i][0]<0):
            flag=0
            break
    for i in range(1, len(z)):
        if z[i] > 0:
            flag = 0
            break
    if flag==0:
        fu()
        show()
    else:
        break

11/15修复了输出函数

要修改的部分

Cj=[-9,-12,-15,0,0,0] #要求的函数
list1=[[-10,-2,-2,-1,1,0,0],[-12,-2,-3,-1,0,1,0],[-14,-1,-1,-5,0,0,1]] #每个子列表第一位为b
z=[0,-9,-12,-15,0,0,0]#
Xb=[4,5,6]#
Cb=[0,0,0]#

在程序里这几个列表都是通过相同下标相关,看图和上面对应应该可以看懂,不会用直接私信我或者评论都可以!

注:分数要用Fraction(分子,分母)这么写,如:

 

例题运行结果

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

白帽Chen_D

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

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

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

打赏作者

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

抵扣说明:

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

余额充值