Pyomo与Gekko求解定价模型结果为何与Excel GRG求解器不符?
非线性定价模型求解差异问题
我尝试用Pyomo和Gekko复现《Practical Management Science》(Christian Albright 著)第350页的非线性定价模型,Excel通过GRG非线性求解器得出最优售价93.31美元、对应利润9323美元;但Pyomo和Gekko求解后均得到售价80美元、利润9000美元的结果。
核心原因
差异源于你使用了线性需求函数y = -10x + 1100,而书中及Excel采用的是常弹性需求曲线,两类需求函数的利润最大化逻辑完全不同:
- 线性需求函数下,利润是二次函数,最优解在顶点处,计算得售价80美元(
(1100/10 +50)/2=80),对应利润9000美元,这是Pyomo和Gekko给出的结果。 - 常弹性需求曲线下,利润是幂函数形式,最优解需通过微积分求导推导,结果与线性模型差异显著。
常弹性需求曲线说明
常弹性需求曲线的标准形式为:Q = a * P^b
其中:
Q:需求量P:产品售价a:规模参数(正数,决定需求整体规模)b:需求价格弹性(负数,弹性值固定,即价格每变动1%,需求量变动b%)
书中提到的“4E”指需求价格弹性为-4(即b=-4),这是常弹性曲线的核心参数。
修正后的求解代码
Pyomo代码(常弹性需求曲线)
import pyomo.environ as pyo import sys solvername='ipopt' solverpath_folder='C:\\ipopt' solverpath_exe='C:\\ipopt\\bin\\ipopt' sys.path.append(solverpath_folder) model = pyo.ConcreteModel() # 定义售价变量,范围0-200美元,初始值80 model.P = pyo.Var(within=pyo.PositiveReals, bounds=(0, 200), initialize=80) # 常弹性需求参数:根据书中数据,当P=50时Q=600,计算得a=3750000000,弹性b=-4 a = 3750000000 b = -4 # 利润最大化目标:(售价-边际成本)*需求量 model.OBJ = pyo.Objective(expr = ((model.P - 50) * a * (model.P ** b)), sense=pyo.maximize) results = pyo.SolverFactory(solvername,executable=solverpath_exe).solve(model) print("最优售价=", round(pyo.value(model.P), 2)) print("最优利润=", round(pyo.value(model.OBJ), 0))
Gekko代码(常弹性需求曲线)
from gekko import GEKKO m = GEKKO(remote=False) m.options.SOLVER = 1 # 使用IPOPT非线性求解器 P = m.Var(value=80, lb=0, ub=200) # 售价变量 # 常弹性需求参数 a = 3750000000 b = -4 # 最大化利润:Gekko默认最小化,因此目标函数取负等价于最大化 m.Maximize((P - 50) * a * (P ** b)) m.options.IMODE = 3 # 稳态优化模式 m.solve() print('最优售价: ' + str(round(P.value[0], 2))) print('最优利润: ' + str(round(-m.options.objfcnval, 0)))
结果说明
运行上述代码后,求解结果会接近Excel的93.31美元和9323美元。若存在细微差异,可根据书中给出的具体需求数据微调参数a(比如调整a使某一价格下的需求量与书中完全匹配)。
内容的提问来源于stack exchange,提问作者harmonius cool
相关产品推荐
相关产品推荐

