单纯形法python实现

'''
max Z=2*x_1+3*x_2
        x_1+2*x_2<=8
      4*x_1<=16
            4*x_2<=12
        x_1,x_2>=0
'''
#add slack variables and transform the problem into standard form
'''
max Z=2*x_1+3*x_2+0*x_3+0*x_4+0*x_5
        x_1+2*x_2+x_3               ==8
      4*x_1              +x_4       ==16
            4*x_2              +x_5 ==12
        x_1,x_2,x_3,x_4,x_5>=0
'''
import numpy as np
Basic=[2,3,4]
Nonbasic=[0,1]
c=np.array([2,3,0,0,0]).astype(float)
c_B=np.array([0,0,0]).astype(float)
c_N=np.array([2,3]).astype(float)
A=np.array([[1,2,1,0,0]
            ,[4,0,0,1,0]
            ,[0,4,0,0,1]]).astype(float)
A_N=np.array([[1,2]
              ,[4,0]
              ,[0,4]])
b=np.array([8,16,12]).astype(float)
B_inv=np.array([[1,0,0]
                ,[0,1,0]
                ,[0,0,1]]).astype(float)
x_opt=np.array([0,0,0,0,0]).astype(float)
z_opt=0
solutionStatus=None

row_num=len(A)
column_num=len(A[0])
reductedCost=c_N-np.dot(np.dot(c_B,B_inv),A_N)
print(reductedCost)
max_sigma=max(reductedCost)
#print(np.argmax(reductedCost))
eps=0.001
iterNum=1

while(max_sigma>=eps):
    #determine the entering basic  variable
    enter_var_index=Nonbasic[np.argmax(reductedCost)]
    print('enter_var_index:',enter_var_index)

    #determine the leaving basic variable :minmum ratio test
    min_ratio=100
    leave_var_index=enter_var_index
    for i in range(row_num):#3
        #print('b:',b[i],'\t A:',A[i][enter_var_index],'\t  ratio:',b[i]/A[i][enter_var_index])
        if(A[i][enter_var_index]==0):
            #solutionStatus
           continue
            #return solutionStatus
        elif(b[i]/A[i][enter_var_index]<min_ratio and b[i]/A[i][enter_var_index]>0):
            min_ratio=b[i]/A[i][enter_var_index]
            leave_var_index=i
    print('min_ratio',min_ratio)
    # process entering basis and leaving basis
    print('leave_var_index:',leave_var_index)
    leave_var=Basic[leave_var_index]
    Basic[leave_var_index]=enter_var_index
    Nonbasic.remove(enter_var_index)
    Nonbasic.append(leave_var)
    #Nonbasic.sort()
    #Gaussian elimination
    #update pivot row
    pivot_number=A[leave_var_index][enter_var_index]
    print('pivot_number',pivot_number)#4
    for col in range(column_num):
        A[leave_var_index][col]=A[leave_var_index][col]/pivot_number
    b[leave_var_index]=b[leave_var_index]/pivot_number
    #update other rows
    for row in range(row_num):
        if(row!=leave_var_index):
            factor=-A[row][enter_var_index]/1.0
            for col in range(column_num):
                A[row][col]=A[row][col]+factor*A[leave_var_index][col]
            b[row]=b[row]+factor*b[leave_var_index]
    # update c_N,c_B,A_N,B_inv
    for i in range(len(Nonbasic)):
        var_index=Nonbasic[i]
        c_N[i]=c[var_index]
    for i in range(len(Basic)):
        var_index=Basic[i]
        c_B[i]=c[var_index]
    for i  in range(row_num):
        for j  in  range(len(Nonbasic)):
            var_index=Nonbasic[j]
            A_N[i][j]=A[i][var_index]
    for i in range(len(Basic)):
        col=Basic[i]
        for row in range(row_num):
            B_inv[row][i]=A[row][col]

    #update reduced cost
    reductedCost=c_N-np.dot(np.dot(c_B,B_inv),A_N)
    max_sigma=max(reductedCost)
    iterNum +=1
#check the solution status
for i in range(len(reductedCost)):
    if(reductedCost[i]==0):
        solutionStatus='Alternative optimal solution'
        break
    else:
        solutionStatus='optimal'
#get the solution
x_basic=np.dot(B_inv,b)
x_opt=np.array([0.0]*column_num).astype(float)
for i in range(len(Basic)):
    basic_var_index=Basic[i]
    x_opt[basic_var_index]=x_basic[i]
z_opt=np.dot(np.dot(c_B,B_inv),b)
print('simplex iteration:',iterNum)
print('objective:',z_opt)
print('optimal solution:',x_opt)

来源于运筹优化常用模型(刘兴禄)

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值