python两种方法实现线性规划

Python实现线性规划的计算

线性规划的目标函数既可以是求最大值,也可以是求最小值,约束条件可以是小于等于也可以是大于等于,但为了方便起见,MATLAB和python都规定线性规划标准型为:
z = m i n   f T x , s . t . = { A ⋅ x ≤ b , A e q ⋅ x = b e q , l b ≤ x ≤ u b z=min\ \bm f^T\bm x,\\ s.t.= \begin{cases} \bm{A} \cdot \bm x \le\bm b,\\ Aeq \cdot \bm x=beq ,\\ lb\le \bm x \le ub \end{cases} z=min fTx,s.t.=Axb,Aeqx=beq,lbxub

转换为标准型的方法

  • 目标函数 m a x → m i n max \rightarrow min maxmin
    若目标函数 z 1 = m a x   f 1 T x , z_1=max\ \bm f_1^T\bm x, z1=max f1Tx,则可以通过加负号来实现变成 z 2 = m i n   − f 1 T x z_2=min\ -\bm f_1^T\bm x z2=min f1Tx
  • 约束条件:大于等于 → \rightarrow 小于等于
    A ⋅ x ≥ b ⇒ − A ⋅ x ≤ − b \bm{A} \cdot \bm x \ge \bm b\quad\bm\Rightarrow -\bm{A} \cdot \bm x \le \bm {-b} AxbAxb

官方示例及代码(不用第三方库)

z = m i n − x 0 + 4 x 1 s . t . = { − 3 x 0 + x 1 ≤ 6 , − x 0 − 2 x 1 ≥ − 4 , x 1 ≥ − 3 z=min -x_0+4x_1\\ s.t.= \begin{cases} -3x_0 + x_1 \leq 6,\\ -x_0 - 2x_1 \geq -4,\\ x_1 \geq -3 \end{cases} z=minx0+4x1s.t.=3x0+x16,x02x14,x13
与MATLAB中 l i n p r o g ( c , A , b , A e q , b e q , l b , u b ) linprog(c,A,b,Aeq,beq,lb,ub) linprog(c,A,b,Aeq,beq,lb,ub) 求解函数类似,python中可以调用scipy库中的optimize.linprog()函数

The problem is not presented in the form accepted by `linprog`. This is
easily remedied by converting the "greater than" inequality
constraint to a "less than" inequality constraint by
multiplying both sides by a factor of :math:`-1`. Note also that the last
constraint is really the simple bound :math:`-3 \leq x_1 \leq \infty`.
Finally, since there are no bounds on :math:`x_0`, we must explicitly
specify the bounds :math:`-\infty \leq x_0 \leq \infty`, as the
default is for variables to be non-negative. After collecting coeffecients
into arrays and tuples, the input for this problem is:

>>> c = [-1, 4]
>>> A = [[-3, 1], [1, 2]]
>>> b = [6, 4]
>>> x0_bounds = (None, None)
>>> x1_bounds = (-3, None)
>>> from scipy.optimize import linprog
>>> res = linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds])

Note that the default method for `linprog` is 'interior-point', which is
approximate by nature.

>>> print(res)
     con: array([], dtype=float64)
     fun: -21.99999984082494 # may vary
 message: 'Optimization terminated successfully.'
     nit: 6 # may vary
   slack: array([3.89999997e+01, 8.46872439e-08] # may vary
  status: 0
 success: True
       x: array([ 9.99999989, -2.99999999]) # may vary

If you need greater accuracy, try 'revised simplex'.

>>> res = linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds], method='revised simplex')
>>> print(res)
  • 运行结果:
     con: array([], dtype=float64)
     fun: -22.0 # may vary
 message: 'Optimization terminated successfully.'
     nit: 1 # may vary
   slack: array([39.,  0.]) # may vary
  status: 0
 success: True
       x: array([10., -3.]) # may vary

使用pulp库求解(推荐,功能更强大)

from pulp import *

# 1. 建立问题
prob = LpProblem("Problem", LpMinimize)

# 2. 建立变量
x1 = LpVariable("x1")
x2 = LpVariable("x2", -3)

# 3. 设置目标函数 z
prob += -x1 + 4*x2, 

# 4. 施加约束
prob += -3*x1 + x2 <= 6.0, "constraint1"
prob += -x1 - 2*x2 >= -4, "constraint2"

# 5. 求解
prob.solve()

# 6. 打印求解状态
print("Status:", LpStatus[prob.status])

# 8. 打印最优解的目标函数值
print("z= ", value(prob.objective))

# 7. 打印出每个变量的最优值
for v in prob.variables():
    print(v.name, "=", v.varValue)

  • 运行结果:
Status: Optimal
x1 = 10.0
x2 = -3.0
z=  -22.0

小结

  • 就以上代码来看,scipy.optimize.linprog()会比较简便,但是pulp库的代码适用性更强,没有 ≥ \ge ≤ \le 的限制,同时目标函数还支持直接设为最大优化。
  • 具体参数设置可以参照pulp求解线性规划问题或者官方文档

注释

  • 代码参考自官方文档
  • 部分内容参考自数学建模算法与应用
  • 觉得有用的不妨点赞支持一下
  • 17
    点赞
  • 87
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值