線性規劃(Linear programming),在線性等式或不等式約束條件下求解線性目標函數的極值問題,經常使用於解決資源分配、生產調度和混合問題。例如:python
max fx = 2*x1 + 3*x2 - 5*x3 s.t. x1 + 3*x2 + x3 <= 12 2*x1 - 5*x2 + x3 >= 10 x1 + x2 + x3 = 7 x1, x2, x3 >=0
線性規劃問題的建模和求解,一般按照如下步驟進行:算法
(1)問題定義,肯定決策變量、目標函數和約束條件;
(2)模型構建,由問題描述創建數學方程,並轉化爲標準形式的數學模型;
(3)模型求解,用標準模型的優化算法對模型求解,獲得優化結果;函數
=== 關注 Youcans,分享更多原創系列 https://www.cnblogs.com/youcans/ ===工具
PuLP是一個開源的第三方工具包,能夠求解線性規劃、整數規劃、混合整數規劃問題。
下面以該題爲例講解 PuLP 求解線性規劃問題的步驟:
(0)導入 PuLP庫函數優化
import pulp
(1)定義一個規劃問題ui
MyProbLP = pulp.LpProblem("LPProbDemo1", sense=pulp.LpMaximize)
pulp.LpProblem 是定義問題的構造函數。
"LPProbDemo1"是用戶定義的問題名(用於輸出信息)。
參數 sense 用來指定求最小值/最大值問題,可選參數值:LpMinimize、LpMaximize 。code
(2)定義決策變量blog
x1 = pulp.LpVariable('x1', lowBound=0, upBound=7, cat='Continuous') x2 = pulp.LpVariable('x2', lowBound=0, upBound=7, cat='Continuous') x3 = pulp.LpVariable('x3', lowBound=0, upBound=7, cat='Continuous')
pulp.LpVariable 是定義決策變量的函數。
'x1' 是用戶定義的變量名。
參數 lowBound、upBound 用來設定決策變量的下界、上界;能夠不定義下界/上界,默認的下界/上界是負無窮/正無窮。本例中 x1,x2,x3 的取值區間爲 [0,7]。
參數 cat 用來設定變量類型,可選參數值:'Continuous' 表示連續變量(默認值)、' Integer ' 表示離散變量(用於整數規劃問題)、' Binary ' 表示0/1變量(用於0/1規劃問題)。資源
(3)添加目標函數get
MyProbLP += 2*x1 + 3*x2 - 5*x3 # 設置目標函數
添加目標函數使用 "問題名 += 目標函數式" 格式。
(4)添加約束條件
MyProbLP += (2*x1 - 5*x2 + x3 >= 10) # 不等式約束 MyProbLP += (x1 + 3*x2 + x3 <= 12) # 不等式約束 MyProbLP += (x1 + x2 + x3 == 7) # 等式約束
添加約束條件使用 "問題名 += 約束條件表達式" 格式。
約束條件能夠是等式約束或不等式約束,不等式約束能夠是 小於等於 或 大於等於,分別使用關鍵字">="、"<="和"=="。
(5)求解
MyProbLP.solve() print("Status:", pulp.LpStatus[MyProbLP.status]) # 輸出求解狀態 for v in MyProbLP.variables(): print(v.name, "=", v.varValue) # 輸出每一個變量的最優值 print("F(x) = ", pulp.value(MyProbLP.objective)) #輸出最優解的目標函數值
solve() 是求解函數。PuLP默認採用 CBC 求解器來求解優化問題,也能夠調用其它的優化器來求解,如:GLPK,COIN CLP/CBC,CPLEX,和GUROBI,但須要另外安裝。
完整的程序代碼以下:
import pulp MyProbLP = pulp.LpProblem("LPProbDemo1", sense=pulp.LpMaximize) x1 = pulp.LpVariable('x1', lowBound=0, upBound=7, cat='Continuous') x2 = pulp.LpVariable('x2', lowBound=0, upBound=7, cat='Continuous') x3 = pulp.LpVariable('x3', lowBound=0, upBound=7, cat='Continuous') MyProbLP += 2*x1 + 3*x2 - 5*x3 # 設置目標函數 MyProbLP += (2*x1 - 5*x2 + x3 >= 10) # 不等式約束 MyProbLP += (x1 + 3*x2 + x3 <= 12) # 不等式約束 MyProbLP += (x1 + x2 + x3 == 7) # 等式約束 MyProbLP.solve() print("Status:", pulp.LpStatus[MyProbLP.status]) # 輸出求解狀態 for v in MyProbLP.variables(): print(v.name, "=", v.varValue) # 輸出每一個變量的最優值 print("F(x) = ", pulp.value(MyProbLP.objective)) #輸出最優解的目標函數值 # === 關注 Youcans,分享更多原創系列 https://www.cnblogs.com/youcans/ ===
程序運行結果以下:
Welcome to the CBC MILP Solver Version: 2.9.0 Build Date: Feb 12 2015 Status: Optimal x1 = 6.4285714 x2 = 0.57142857 x3 = 0.0 F(x) = 14.57142851
=== 關注 Youcans,分享更多原創系列 https://www.cnblogs.com/youcans/ === 版權說明: 原創做品 Copyright 2021 YouCans, XUPT Crated:2021-04-28