单纯形法求解线性规划问题

我们来看一个简单的数学规划模型:
max ⁡ Z = 70 x 1 + 30 x 2 \max Z=70 x_{1}+30 x_{2} maxZ=70x1+30x2 s . t . { 3 x 1 + 9 x 2 ⩽ 540 5 x 1 + 5 x 2 ⩽ 450 9 x 1 + 3 x 2 ⩽ 720 x 1 , x 2 ⩾ 0 s.t. \left\{\begin{array}{l}3 x_{1}+9 x_{2} \leqslant 540 \\ 5 x_{1}+5 x_{2} \leqslant 450 \\ 9 x_{1}+3 x_{2} \leqslant 720 \\ x_{1}, x_{2} \geqslant 0\end{array}\right. s.t.3x1+9x25405x1+5x24509x1+3x2720x1,x20

首先,我们需要把这个不规范的数学规划模型转换成标准型,标准型的要求有以下几点:

  • 目标为求函数的最大值问题,即Maxmize问题
  • 约束条件为等式约束
  • 约束条件的右边常数项大于或者等于0
  • 所有变量大于或者等于零

我们可以通过引入松弛变量的方式来进行非标准型的标准化转换,对于上式,我们可以通过变换得到它的标准型如下:

max ⁡ Z = 70 x 1 + 30 x 2 \max Z=70 x_{1}+30 x_{2} maxZ=70x1+30x2 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 s.t. \left\{\begin{array}{l}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} \geqslant 0\end{array}\right. s.t.3x1+9x2+x3=5405x1+5x2+x4=4509x1+3x2+x5=720x1,x2,x3,x4,x50

我们可以使用单纯性法来进行求解,首先我们需要建立单纯形表matrx,然后根据以下的步骤进行迭代,指导目标函数一行的系数没有正数为止:

  1. Step1:判断出基和入基:根据系数选入度、根据theta选出度,选取入度一列和出度一行"
  2. Step2:修改matrix,初等行变换,先归一化出基一行,然后归零其他行的入度一列;
  3. Step3:更新index,把入度变量替换掉index中的松弛变量

我可以使用以下代码来实现:

import pandas as pd
import numpy as np

def lp_solver(matrix: pd.DataFrame):
	c = matrix.iloc[0,1:]
	while c.max() > 0:
		print("Step1:判断出基和入基:根据系数选入度、根据theta选出度,选取入度一列和出度一行")
		#判断出基和入基:根据系数选入度、根据theta选出度,选取入度一列和出度一行
		in_x = c.idxmax()
		in_x_v = c[in_x]
		b = matrix.iloc[1:,0]
		in_x_a = matrix.iloc[1:][in_x]
		out_x = (b/in_x_a).idxmin()
		print(f"in_x={in_x},out_x={out_x}")
		#修改matrix,初等行变换,先归一化出基一行,然后归零其他行的入度一列
		print("Step2:修改matrix,初等行变换,先归一化出基一行,然后归零其他行的入度一列")
		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,把入度变量替换掉index中的松弛变量
		print("Step3:更新index,把入度变量替换掉index中的松弛变量")
		index = matrix.index.tolist()
		print(f"index before update ={index}")
		#index可以认为是索引
		i = index.index(out_x)
		print(f"the in dex of out_x = {i}")
		index[i] = in_x
		print(f"index after update ={index}")
		matrix.index = index
		c = matrix.iloc[0,1:]
		print(matrix)

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']
		)
	print(matrix)
	lp_solver(matrix)

在这里插入图片描述
我们可以看到这个程序求解的全过程,最终,在x1=75、x2=15处,目标函数取得最大值5700.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值