Pyomo中不同含义同名时间索引t的定义与使用方法
Pyomo不同语义时间索引决策变量实现方案
首先直接给结论:建议为三类不同语义的时间定义三个命名清晰的独立集合,不要复用同一个t索引,哪怕三类时间的取值范围完全一致,也最好做明确区分,从根源上避免索引混用导致的隐蔽bug。
具体实现可以参考以下逻辑:
- 第一步:先按时间语义定义对应集合,不要用无意义的
t当集合名,直接把时间含义写到集合名里,比如出发时间集合、装载时间集合、作业时间集合,同时定义你需要的其他业务索引(比如节点i、j) - 第二步:定义决策变量时,每个变量绑定对应语义的时间集合即可,索引顺序和你公式里的上下标保持一致就行
参考实现代码:
from pyomo.environ import * model = ConcreteModel() # 1. 定义基础业务索引 model.I = Set(initialize=[1,2,3]) # 对应公式里的i节点 model.J = Set(initialize=[1,2,3]) # 对应公式里的j节点 # 2. 按语义定义三类不同的时间集合,初始化值按你的实际业务时间填 model.departure_t = Set(initialize=[6,7,8,9,10,11,12]) # y变量用的出发时间 model.loading_t = Set(initialize=[8,9,10,11,12,13,14]) # X变量用的装载时间 model.operation_t = Set(initialize=range(0,24)) # u变量用的作业时间 # 3. 定义三个带对应时间索引的决策变量,域根据你的实际需求改 model.y = Var(model.J, model.departure_t, within=Binary) # 对应y_j^t model.X = Var(model.I, model.J, model.loading_t, within=NonNegativeReals) # 对应X_ij^t model.u = Var(model.I, model.operation_t, within=NonNegativeReals) # 对应u_i^t
如果三类时间的取值范围完全相同,你也可以先定义一个基础时间集合,再给它起三个语义不同的别名,减少重复的初始化代码,本质还是三个独立的索引标识,不会出现混用问题:
# 基础时间全集 model.full_t = Set(initialize=range(0,24)) # 三个语义别名集合,取值和full_t一致 model.departure_t = model.full_t model.loading_t = model.full_t model.operation_t = model.full_t
注意:绝对不要图省事给三个变量都绑定同一个叫
t的时间集合,后续写跨时间维度的约束时,你很容易把出发时间、装载时间、作业时间搞混,这类错误不会触发代码报错,但会直接导致模型计算结果完全错误,排查成本极高。
比如写跨时间维度的约束时,命名清晰的集合能让你一眼看清索引逻辑,不容易写错:
# 示例约束:j点的出发时间必须晚于对应i到j订单的装载时间 def depart_after_load_rule(model, i, j, lt, dt): if dt < lt: return model.X[i,j,lt] * model.y[j,dt] == 0 return Constraint.Skip model.depart_after_load_cons = Constraint( model.I, model.J, model.loading_t, model.departure_t, rule=depart_after_load_rule )
内容的提问来源于stack exchange,提问作者mary
相关产品推荐
相关产品推荐

