服裝種類 | 設備租金 | 材料成本 | 銷售價格 | 人工工時 | 設備工時 | 設備可用工時 |
---|---|---|---|---|---|---|
單位 | (元) | (元/件) | (元/件) | (小時/件) | (小時/件) | (小時) |
A | 5000 | 280 | 400 | 5 | 3 | 300 |
B | 2000 | 30 | 40 | 1 | 0.5 | 300 |
C | 2000 | 200 | 300 | 4 | 2 | 300 |
如果各類服裝的市場需求都足夠大,服裝廠每月可用人工時為 2000h,那么應該如何安排生產(chǎn)計劃使利潤最大?
首先要理解生產(chǎn)某種服裝就會發(fā)生設備租金,租金只與是否生產(chǎn)該產(chǎn)品有關,而與生產(chǎn)數(shù)量無關,這就是固定成本。因此本題屬于固定費用問題。
有些同學下意識地認為是從 3 種產(chǎn)品中選擇一種,但題目中并沒有限定必須或只能生產(chǎn)一種產(chǎn)品,因此決策結果可以是都不生產(chǎn)、選擇 1 種或 2 種產(chǎn)品、3 種都生產(chǎn)。
決策結果會是什么都不生產(chǎn)嗎?有可能的。
每種產(chǎn)品的利潤:(銷售價格 - 材料成本)× 生產(chǎn)數(shù)量 - 設備租金
本題中如果設備租金很高,決策結果就可能是什么都不做時利潤最大,這是利潤為 0,至少不虧。
現(xiàn)在可以用固定費用問題的數(shù)學模型來描述問題了:
編程求解建立的數(shù)學模型,用標準模型的優(yōu)化算法對模型求解,得到優(yōu)化結果。
模型求解的編程步驟與之前的線性規(guī)劃、整數(shù)規(guī)劃問題并沒有什么區(qū)別,這就是 PuLP工具包的優(yōu)勢。
(0)導入 PuLP庫函數(shù)
import pulp
(1)定義一個規(guī)劃問題
FixedCostP1 = pulp.LpProblem("Fixed_cost_problem", sense=pulp.LpMaximize) # 定義問題,求最大值
pulp.LpProblem 用來定義問題的構造函數(shù)。"FixedCostP1"是用戶定義的問題名。
參數(shù) sense 指定問題求目標函數(shù)的最小值/最大值 。本例求最大值,選擇 “pulp.LpMaximize” 。
(2)定義決策變量
x1 = pulp.LpVariable('A', cat='Binary') # 定義 x1,0-1變量,是否生產(chǎn) A 產(chǎn)品 x2 = pulp.LpVariable('B', cat='Binary') # 定義 x2,0-1變量,是否生產(chǎn) B 產(chǎn)品 x3 = pulp.LpVariable('C', cat='Binary') # 定義 x3,0-1變量,是否生產(chǎn) C 產(chǎn)品 y1 = pulp.LpVariable('yieldA', lowBound=0, upBound=100, cat='Integer') # 定義 y1,整型變量 y2 = pulp.LpVariable('yieldB', lowBound=0, upBound=600, cat='Integer') # 定義 y2,整型變量 y3 = pulp.LpVariable('youCans', lowBound=0, upBound=150, cat='Integer') # 定義 y3,整型變量
pulp.LpVariable 用來定義決策變量的函數(shù)。參數(shù) cat 用來設定變量類型,' Binary ' 表示0/1變量(用于0/1規(guī)劃問題),' Integer ' 表示整數(shù)變量。'lowBound'、'upBound' 分別表示變量取值范圍的下限和上限。
(3)添加目標函數(shù)
FixedCostP1 += pulp.lpSum(-5000*x1-2000*x2-2000*x3+120*y1+10*y2+100*y3) # 設置目標函數(shù) f(x)
(4)添加約束條件
FixedCostP1 += (5*y1 + y2 + 4*y3 = 2000) # 不等式約束 FixedCostP1 += (3*y1 - 300*x1 = 0) # 不等式約束 FixedCostP1 += (0.5*y2 - 300*x2 = 0) # 不等式約束 FixedCostP1 += (2*y3 - 300*x3 = 0) # 不等式約束
添加約束條件使用 "問題名 += 約束條件表達式" 格式。
約束條件可以是等式約束或不等式約束,不等式約束可以是 小于等于 或 大于等于,分別使用關鍵字">="、"="和"=="。
(5)求解
FixedCostP1.solve()
solve() 是求解函數(shù),可以對求解器、求解精度進行設置。
import pulp # 導入 pulp 庫 # 主程序 def main(): # 固定費用問題(Fixed cost problem) print("固定費用問題(Fixed cost problem)") # 問題建模: """ 決策變量: y(i) = 0, 不生產(chǎn)第 i 種產(chǎn)品 y(i) = 1, 生產(chǎn)第 i 種產(chǎn)品 x(i), 生產(chǎn)第 i 種產(chǎn)品的數(shù)量, i>=0 整數(shù) i=1,2,3 目標函數(shù): min profit = 120x1 + 10x2+ 100x3 - 5000y1 - 2000y2 - 2000y3 約束條件: 5x1 + x2 + 4x3 = 2000 3x1 = 300y1 0.5x2 = 300y2 2x3 = 300y3 變量取值范圍:Youcans XUPT 0=x1=100, 0=x2=600, 0=x3=150, 整數(shù)變量 y1, y2 ,y3 為 0/1 變量 """ # 1. 固定費用問題(Fixed cost problem), 使用 PuLP 工具包求解 # (1) 建立優(yōu)化問題 FixedCostP1: 求最大值(LpMaximize) FixedCostP1 = pulp.LpProblem("Fixed_cost_problem_1", sense=pulp.LpMaximize) # 定義問題,求最大值 # (2) 建立變量 x1 = pulp.LpVariable('A', cat='Binary') # 定義 x1,0-1變量,是否生產(chǎn) A 產(chǎn)品 x2 = pulp.LpVariable('B', cat='Binary') # 定義 x2,0-1變量,是否生產(chǎn) B 產(chǎn)品 x3 = pulp.LpVariable('C', cat='Binary') # 定義 x3,0-1變量,是否生產(chǎn) C 產(chǎn)品 y1 = pulp.LpVariable('yieldA', lowBound=0, upBound=100, cat='Integer') # 定義 y1,整型變量 y2 = pulp.LpVariable('yieldB', lowBound=0, upBound=600, cat='Integer') # 定義 y2,整型變量 y3 = pulp.LpVariable('yieldC', lowBound=0, upBound=150, cat='Integer') # 定義 y3,整型變量 # (3) 設置目標函數(shù) FixedCostP1 += pulp.lpSum(-5000*x1-2000*x2-2000*x3+120*y1+10*y2+100*y3) # 設置目標函數(shù) f(x) # (4) 設置約束條件 FixedCostP1 += (5*y1 + y2 + 4*y3 = 2000) # 不等式約束 FixedCostP1 += (3*y1 - 300*x1 = 0) # 不等式約束 FixedCostP1 += (0.5*y2 - 300*x2 = 0) # 不等式約束 FixedCostP1 += (2*y3 - 300*x3 = 0) # 不等式約束 # (5) 求解 youcans FixedCostP1.solve() # (6) 打印結果 print(FixedCostP1.name) if pulp.LpStatus[FixedCostP1.status] == "Optimal": # 獲得最優(yōu)解 for v in FixedCostP1.variables(): # youcans print(v.name, "=", v.varValue) # 輸出每個變量的最優(yōu)值 print("Youcans F(x) = ", pulp.value(FixedCostP1.objective)) # 輸出最優(yōu)解的目標函數(shù)值 return if __name__ == '__main__': # Copyright 2021 YouCans, XUPT main()
Welcome to the CBC MILP Solver
Version: 2.9.0
Build Date: Feb 12 2015
Result - Optimal solution found
Fixed_cost_problem_1
A = 1.0
B = 1.0
C = 1.0
yieldA = 100.0
yieldB = 600.0
yieldC = 150.0
Max F(x) = 24000.0
從固定費用問題模型的求解結果可知,A、B、C 三種服裝都生產(chǎn),產(chǎn)量分別為 A/100、B/600、C/150 時獲得最大利潤為:24000。
通過從線性規(guī)劃、整數(shù)規(guī)劃、0-1規(guī)劃到上例中的混合0-1規(guī)劃問題,我們已經(jīng)充分體會到 PuLP 使用相同的步驟和參數(shù)處理不同問題所帶來的便利。
但是,如果問題非常復雜,例如變量數(shù)量很多,約束條件復雜,逐個定義變量、逐項編寫目標函數(shù)與約束條件的表達式,不僅顯得重復冗長,不方便修改對變量和參數(shù)的定義,而且在輸入過程中容易發(fā)生錯誤。因此,我們希望用字典、列表、循環(huán)等快捷方法來進行變量定義、目標函數(shù)和約束條件設置。
PuLP 提供了快捷建模的編程方案,下面我們仍以上節(jié)中的固定費用問題為例進行介紹。本例中的問題、條件和參數(shù)都與上節(jié)完全相同,以便讀者進行對照比較快捷方法的具體內容。
(0)導入 PuLP 庫函數(shù)
import pulp
(1)定義一個規(guī)劃問題
FixedCostP2 = pulp.LpProblem("Fixed_cost_problem", sense=pulp.LpMaximize) # 定義問題,求最大值
(2)定義決策變量
types = ['A', 'B', 'C'] # 定義產(chǎn)品種類 status = pulp.LpVariable.dicts("生產(chǎn)決策", types, cat='Binary') # 定義 0/1 變量,是否生產(chǎn)該產(chǎn)品 yields = pulp.LpVariable.dicts("生產(chǎn)數(shù)量", types, lowBound=0, upBound=600, cat='Integer') # 定義整型變量
本例中的快捷方法使用列表 types 定義 0/1 變量 status 和 整型變量 yields,不論產(chǎn)品的品種有多少,都只有以上幾句,從而使程序大為簡化。
(3)添加目標函數(shù)
fixedCost = {'A':5000, 'B':2000, 'C':2000} # 各產(chǎn)品的 固定費用 unitProfit = {'A':120, 'B':10, 'C':100} # 各產(chǎn)品的 單位利潤 FixedCostP2 += pulp.lpSum([(yields[i]*unitProfit[i]- status[i]*fixedCost[i]) for i in types])
雖然看起來本例中定義目標函數(shù)的程序語句較長,但由于使用字典定義參數(shù)、使用 for 循環(huán)定義目標函數(shù),因此程序更加清晰、簡明、便于修改參數(shù)、不容易輸入錯誤。
(4)添加約束條件
humanHours = {'A':5, 'B':1, 'C':4} # 各產(chǎn)品的 單位人工工時 machineHours = {'A':3.0, 'B':0.5, 'C':2.0} # 各產(chǎn)品的 單位設備工時 maxHours = {'A':300, 'B':300, 'C':300} # 各產(chǎn)品的 最大設備工時 FixedCostP2 += pulp.lpSum([humanHours[i] * yields[i] for i in types]) = 2000 # 不等式約束 for i in types: FixedCostP2 += (yields[i]*machineHours[i] - status[i]*maxHours[i] = 0) # 不等式約束
快捷方法對于約束條件的定義與對目標函數(shù)的定義相似,使用字典定義參數(shù),使用循環(huán)定義約束條件,使程序簡單、結構清楚。
注意本例使用了兩種不同的循環(huán)表達方式:語句內使用 for 循環(huán)遍歷列表實現(xiàn)所有變量的線性組合,標準的 for 循環(huán)結構實現(xiàn)多組具有相似結構的約束條件。讀者可以對照數(shù)學模型及上例的例程,理解這兩種定義約束條件的快捷方法。
(5)求解和結果的輸出
# (5) 求解 FixedCostP2.solve() # (6) 打印結果 print(FixedCostP2.name) temple = "品種 %(type)s 的決策是:%(status)s,生產(chǎn)數(shù)量為:%(yields)d" if pulp.LpStatus[FixedCostP2.status] == "Optimal": # 獲得最優(yōu)解 for i in types: output = {'type': i, 'status': '同意' if status[i].varValue else '否決', 'yields': yields[i].varValue} print(temple % output) # youcans@qq.com print("最大利潤 = ", pulp.value(FixedCostP2.objective)) # 輸出最優(yōu)解的目標函數(shù)值
由于快捷方法使用列表或字典定義變量,對求解的優(yōu)化結果也便于實現(xiàn)結構化的輸出。
import pulp # 導入 pulp 庫 # 主程序 def main(): # 2. 問題同上,PuLP 快捷方法示例 # (1) 建立優(yōu)化問題 FixedCostP2: 求最大值(LpMaximize) FixedCostP2 = pulp.LpProblem("Fixed_cost_problem_2", sense=pulp.LpMaximize) # 定義問題,求最大值 # (2) 建立變量 types = ['A', 'B', 'C'] # 定義產(chǎn)品種類 status = pulp.LpVariable.dicts("生產(chǎn)決策", types, cat='Binary') # 定義 0/1 變量,是否生產(chǎn)該產(chǎn)品 yields = pulp.LpVariable.dicts("生產(chǎn)數(shù)量", types, lowBound=0, upBound=600, cat='Integer') # 定義整型變量 # (3) 設置目標函數(shù) fixedCost = {'A':5000, 'B':2000, 'C':2000} # 各產(chǎn)品的 固定費用 unitProfit = {'A':120, 'B':10, 'C':100} # 各產(chǎn)品的 單位利潤 FixedCostP2 += pulp.lpSum([(yields[i]*unitProfit[i]- status[i]*fixedCost[i]) for i in types]) # (4) 設置約束條件 humanHours = {'A':5, 'B':1, 'C':4} # 各產(chǎn)品的 單位人工工時 machineHours = {'A':3.0, 'B':0.5, 'C':2.0} # 各產(chǎn)品的 單位設備工時 maxHours = {'A':300, 'B':300, 'C':300} # 各產(chǎn)品的 最大設備工時 FixedCostP2 += pulp.lpSum([humanHours[i] * yields[i] for i in types]) = 2000 # 不等式約束 for i in types: FixedCostP2 += (yields[i]*machineHours[i] - status[i]*maxHours[i] = 0) # 不等式約束 # (5) 求解 youcans FixedCostP2.solve() # (6) 打印結果 print(FixedCostP2.name) temple = "品種 %(type)s 的決策是:%(status)s,生產(chǎn)數(shù)量為:%(yields)d" if pulp.LpStatus[FixedCostP2.status] == "Optimal": # 獲得最優(yōu)解 for i in types: output = {'type': i, 'status': '同意' if status[i].varValue else '否決', 'yields': yields[i].varValue} print(temple % output) print("最大利潤 = ", pulp.value(FixedCostP2.objective)) # 輸出最優(yōu)解的目標函數(shù)值 return if __name__ == '__main__': # Copyright 2021 YouCans, XUPT main()
Welcome to the CBC MILP Solver
Version: 2.9.0
Build Date: Feb 12 2015
Result - Optimal solution found
Fixed_cost_problem_2
品種 A 的決策是:同意,生產(chǎn)數(shù)量為:100
品種 B 的決策是:同意,生產(chǎn)數(shù)量為:600
品種 C 的決策是:同意,生產(chǎn)數(shù)量為:150
最大利潤 = 24000.0
本例的問題、條件和參數(shù)都與上節(jié)完全相同,只是采用 PuLP 提供的快捷建模的編程方案,優(yōu)化結果也與 PuLP 標準方法完全相同,但本例使用了結構化的輸出顯示,使輸出結果更為直觀。
以上就是淺談Python數(shù)學建模之固定費用問題的詳細內容,更多關于Python 數(shù)學建模 固定費用的資料請關注腳本之家其它相關文章!