用 scipy.optimize.linprog 實現線性規划


1. 概述

線性規划:在線性等式和不等式約束下最小化線性目標函數。
線性編程可解決以下形式的問題:

\[\begin{aligned} \min _{x} c^{T} x & \\ \text { such that } & A_{u b} x \leq b_{u b}, \\ & A_{e q} x =b_{e q}, \\ & l \leq x \leq u \end{aligned} \]

也就是說求解使得 \(c^{T} x\) 最小的x,同時x又要符合約束條件。
其中\(x\)是決策變量的向量;\(c\),\(b_{ub}\),\(b_{eq}\),\(l\)和\(u\)是向量;\(A_{ub}\)和\(A_{eq}\)是矩陣。

2. 實例

2.1 問題

要最小化 \(Z = 0.4X_{1} + 0.5X_{2}\),約束如下

\[\begin{aligned} &0.3 x_{1}+0.1 x_{2} \leq 2.7 \\ &0.5 x_{1}+0.5 x_{2}=6 \\ &0.6 x_{1}+0.4 x_{2} \geq 6 \\ &x_{1} \geq 0, \quad x_{2} \geq 0 \end{aligned} \]

2.2 求解

這里我們使用scipy中的linprog進行求解,其用法如下:

scipy.optimize.linprog(c, A_ub=None, b_ub=None, A_eq=None, b_eq=None, 
                       bounds=None, method='simplex', callback=None, options=None)

其中,c為要最小化的線性目標函數的系數。,A_ub和b_ub對應線性不等式約束,A_eq和b_eq對應線性等式約束,bounds確定邊界,如x≥0為(0,None),x無約束則為(None,None),method是求解器的類型,'simplex' 為單純形法,其他的參數暫時可忽略。
要使用linprog,目標函數要變成求最小值,如果原題目要求求max(最大值),只需對目標函數取負,但要注意求解的最終值是取負后的目標函數的最小值,取負即為最大值。

最終分析如下:

python代碼如下:

import numpy as np
from scipy.optimize import linprog

c = np.array([0.4, 0.5])
A_ub = np.array([[0.3, 0.1], [-0.6, -0.4]])  # 不等式約束
b_ub = np.array([2.7, -6])
A_eq = np.array([[0.5, 0.5]])                # 等式約束
b_eq = np.array([6])
r = linprog(c, A_ub, b_ub, A_eq, b_eq, bounds=((0, None), (0, None)))
print(r)

運行結果如下所示:

     con: array([9.3865955e-09])
     fun: 5.2499999910145405
 message: 'Optimization terminated successfully.'
     nit: 5
   slack: array([2.67959077e-09, 2.99999992e-01])
  status: 0
 success: True
       x: array([7.5       , 4.49999999])

fun 為目標函數的最優值,slack 為松弛變量,status 表示優化結果狀態,x 為最優解。
此模型的求解結果為:當 \(x_{1}=7.5\),\(x_2=4.49999999\) 時,函數取得最小值5.2499999910145405

參考

https://www.pianshen.com/article/39912031011/
https://www.freesion.com/article/98311054345/
https://blog.csdn.net/weixin_43638511/article/details/104236557


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM