Python數模筆記-Scipy庫(1)線性規划問題



1、最優化問題建模

最優化問題的三要素是決策變量、目標函數和約束條件。

(1)分析影響結果的因素是什么,確定決策變量
(2)決策變量與優化目標的關系是什么,確定目標函數
(3)決策變量所受的限制條件是什么,確定約束條件

最優化問題的建模,通常按照以下步驟進行:

(1)問題定義,確定決策變量、目標函數和約束條件;
(2)模型構建,由問題描述建立數學方程,並轉化為標准形式的數學模型;
(3)模型求解,用標准模型的優化算法對模型求解,得到優化結果;
(4)模型檢驗,統計檢驗和靈敏度分析。


歡迎關注 Youcans 原創系列,每周更新數模筆記

Python數模筆記-PuLP庫
Python數模筆記-StatsModels統計回歸
Python數模筆記-Sklearn
Python數模筆記-NetworkX
Python數模筆記-模擬退火算法



2、線性規划

線性規划(Linear programming),是研究線性約束條件下線性目標函數的極值問題的優化方法,常用於解決利用現有的資源得到最優決策的問題。

線性規划模型的一般形式如下:

min  fx = c1*x1 + ...+ cn*xn
  s.t. a11*x1+...+a1n*Xn ≤ b1
    ...
    am1*x1+...+amn*Xn ≤ bm
    x1≥0,...,xn≥0

其中:fx 是目標函數,求最小值;x1,...xn 是決策變量;aij, bi 是不等式約束的參數。



3、Scipy 求解線性規划

Python 的 SciPy 庫帶有用於解決線性編程問題的 linprog 函數。
  linporg 函數對於線性規划模型的描述為:

min fx = C'*X fx 是目標函數
  s.t. A_ub*X <= B_ub 不等式約束
    A_eq*X = B_eq 等式約束
    lb <= X <= ub 取值范圍

其中:

fx 是目標函數,求最小值;
X 是決策變量,向量;
C 是目標函數的參數向量;
A_ub 是不等式約束的參數矩陣,B_ub 是不等式約束的參數向量;
A_eq 是等式約束的參數矩陣,B_eq 是等式約束的參數向量;
lb,ub 是參數向量,(lb,ub) 是 X 的取值范圍。

注意:
  (1)問題表示為:求 fx 的最小值,如果問題要求 fx 的最大值則要通過 fx‘= -fx 將問題轉化為求 fx' 的最小值;
  (2)不等式約束條件表示為:小於等於,如果約束條件為大於等於則要通過不等式兩側乘以 -1 將約束條件轉化為小於等於的形式。
linporg 函數求解線性規划問題的輸出參數為:

con: 等式約束的殘差(名義上為 0),B_eq - A_eqX
fun: 目標函數的當前值(最小值),C'X
message: 算法狀態描述
nit: 當前迭代次數
slack: 不等式約束的松弛值,B_ub - A_ub
X
status: 算法退出時的狀態,0:優化完成,1:達到最大迭代次數,2:不可行,3:不收斂,4:數值困難
success: 當算法成功完成時為 True
x: 當前解,向量



4 實例

4.1 問題模型:

    max     fx = 2*x1 + 3*x2 - 5*x3
    s.t.    x1 + x2 + x3 = 7
            2*x1 - 5*x2 + x3 >= 10
            x1 + 3*x2 + x3 <= 12
            x1, x2, x3 >=0

4.2 模型轉換:

首先要將求解問題的模型轉化為 Linprog 的標准形式:

(1)求最大值問題要轉換為求最小值問題:C = [-2, 3, 5]
(2)當約束條件為 大於等於 時要加負號:A_ub = [[-2, 5, -1], [1, 3, 1]]
(3)由 x1,x2,x3>=0 和 x1+x2+x3=7 可知:0 <= x1,x2,x3 <= 7

4.3 python 程序:

import numpy as np  # 導入 numpy
from scipy.optimize import linprog  # 導入 scipy

c = np.array([-2, -3, 5])
A_ub = np.array([[-2, 5, -1], [1, 3, 1]])  # 不等式約束參數矩陣
B_ub = np.array([-10, 12])  # 不等式約束參數向量
A_eq = np.array([[1, 1, 1]])  # 等式約束參數矩陣
B_eq = np.array([7])  # 等式約束參數向量
x1 = (0, 7)  # x1 的取值范圍,lb1 < x1 < ub1
x2 = (0, 7)  # x2 的取值范圍,lb2 < x2 < ub2
x3 = (0, 7)  # x3 的取值范圍,lb3 < x3 < ub3
res = linprog(c, A_ub, B_ub, A_eq, B_eq, bounds=(x1, x2, x3))
print(res)
# === 關注 Youcans,分享更多原創系列 https://www.cnblogs.com/youcans/ ===

4.4 運行結果:

     con: array([1.19830306e-08])
     fun: -14.57142854231215
 message: 'Optimization terminated successfully.'
     nit: 5
   slack: array([-3.70231543e-08,  3.85714287e+00])
  status: 0
 success: True
       x: array([6.42857141e+00, 5.71428573e-01, 9.82192085e-10])


版權說明:
YouCans 原創作品,轉載必須注明原文鏈接
Copyright 2021 YouCans, XUPT
Crated:2021-04-28


歡迎關注 Youcans 原創系列,每周更新數模筆記

Python數模筆記-PuLP庫
Python數模筆記-StatsModels統計回歸
Python數模筆記-Sklearn
Python數模筆記-NetworkX
Python數模筆記-模擬退火算法



免責聲明!

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



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