Python数模笔记-PuLP库(2)线性规划进阶
1、基于字典的創建規劃問題
上篇中介紹了使用 LpVariable 對逐一定義每個決策變量,設定名稱、類型和上下界,類似地對約束條件也需要逐一設置模型參數。在大規模的規劃問題中,這樣逐個定義變量和設置模型參數非常繁瑣,效率很低。Pulp 庫提供了一種快捷方式,可以結合 Python語言的循環和容器,使用字典來創建問題。
-(1)使用快捷方法建立一個規劃問題,可以用字典類型(dict) 建立多個變量,例如:
name = [‘廢料1’, ‘廢料2’, ‘廢料3’, ‘廢料4’, ‘鎳’, ‘鉻’, ‘鉬’]
# A dictionary of the costs of each of the Ingredients is created
mass = pulp.LpVariable.dicts(“原料”, material, lowBound=0, cat=‘Continuous’)
-(2)使用字典類型(dict) 設置目標函數和約束條件的參數,例如:
cost = {
‘廢料1’: 16,
‘廢料2’: 10,
‘廢料3’: 8,
‘廢料4’: 9,
‘鎳’: 48,
‘鉻’: 60,
‘鉬’: 53}
-(3)使用 遍歷循環結構 設置目標函數和約束條件,例如:
AlloyModel += pulp.lpSum([cost[item] * mass[item] for item in material]), “總生產成本”
AlloyModel += pulp.lpSum([mass[item] for item in material]) == 1000, “質量約束”
詳細用法參見下節例程。
歡迎關注 Youcans 原創系列,每周更新數模筆記
Python數模筆記-PuLP庫
Python數模筆記-StatsModels統計回歸
Python數模筆記-Sklearn
Python數模筆記-NetworkX
Python數模筆記-模擬退火算法
2、線性規劃問題案例
本篇以合金鋼材生產投料問題為例,分析基于列表和字典創建問題的快捷方法。
問題描述:
某鋼鐵廠通過熔煉回收的金屬廢料并添加一定新料的方法生產滿足化學成分要求的合金,計劃生產1000千克的合金。
所有金屬廢料的主要成分是鐵,不同金屬廢料還含有各種微量元素。
金屬廢料、新料的各組分含量占比、可用數量和單位成本如下表所示。生成合金中各組分的含量要求,也如表中所示。
問如何安排投料比例,在滿足合金組分含量要求的條件下的材料成本最小?
| 廢料1 | 0.80 | 18.0 | 12.0 | 0.0 | 75 | 16 |
| 廢料2 | 0.70 | 3.2 | 1.1 | 0.1 | 250 | 10 |
| 廢料3 | 0.85 | 0 | 0 | 0 | 不限 | 8 |
| 廢料4 | 0.40 | 0 | 0 | 0 | 不限 | 9 |
| 鎳 | 0 | 100 | 0 | 0 | 不限 | 48 |
| 鉻 | 0 | 0 | 100 | 0 | 不限 | 60 |
| 鉬 | 0 | 0 | 0 | 100 | 不限 | 53 |
| 合金下限 | 0.65 | 3.0 | 1.0 | 1.1 | / | / |
| 合金上限 | 0.75 | 3.5 | 1.2 | 1.3 | / | / |
3、建立模型
(1)決策變量
x1:廢料 1 用量(千克)
x2:廢料 2 用量(千克)
x3:廢料 3 用量(千克)
x4:廢料 4 用量(千克)
x5:原料鎳 用量(千克)
x6:原料鉻 用量(千克)
x7:原料鉬 用量(千克)
(2)目標函數:
min cost = 16*x1 + 10*x2 + 8*x3 + 9*x4 + 48*x5 + 60*x6 + 53*x7
(3)約束條件:
0.8*x1 + 0.7*x2 + 0.85*x3 + 0.40*x4 >= 0.65*1000
0.8*x1 + 0.7*x2 + 0.85*x3 + 0.40*x4 <= 0.75*1000
18.0*x1 + 3.2*x2 + 100.0*x5 >= 3.0*1000
18.0*x1 + 3.2*x2 + 100.0*x5 <= 3.5*1000
12.0*x1 + 1.1*x2 + 100.0*x6 >= 1.0*1000
12.0*x1 + 1.1*x2 + 100.0*x6 >= 1.2*1000
0.1*x2 + 100.0*x7 >= 1.1*1000
0.1*x2 + 100.0*x7 >= 1.3*1000
(4)變量取值范圍:
xi >= 0, i=1,2,…7
x1 <= 75, x2 <= 250
4、PuLP 程序 1:使用 LpVariable 逐一定義變量
本程序與上篇的方法相同,使用 LpVariable 逐一定義變量。完整的程序代碼如下:
import pulp # 導入 pulp庫# 1.建立優化問題 AlloyLP: 求最小值(LpMinimize)AlloyLP = pulp.LpProblem("合金生產材料優化", sense=pulp.LpMinimize) # 定義問題,求最小值# 2.定義決策變量 x1~x7x1 = pulp.LpVariable('廢料1#', lowBound=0, upBound=75.0, cat='Continuous') # 定義 x1x2 = pulp.LpVariable('廢料2#', lowBound=0, upBound=250., cat='Continuous') # 定義 x2x3 = pulp.LpVariable('廢料3#', lowBound=0, cat='Continuous') # 定義 x3x4 = pulp.LpVariable('廢料4#', lowBound=0, cat='Continuous') # 定義 x4x5 = pulp.LpVariable('原料鎳', lowBound=0, cat='Continuous') # 定義 x5x6 = pulp.LpVariable('原料鉻', lowBound=0, cat='Continuous') # 定義 x6x7 = pulp.LpVariable('原料鉬', lowBound=0, cat='Continuous') # 定義 x7# 3.定義目標函數 costAlloyLP += (16*x1 + 10*x2 + 8*x3 + 9*x4 + 48*x5 + 60*x6 + 53*x7) # 投料成本# 4.設置約束條件AlloyLP += (x1 + x2 + x3 + x4 + x5 + x6 + x7 == 1000) # 等式約束AlloyLP += (0.8*x1 + 0.7*x2 + 0.85*x3 + 0.4*x4 >= 0.65*1000) # 不等式約束AlloyLP += (0.8*x1 + 0.7*x2 + 0.85*x3 + 0.4*x4 <= 0.75*1000) # 不等式約束AlloyLP += (18.0*x1 + 3.2*x2 + 100.0*x5 >= 3.0*1000) # 不等式約束AlloyLP += (18.0*x1 + 3.2*x2 + 100.0*x5 <= 3.5*1000) # 不等式約束AlloyLP += (12.0*x1 + 1.1*x2 + 100.0*x6 >= 1.0*1000) # 不等式約束AlloyLP += (12.0*x1 + 1.1*x2 + 100.0*x6 <= 1.2*1000) # 不等式約束AlloyLP += (0.1*x2 + 100.0*x7 >= 1.1*1000) # 不等式約束AlloyLP += (0.1*x2 + 100.0*x7 <= 1.3*1000) # 不等式約束AlloyLP += (x1 + x2 + x3 + x4 + x5 + x6 + x7 == 1000) # 等式約束# 5.求解線性規劃問題AlloyLP.solve()# 6.輸出優化結果print(AlloyLP) # 輸出問題設定參數和條件# print("求解狀態:", pulp.LpStatus[AlloyLP.status]) # 輸出求解狀態for v in AlloyLP.variables():print(v.name, " = ", v.varValue) # 輸出每個變量的最優值print("最小材料成本 = ", pulp.value(AlloyLP.objective)) # 輸出最優解的目標函數值# = 關注 Youcans,分享原創系列 https://blog.csdn.net/youcans =5、PuLP 程序 2:使用 dict 定義決策變量和約束條件
本程序使用 dict 定義變量、目標函數和約束條件參數,便于復雜問題的參數設定。
import pulp # 導入 pulp庫= 關注 Youcans,分享原創系列 https://blog.csdn.net/youcans =# 1. 建立問題AlloyModel = pulp.LpProblem("鋼材生產問題", pulp.LpMinimize)# 2. 建立變量material = ['廢料1', '廢料2', '廢料3', '廢料4', '鎳', '鉻', '鉬']mass = pulp.LpVariable.dicts("原料", material, lowBound=0, cat='Continuous')# 3. 設置目標函數cost = {'廢料1': 16,'廢料2': 10,'廢料3': 8,'廢料4': 9,'鎳': 48,'鉻': 60,'鉬': 53}AlloyModel += pulp.lpSum([cost[item] * mass[item] for item in material]), "總生產成本"# # 4. 施加約束carbonPercent = {'廢料1': 0.8,'廢料2': 0.7,'廢料3': 0.85,'廢料4': 0.4,'鎳': 0,'鉻': 0,'鉬': 0}NiPercent = {'廢料1': 18,'廢料2': 3.2,'廢料3': 0,'廢料4': 0,'鎳': 100,'鉻': 0,'鉬': 0}CrPercent = {'廢料1': 12,'廢料2': 1.1,'廢料3': 0,'廢料4': 0,'鎳': 0,'鉻': 100,'鉬': 0}MoPercent = {'廢料1': 0,'廢料2': 0.1,'廢料3': 0,'廢料4': 0,'鎳': 0,'鉻': 0,'鉬': 100}AlloyModel += pulp.lpSum([mass[item] for item in material]) == 1000, "質量約束"AlloyModel += pulp.lpSum([carbonPercent[item] * mass[item] for item in material]) >= 0.65*1000, "碳最小占比"AlloyModel += pulp.lpSum([carbonPercent[item] * mass[item] for item in material]) <= 0.75*1000, "碳最大占比"AlloyModel += pulp.lpSum([NiPercent[item] * mass[item] for item in material]) >= 3.0*1000, "鎳最小占比"AlloyModel += pulp.lpSum([NiPercent[item] * mass[item] for item in material]) <= 3.5*1000, "鎳最大占比"AlloyModel += pulp.lpSum([CrPercent[item] * mass[item] for item in material]) >= 1.0*1000, "鉻最小占比"AlloyModel += pulp.lpSum([CrPercent[item] * mass[item] for item in material]) <= 1.2*1000, "鉻最大占比"AlloyModel += pulp.lpSum([MoPercent[item] * mass[item] for item in material]) >= 1.1*1000, "鉬最小占比"AlloyModel += pulp.lpSum([MoPercent[item] * mass[item] for item in material]) <= 1.3*1000, "鉬最大占比"AlloyModel += mass['廢料1'] <= 75, "廢料1可用量"AlloyModel += mass['廢料2'] <= 250, "廢料2可用量"# 5. 求解AlloyModel.solve()# 6. 打印結果print(AlloyModel) # 輸出問題設定參數和條件print("優化狀態:", pulp.LpStatus[AlloyModel.status])for v in AlloyModel.variables():print(v.name, "=", v.varValue)print("最優總成本 = ", pulp.value(AlloyModel.objective))6、Python程序和運行結果
程序 1 和程序 2 的運行結果完全相同,結果如下:
Welcome to the CBC MILP Solver Version: 2.9.0 Build Date: Feb 12 2015 鋼材生產問題: MINIMIZE 16*原料_廢料1 + 10*原料_廢料2 + 8*原料_廢料3 + 9*原料_廢料4 + 53*原料_鉬 + 60*原料_鉻 + 48*原料_鎳 + 0 SUBJECT TO 質量約束: 原料_廢料1 + 原料_廢料2 + 原料_廢料3 + 原料_廢料4 + 原料_鉬 + 原料_鉻 + 原料_鎳 = 1000 碳最小占比: 0.8 原料_廢料1 + 0.7 原料_廢料2 + 0.85 原料_廢料3 + 0.4 原料_廢料4 >= 650 碳最大占比: 0.8 原料_廢料1 + 0.7 原料_廢料2 + 0.85 原料_廢料3 + 0.4 原料_廢料4 <= 750 鎳最小占比: 18 原料_廢料1 + 3.2 原料_廢料2 + 100 原料_鎳 >= 3000 鎳最大占比: 18 原料_廢料1 + 3.2 原料_廢料2 + 100 原料_鎳 <= 3500 鉻最小占比: 12 原料_廢料1 + 1.1 原料_廢料2 + 100 原料_鉻 >= 1000 鉻最大占比: 12 原料_廢料1 + 1.1 原料_廢料2 + 100 原料_鉻 <= 1200 鉬最小占比: 0.1 原料_廢料2 + 100 原料_鉬 >= 1100 鉬最大占比: 0.1 原料_廢料2 + 100 原料_鉬 <= 1300 廢料1可用量: 原料_廢料1 <= 75 廢料2可用量: 原料_廢料2 <= 250 VARIABLES 原料_廢料1 Continuous 原料_廢料2 Continuous 原料_廢料3 Continuous 原料_廢料4 Continuous 原料_鉬 Continuous 原料_鉻 Continuous 原料_鎳 Continuous優化狀態: Optimal 原料_廢料1 = 75.0 原料_廢料2 = 90.909091 原料_廢料3 = 672.28283 原料_廢料4 = 137.30808 原料_鉬 = 10.909091 原料_鉻 = 0.0 原料_鎳 = 13.590909 最優總成本 = 9953.671725000002版權說明:
原創作品= 關注 Youcans,分享原創系列 https://blog.csdn.net/youcans =
Copyright 2021 YouCans, XUPT
Crated:2021-04-28
關注 Youcans,分享原創系列 https://blog.csdn.net/youcans
Python數模筆記-PuLP庫(1)線性規劃入門
Python數模筆記-PuLP庫(2)線性規劃進階
Python數模筆記-PuLP庫(3)線性規劃實例
Python數模筆記-StatsModels 統計回歸(1)簡介
Python數模筆記-StatsModels 統計回歸(2)線性回歸
Python數模筆記-StatsModels 統計回歸(3)模型數據的準備
Python數模筆記-StatsModels 統計回歸(4)可視化
Python數模筆記-Sklearn (1)介紹
Python數模筆記-Sklearn (2)聚類分析
Python數模筆記-Sklearn (3)主成分分析
Python數模筆記-Sklearn (4)線性回歸
Python數模筆記-Sklearn (5)支持向量機
Python數模筆記-模擬退火算法(1)多變量函數優化
Python數模筆記-模擬退火算法(2)約束條件的處理
Python數模筆記-模擬退火算法(3)整數規劃問題
Python數模筆記-模擬退火算法(4)旅行商問題
總結
以上是生活随笔為你收集整理的Python数模笔记-PuLP库(2)线性规划进阶的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL语句中,创建标识列、默认值及各种约
- 下一篇: python里面的list