多阶段随机优化中非预期性约束的索引错误排查求助
多阶段随机优化模型非预期性约束索引错误排查
问题场景
构建多阶段随机优化模型时,添加非预期性约束出现索引错误,错误提示:
KeyError: "Index '(1, 1, 1, 1, 1)' is not valid for indexed component 'Prod'"
模型集合定义
graph = { 1 : [2], 2 : [3, 4], 3 : [4, 5, 6], 4 : [7, 8, 9], 5 : [], 6 : [], 7 : [], 8 : [], 9 : [10], 10 : [], 11 : [12], 12 : [4, 8] } connections = [(s, t) for s in graph.keys() for t in graph[s]] model.N = pyo.Set(initialize=graph.keys()) ## 所有节点集合 model.P = pyo.Set(within=model.N, initialize= [1, 11]) ## 生产节点集合 model.connection = pyo.Set(model.N, within=model.N, initialize=graph) ## 节点关联集合,按节点索引 model.E = pyo.Set(within=model.N * model.N, initialize=connections) ## 所有边(弧)集合 model.T = pyo.Set(initialize=range(1,8)) ## 时间周期集合 model.S = pyo.Set(initialize= [1, 2, 3, 4]) model.Prod = pyo.Var(model.P, model.T, model.S, within=NonNegativeReals)
非预期性约束场景集合Omega
Omega = { 1: { 1: [1, 2, 3, 4], 2: [1, 2], 3: [1, 2], 4: [1, 2], 5: [1], 6: [1], 7: [1], }, 2: { 1: [1, 2, 3, 4], 2: [1, 2], 3: [1, 2], 4: [1, 2], 5: [2], 6: [2], 7: [2], }, 3: { 1: [1, 2, 3, 4], 2: [3, 4], 3: [3, 4], 4: [3, 4], 5: [3], 6: [3], 7: [3], }, 4: { 1: [1, 2, 3, 4], 2: [3, 4], 3: [3, 4], 4: [3, 4], 5: [4], 6: [4], 7: [4], } }
出错的约束代码
model.AA1 = ConstraintList() for P in model.Prod: for T in model.T: for S in model.S: for Omega in Omega[S][T]: model.AA1.add(model.Prod[P, T, S] == model.Prod[P, T, Omega]) model.pprint()
对比可正常运行的相似逻辑代码
W = Set(initialize=range(1, 4)) S = Set(initialize=range(1, 5)) TH = Set(initialize=range(1, 3)) model_parcel.z = Var(W, TH, S, within=NonNegativeIntegers) Omega = { 1: {1: [1, 2, 3, 4], 2: [1, 2], 3: [1]}, 2: {1: [1, 2, 3, 4], 2: [1, 2], 3: [2]}, 3: {1: [1, 2, 3, 4], 2: [3, 4], 3: [3]}, 4: {1: [1, 2, 3, 4], 2: [3, 4], 3: [4]}, } model_parcel.non_anticipativity_z = ConstraintList() for w in W: for t in TH: for s in S: for omega in Omega[s][t]: model_parcel.non_anticipativity_z.add(model_parcel.z[w, t, s] == model_parcel.z[w, t, omega])
错误原因
核心错误在于遍历对象错误:
model.Prod是一个三维决策变量(索引为model.P, model.T, model.S),直接遍历它时,每次拿到的P是一个三元组(比如(1,1,1)),而非单个生产节点ID。- 后续嵌套循环中又加入
T和S,导致访问model.Prod[P, T, S]时,实际传入的是((1,1,1), 1, 1),也就是五维索引,完全超出了Prod的三维定义范围,因此触发索引错误。
而可正常运行的代码中,遍历的是单个维度的集合W,而非变量本身,所以不会出现索引维度溢出的问题。
另外,循环变量Omega与外部字典Omega重名,会导致后续无法访问原字典,虽然不是本次报错的直接原因,但属于代码隐患。
修复方案
将遍历model.Prod改为遍历生产节点集合model.P,同时修正循环变量名避免重名:
model.AA1 = ConstraintList() for P in model.P: # 遍历生产节点集合,而非三维变量 for T in model.T: for S in model.S: for omega in Omega[S][T]: # 改用小写omega避免与字典名重名 model.AA1.add(model.Prod[P, T, S] == model.Prod[P, T, omega]) model.pprint()
内容的提问来源于stack exchange,提问作者Cvakapoor
相关产品推荐
相关产品推荐

