Pyomo运输模型:新增工厂跨周期启动固定成本约束的实现问询
解决Pyomo中工厂启动固定成本约束的实现方法
核心思路
要处理“第1周无生产、第2周有生产需额外支付100美元启动成本”的逻辑,需引入二进制变量标记工厂的启动状态,通过线性约束关联生产变量与启动变量,最后将启动成本纳入目标函数。
具体实现步骤
1. 定义启动状态二进制变量
为每个工厂添加一个二进制变量startup[i],其中i代表工厂:
startup[i] = 1:工厂i满足“第1周无生产、第2周有生产”的启动条件startup[i] = 0:不满足启动条件
2. 添加约束关联生产与启动变量
假设你已定义生产变量produce[i, t](i为工厂,t为周次,t=1对应第1周,t=2对应第2周),需添加两组约束:
- 约束1:若工厂触发启动(
startup[i]=1),则第1周必须无生产 - 约束2:若工厂触发启动(
startup[i]=1),则第2周必须有生产
通过大M法实现线性约束,其中:
M为足够大的常数(需大于工厂单周最大可能产量)epsilon为极小正数(确保生产变量严格大于0,若生产为整数可设为1)
3. 更新目标函数
在原目标函数基础上,追加启动固定成本:每个触发启动的工厂增加100美元成本。
完整代码示例片段
from pyomo.environ import * # 假设已有的模型基础定义 model = ConcreteModel() model.factories = Set(initialize=['F1', 'F2', 'F3']) # 3家工厂 model.time_periods = Set(initialize=[1, 2]) # 2周 # 已有生产变量:produce[i,t] 表示工厂i在t周的产量 model.produce = Var(model.factories, model.time_periods, domain=NonNegativeReals) # 1. 添加启动状态二进制变量 model.startup = Var(model.factories, domain=Binary) # 2. 配置启动约束 # 定义大M和epsilon(根据实际生产情况调整) M = 10000 # 需大于工厂单周最大产能 epsilon = 0.001 # 若生产为整数,可改为1 def startup_no_prod_week1(model, i): # 启动状态触发时,第1周产量必须为0 return model.produce[i, 1] <= M * (1 - model.startup[i]) model.startup_constraint1 = Constraint(model.factories, rule=startup_no_prod_week1) def startup_has_prod_week2(model, i): # 启动状态触发时,第2周产量必须大于0 return model.produce[i, 2] >= epsilon * model.startup[i] model.startup_constraint2 = Constraint(model.factories, rule=startup_has_prod_week2) # 3. 更新目标函数(替换为你原有的成本计算逻辑,追加启动成本) def objective_rule(model): # 原目标函数示例(替换为你的实际运输+生产成本) original_cost = sum(model.produce[i,t] * 5 for i in model.factories for t in model.time_periods) # 追加启动固定成本 startup_cost = sum(model.startup[i] * 100 for i in model.factories) return original_cost + startup_cost model.objective = Objective(rule=objective_rule, sense=minimize)
注意事项
M的取值需合理:既要大于工厂单周最大产能,避免约束失效;也不要过大,防止数值求解时出现精度问题- 若生产变量为整数类型(如按件生产),可将
epsilon设为1,更贴合实际业务逻辑
内容的提问来源于stack exchange,提问作者Hookstark
相关产品推荐
相关产品推荐

