如何修复Pyomo中的‘ValueError: Constraint does not have a proper value’错误
ValueError: Constraint does not have a proper value.
ValueError: Constraint 'uvuoncea122222222222[1]' does not have a proper value. Found 'AbstractScalarConstraint' Expecting a tuple or relational expression. Examples: sum(model.costs) == model.income (0, model.price[item], 50)
这是定义约束3时遇到的错误,以下是集合、决策变量定义及相关代码:
集合定义
## Sets model.P = pe.Set(initialize = depots, ordered = False) #depots model.S = pe.Set(initialize = satellites, ordered = False) #satellites model.I = pe.Set(within=model.P | model.S) #union depots and satellites model.Z = pe.Set(initialize = customers, ordered = False) #customers model.Y = pe.Set(within=model.S | model.Z) #union customers and satellites model.T = pe.Set(initialize=numUV, ordered=False) #FE vehicle model.F = pe.Set(initialize=numCF, ordered=False) #SE vehicle model.V = model.P | model.S | model.Z model.A = model.V*model.V
决策变量定义
## Decision variables model.x = pe.Var(model.T, model.P, model.S, domain = pe.NonNegativeIntegers) #flow FE model.r = pe.Var(model.T, model.P, model.S, domain = pe.Binary) #binary FE arc used model.q = pe.Var(model.F, model.S, model.Z, domain = pe.Binary) #binary SE arc used model.w = pe.Var(model.Z, model.S, domain = pe.Binary) #binary Z gekoppeld aan S model.u1 = pe.Var(model.T, domain = pe.Binary) #binary FE vehicle used model.u2 = pe.Var(model.F, domain = pe.Binary) #binary SE vehicle used model.p1 = pe.Var(model.T, model.S,domain = pe.NonNegativeIntegers) #arrival time at s model.b1 = pe.Var(model.F, model.Z, domain = pe.NonNegativeIntegers) #arrival time at z #model.pi = pe.Var(model.F, domain = pe.NonNegativeIntegers) #working duration model.pprint()
目标函数
## Objective function objExpr = (sum(model.r[t,i,j]* c[i,j] * cKm for t in model.T for i in model.I for j in model.I)\ + sum(model.q[f,i,j]* c[i,j] * cKm for f in model.F for i in model.Y for j in model.Y)\ + sum(model.u1[t]* ch1 for t in model.T) + sum(model.u2[f] * ch2 for f in model.F)) model.obj = pe.Objective(expr = objExpr, sense = pe.minimize)
约束定义
## Constraints #2 model.confcfe = pe.ConstraintList() for j in model.I: for t in model.T: expression = sum(model.r[t,l,j] for l in model.I) - sum(model.r[t,j,l] for l in model.I) == 0 model.confcfe.add(expression) #3 model.uvuoncea122222222222 = pe.ConstraintList() for t in model.T: expression = sum(model.r[t, i, j] for i in model.I for j in model.P) constraint = pe.Constraint(expr=expression <= 1) model.uvuoncea122222222222.add(constraint)
我用不同于约束2的方式编写约束3,是因为之前写约束3会出现布尔值相关错误,原以为此写法能解决问题。尝试过多种约束定义方式(如约束规则、直接/间接添加到模型、范围约束等),但均无法解决该错误。
问题解决
错误核心原因是**ConstraintList.add()方法只接受关系表达式(如sum(...) <= 1),不能传入已经实例化的pe.Constraint对象**。你在约束3里先创建pe.Constraint实例再添加到列表,违背了ConstraintList的使用逻辑。
修改约束3的代码,直接将关系表达式传入add()即可:
#3 修改后的代码 model.uvuoncea122222222222 = pe.ConstraintList() for t in model.T: expression = sum(model.r[t, i, j] for i in model.I for j in model.P) <= 1 model.uvuoncea122222222222.add(expression)
另外需要注意:model.r定义的维度是(model.T, model.P, model.S),但你在约束3中使用model.r[t,i,j]时,i属于model.I(P|S),j属于model.P,这会导致当i是S中的元素时,访问model.r[t,S,P]超出变量定义的索引范围(原变量r的第二个索引只能是P,第三个是S),这大概率是之前布尔值错误的根源。请确认约束逻辑是否正确,或调整model.r的定义维度。
内容的提问来源于stack exchange,提问作者Wieger Prinsze
相关产品推荐
相关产品推荐

