我在用Pyomo为3d索引变量制定约束时遇到问题:我有以下变量列表:
1 Var Declarations
E : Size=6, Index=N
Key : Lower : Value : Upper : Fixed : Stale : Domain
(0, 0, 2) : 0 : 10 : None : False : False : NonNegativeReals
(0, 0, 3) : 0 : 10 : None : False : False : NonNegativeReals
(0, 2, 0) : 0 : 10 : None : False : False : NonNegativeReals
(0, 3, 0) : 0 : 10 : None : False : False : NonNegativeReals
(1, 3, 1) : 0 : 10 : None : False : False : NonNegativeReals
(1, 4, 1) : 0 : 10 : None : False : False : NonNegativeReals
它们本质上是3D数组(2x5x5)中的值,该值可以采用非0的值。我尝试通过一些约束对它们进行优化:-行中变量的总和应最大化-列中变量的总和应取特定值
我的问题考虑到两个约束:我试图像这样制定第一个约束:
def max_perf_rule(model, a, b):
return sum(model.E[a,b,c] for c in range(5) if (a,b,c) in model.N) <= H[a,b]
model.max_perf = Constraint(range(2), range(5), rule = max_perf_rule)
,其中model.N = [[0,0,2),(0,0,3),(0,2,0),(0,3,0),(1,3,1),( 1,4,1)]
变量最初是由model.N(3d元组列表)给定的,但在此约束中我需要两个“ range(2)”和“ range(5)”作为输入,以便能够引用适当的行。
无论我尝试什么,都无法创建所需的约束。他们应该看起来像这样:
max_perf : Size=10, Index=max_perf_index, Active=True
(0, 0) : E[0,0,2] + E[0,0,3] : <= 0.0
(0, 2) : E[0,2,0] : <= 2688.0
(0, 3) : E[0,3,0] : <= 896.0
(1, 3) : E[1,3,1] : <= 448.0
(1, 4) : E[1,4,1] : <= 9999999.0
...但是我一直收到以下错误:
"ERROR: Constructing component 'max_perf' from data=None failed: ValueError:
Invalid constraint expression. The constraint expression resolved to a
trivial Boolean (True) instead of a Pyomo object. Please modify your rule
to return Constraint.Feasible instead of True.
Error thrown for Constraint 'max_perf[0,1]'"
我不知道这是什么;我什至尝试用字典而不是model.E重现这种情况,并且效果很好。
您对此问题有解决方案吗?预先感谢!
问题在于,通过设置索引集的方式,并不是model.N
中出现range(2)x range(5)x range(5)的每个组合。对于某些组合,约束规则中的sum
将没有任何条件,因此求值为常数0。解决此问题的最简单方法是在约束规则中添加检查以确保总和不为零。空:
def max_perf_rule(model, a, b):
temp = sum(model.E[a,b,c] for c in range(5) if (a,b,c) in model.N)
if type(temp) is int: # This will be true if the sum was empty
return Constraint.Skip
return temp <= H[a,b]
model.max_perf = Constraint(range(2), range(5), rule = max_perf_rule)