线性规划——单纯形法(原理及代码实现)

编程入门 行业动态 更新时间:2024-10-25 18:33:49

<a href=https://www.elefans.com/category/jswz/34/1747333.html style=线性规划——单纯形法(原理及代码实现)"/>

线性规划——单纯形法(原理及代码实现)

线性规划基本模型

由于单纯性法是用于求解线性规划模型,因此我们对一般的问题进行松弛之后得到了线性规划模型的一般形式(及是LP问题的一般形式)如下:
m a x z = c T X s . t . { A X = b X ≥ 0 max\ z = c^TX\\[2ex] s.t.\begin{cases} AX = b\\[2ex] X\geq0 \\ \end{cases} max z=cTXs.t.⎩ ⎧​AX=bX≥0​

单纯形法的矩阵描述

针对于该模型引入基变量 X B X_B XB​和非基变量 X N X_N XN​、系数矩阵的基 B B B和非基部分 N N N以及基变量对应的系数数列 c B T c_B^T cBT​、非基变量对应的系数数列 c N T c_N^T cNT​可以将原问题化为如下形式:
m a x z = c B T X B + c N T X N s . t . { B X B + N X n = b X B , X N ≥ 0 max\ z = c^T_BX_B+c^T_NX_N\\[2ex] s.t.\begin{cases} BX_B+NX_n = b\\[2ex] X_B,X_N\geq0 \\ \end{cases} max z=cBT​XB​+cNT​XN​s.t.⎩ ⎧​BXB​+NXn​=bXB​,XN​≥0​
将目标函数与约束条件进行联立,消去 X B X_B XB​可以得到目标函数的新的表达式如下所示:
z = C B B − 1 b + ( C N − C B B − 1 N ) X N z = C_BB^{-1}b + (C_N-C_BB^{-1}N)X_N z=CB​B−1b+(CN​−CB​B−1N)XN​
可以发现进行联立之后计算式所得的目标函数与基变量无关,要确定从非基变量进行的检验数为 C N − C B B − 1 N C_N-C_BB^{-1}N CN​−CB​B−1N,若想要目标函数变得更大则检验数需要大于零,从而可以确定进基变量为非基变量中检验数大于零的一个。

因此对于单纯行表可以表示为如下:

基变量 X B X_B XB​非基变量 X N X_N XN​右侧RHS
系数矩阵 I I I B − 1 N B^{-1}N B−1N B − 1 b B^{-1}b B−1b
检验数0 C N − C B B − 1 N C_N-C_BB^{-1}N CN​−CB​B−1N − C B B − 1 b -C_BB^{-1}b −CB​B−1b

任意时刻各个部分的核心是某个已知矩阵的部分左乘一个 B − 1 B^{-1} B−1,因此求解的核心在于快速地维护 B − 1 B^{-1} B−1。

以下我们设 P k P_k Pk​ 是 x k x_k xk​ 对应的原始系数矩阵的那一列。
又存在递推式:
B i − 1 = E i B i − 1 − 1 B^{-1}_i = E_iB^{-1}_{i-1} Bi−1​=Ei​Bi−1−1​
其中 E i E_i Ei​是把一个单位矩阵中,第 j j j列替换为 ξ i \xi_i ξi​后的结果,其中 j j j表示本次新换入的基在 B i B_i Bi​中对应的第 j j j列, ξ i \xi_i ξi​由本次换入变量在换入前 B i − 1 − 1 N i − 1 B_{i-1}^{-1}N_{i-1} Bi−1−1​Ni−1​中对应的列 ( a 1 , a 2 , . . . . , a m ) (a_1,a_2,....,a_m) (a1​,a2​,....,am​)变换得到,设 l l l是换出变量对应的行,则
ξ i = ( − a 1 a l , . . . , 1 a l , . . . , − a m a l ) \xi_i = (-\frac{a_1}{a_l},...,\frac{1}{a_l},...,-\frac{a_m}{a_l}) ξi​=(−al​a1​​,...,al​1​,...,−al​am​​)
于是,
B i − 1 = ( e 1 , . . . , e j − 1 , ξ j , e j + 1 . . . , e m ) B i − 1 − 1 B_i^{-1}= (e_1,...,e_{j-1},\xi_j,e_{j+1}...,e_m)B^{-1}_{i-1} Bi−1​=(e1​,...,ej−1​,ξj​,ej+1​...,em​)Bi−1−1​

寻找入基变量

入基变量求解根据检验数
σ i = C N i − C B i B i − 1 N i \sigma_i = C_{N_i}-C_{B_i}B_i^{-1}N_i σi​=CNi​​−CBi​​Bi−1​Ni​
中找最大值下标即可以找到。

寻找出基变量

出基变量根据 θ \theta θ法则求出
θ = m i n { B − 1 b B i − 1 P k ∣ B i − 1 P k > 0 } \theta = min \left\{{\frac{B^{-1}b}{B_i^{-1}P_k}|B_i^{-1}P_k >0}\right\} θ=min{Bi−1​Pk​B−1b​∣Bi−1​Pk​>0}
即可以找到。
当所有检验数都小于零则单纯形法结束,因为目标值已经不可能再大一步了。

python实现单纯形法

使用单纯形法对如下线性规划模型进行求解:
m a x z = 70 x 1 + 30 x 2 s . t . { 3 x 1 + 9 x 2 + x 3 = 540 5 x 1 + 5 x 2 + x 4 = 450 9 x 1 + 3 x 2 + x 5 = 720 x 1 , x 2 , x 3 , x 4 , x 5 ≥ 0 max\ z = 70x_1+30x_2\\[2ex] s.t.\begin{cases} 3x_1+9x_2+x_3 =540\\[2ex] 5x_1+5x_2+x_4=450 \\[2ex] 9x_1+3x_2+x_5=720\\[2ex] x_1,x_2,x_3,x_4,x_5\geq0 \end{cases} max z=70x1​+30x2​s.t.⎩ ⎧​3x1​+9x2​+x3​=5405x1​+5x2​+x4​=4509x1​+3x2​+x5​=720x1​,x2​,x3​,x4​,x5​≥0​
具体实现代码如下所示:

# 单纯形法
import pandas as pd
import numpy as np
from pandas import DataFrame# 定义线性规划求解函数
def lp_solver(matrix: DataFrame):'''输入线性规划的矩阵,根据单纯形法求解线性规划模型max cxs.t. ax <= b矩阵形式是:b   x1  x2  x3  X4  X5obj 0   70  30  0   0   0x3  540 3   9   1   0   0x4  450 5   5   0   1   0x5  720 9   3   0   0   1第1行是目标函数的系数第2-4行是约束方程的系数第1列是约束方程的常数项obj-b 交叉,即第1行第一列的元素是目标函数的负值x3,x4,x5 既是松弛变量,也是初始可行解:param matrix:return'''# 检验数是否大于零c = matrix.iloc[0, 1:]while c.max() > 0:# 选择入基变量c = matrix.iloc[0, 1:]in_x = c.idxmax()# 入基变量的系数in_x_v = c[in_x]# 选择出基变量# 选择正的最小比值对应的变量出基 min(b列/入基变量列)b = matrix.iloc[1:, 0]# 选择入基变量对应的列in_x_a = matrix.iloc[1:][in_x]# 得到出基变量out_x = (b / in_x_a).idxmin()# 旋转操作print(matrix.loc[out_x, in_x])matrix.loc[out_x, :] = matrix.loc[out_x, :] / matrix.loc[out_x, in_x]for idx in matrix.index:if idx != out_x:matrix.loc[idx, :] = matrix.loc[idx, :] - matrix.loc[out_x, :] * matrix.loc[idx, in_x]# 索引替换(入基与出基变量名称替换)index = matrix.index.tolist()i = index.index(out_x)index[i] = in_xmatrix.index = index# 打印结果print("最终的最优单纯形法是:")print(matrix)print("目标函数值是:", -matrix.iloc[0, 0])print("最优决策变量是:")x_count = (matrix.shape[1] - 1) - (matrix.shape[0] - 1)x = matrix.iloc[0, 1:].index.tolist()[: x_count]for xi in x:print(xi, '=', matrix.loc[xi, 'b'])# 主程序代码
if __name__ == '__main__':# 约束方程系数矩阵,包含常数项matrix = pd.DataFrame(np.array([[0, 70, 30, 0, 0, 0],[540, 3, 9, 1, 0, 0],[450, 5, 5, 0, 1, 0],[720, 9, 3, 0, 0, 1], ]),index=['obj', 'x3', 'x4', 'x5'],columns=['b', 'x1', 'x2', 'x3', 'x4', 'x5'])# 调用前面定义的函数求解lp_solver(matrix)

最终的求解结果如下:

最终的最优单纯形法是:b   x1   x2   x3   x4        x5
obj -5700.0  0.0  0.0  0.0 -2.0 -6.666667
x3    180.0  0.0  0.0  1.0 -2.4  1.000000
x2     15.0  0.0  1.0  0.0  0.3 -0.166667
x1     75.0  1.0  0.0  0.0 -0.1  0.166667
目标函数值是: 5700.0
最优决策变量是:
x1 = 75.0
x2 = 15.0

更多推荐

线性规划——单纯形法(原理及代码实现)

本文发布于:2024-02-13 04:45:20,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1690737.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:线性规划   原理   代码

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!