Python數模筆記-PuLP庫(1)線性規划入門


1、什么是線性規划

  線性規划(Linear programming),在線性等式或不等式約束條件下求解線性目標函數的極值問題,常用於解決資源分配、生產調度和混合問題。例如:

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/ ===

2、PuLP 庫求解線性規划

  PuLP是一個開源的第三方工具包,可以求解線性規划、整數規划、混合整數規划問題。
  下面以該題為例講解 PuLP 求解線性規划問題的步驟:
(0)導入 PuLP庫函數

    import pulp

(1)定義一個規划問題

    MyProbLP = pulp.LpProblem("LPProbDemo1", sense=pulp.LpMaximize)

  pulp.LpProblem 是定義問題的構造函數。
  "LPProbDemo1"是用戶定義的問題名(用於輸出信息)。
  參數 sense 用來指定求最小值/最大值問題,可選參數值:LpMinimize、LpMaximize 。

(2)定義決策變量

    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)添加目標函數

    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,但需要另外安裝。 

3、Python程序和運行結果

完整的程序代碼如下:

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


免責聲明!

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



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