我正在使用pyomo库在python中开发一个优化模型(我刚刚开始使用它)。我可以在excel中建模,并带有必要的约束条件。然而,我在python中收到一条错误消息,我似乎无法理解。下面是代码和错误消息。一切帮助都将不胜感激。谢谢
from scipy.stats import norm
setup_cost = 125
holding_cost = 17
annual_demand = 1200
std_annual_demand = 70
lead_time = 1/52
ltd = annual_demand*lead_time
std_ltd = 9.707
model = ConcreteModel()
model.order_quantity = Var(bounds = (0,None))
model.multiple_k = Var(bounds = (0,None))
def total_annual_cost(model):
orders_per_year = annual_demand/model.order_quantity
safety_stock = model.multiple_k * std_ltd
annual_ordering_cost = orders_per_year * setup_cost
annual_holding_cost = holding_cost*(safety_stock+model.order_quantity/2)
total_cost = annual_holding_cost + annual_ordering_cost
return total_cost
def service_level(model):
k = value(model.multiple_k)
order_quantity = value(model.order_quantity)
#expected_shortage_per_cycle = (norm.pdf(model.multiple_k)-model.multiple_k*(1-norm.cdf(model.multiple_k))) * std_ltd
expected_shortage_per_cycle = (norm.pdf(k)- k *(1-norm.cdf(k))) * std_ltd
service_level = 1-expected_shortage_per_cycle/order_quantity
return service_level
#model.service_level = Expression(initialize = ((norm.pdf(model.multiple_k)-model.multiple_k*(1-norm.cdf(model.multiple_k))) * std_ltd))
model.service_level_constraint = Constraint(rule = service_level)
model.objective = Objective(rule = total_annual_cost, sense = 1)
solver = SolverFactory('ipopt')
status = solver.solve(model)
错误:将对象计算为数值:多个(对象:)未初始化的数值对象多个没有值
错误:规则在生成约束service_level_constraint表达式时失败:值错误:未初始化的NumericValue对象没有值multiple_k
错误:构建组件'service_level_constraint'从数据=无失败:值错误:没有值的未初始化NumericValue对象multiple_k
这不是一个完整的答案,但您使用的函数(norm.pdf
和norm.cdf
)不能与数学编程模型中的模型变量一起使用。
如果您要使用这样的函数,您必须仅在参数上使用它们。如果您想将它们与模型变量一起用作参数,直接在模型中重写它们可能会很有趣。虽然对于norm.pdf
很容易做到这一点,但对于norm.cdf
可能更难,因为计算它的公式是不确定的。
有关如何使用或调整范数的讨论,请参见pyomo中概率分布的问题。cdf
转化为优化模型。我也在这里的StackExchange网站上发布了一个更一般的问题,因为这是所有AML通用的数学公式。
多亏了@V.Brunelle的建议,我将pdf和cdf函数直接重写到约束中,效果非常好。
from pyomo.environ import *
setup_cost = 125
holding_cost = 17
annual_demand = 1200
std_annual_demand = 70
lead_time = 1/52
ltd = annual_demand*lead_time
std_ltd = 9.707
model = ConcreteModel()
model.order_quantity = Var(bounds = (0,None))
model.multiple_k = Var(bounds = (0,None))
def total_annual_cost(model):
safety_stock = model.multiple_k * std_ltd
orders_per_year = annual_demand/model.order_quantity
annual_ordering_cost = orders_per_year * setup_cost
annual_holding_cost = holding_cost*(safety_stock+(model.order_quantity/2))
total_cost = annual_holding_cost + annual_ordering_cost
return total_cost
def service_level_req(model):
e = np.exp(1)
pi = np.pi
pdf = e**(-((model.multiple_k ** 2)/2))/np.sqrt(2*np.pi)
cdf = 1/(1+ (e**(-(model.multiple_k * 1.65451))))
expected_shortage_per_cycle = (pdf - ((1-cdf)*model.multiple_k))* std_ltd
service_level = 1-expected_shortage_per_cycle/model.order_quantity
return service_level >= .98
def turn_requirement(model):
rop = model.multiple_k * std_ltd + ltd
max_rop = model.order_quantity-1 + rop
turn = annual_demand/max_rop
return turn >= 6
model.sl_const = Constraint(rule = service_level_req)
model.turn_const = Constraint(rule = turn_requirement)
model.objective = Objective(rule = total_annual_cost, sense = 1)
solver = SolverFactory('ipopt')
status = solver.solve(model)