线性规划基本模型
由于单纯性法是用于求解线性规划模型,因此我们对一般的问题进行松弛之后得到了线性规划模型的一般形式(及是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=cBTXB+cNTXNs.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=CBB−1b+(CN−CBB−1N)XN
可以发现进行联立之后计算式所得的目标函数与基变量无关,要确定从非基变量进行的检验数为
C
N
−
C
B
B
−
1
N
C_N-C_BB^{-1}N
CN−CBB−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−CBB−1N | − C B B − 1 b -C_BB^{-1}b −CBB−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=EiBi−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−1Ni−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=(−ala1,...,al1,...,−alam)
于是,
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−CBiBi−1Ni
中找最大值下标即可以找到。
寻找出基变量
出基变量根据
θ
\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−1PkB−1b∣Bi−1Pk>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+30x2s.t.⎩
⎨
⎧3x1+9x2+x3=5405x1+5x2+x4=4509x1+3x2+x5=720x1,x2,x3,x4,x5≥0
具体实现代码如下所示:文章来源:https://www.toymoban.com/news/detail-474128.html
# 单纯形法
import pandas as pd
import numpy as np
from pandas import DataFrame
# 定义线性规划求解函数
def lp_solver(matrix: DataFrame):
'''
输入线性规划的矩阵,根据单纯形法求解线性规划模型
max cx
s.t. ax <= b
矩阵形式是:
b x1 x2 x3 X4 X5
obj 0 70 30 0 0 0
x3 540 3 9 1 0 0
x4 450 5 5 0 1 0
x5 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_x
matrix.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)
最终的求解结果如下:文章来源地址https://www.toymoban.com/news/detail-474128.html
最终的最优单纯形法是:
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
到了这里,关于线性规划——单纯形法(原理及代码实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!