【问题标题】:Constraint formulation in Pyomo with 3d-indexed varaiblesPyomo 中具有 3d 索引变量的约束公式
【发布时间】:2019-10-25 13:50:46
【问题描述】:

我在使用 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 来重现这种情况,而且效果很好。

你有解决这个问题的办法吗? 提前致谢!

【问题讨论】:

    标签: python list-comprehension pyomo


    【解决方案1】:

    问题在于,根据您设置索引集的方式,并非 range(2) x range(5) x range(5) 的每个组合都出现在 model.N 中。对于某些组合,约束规则中的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) 
    

    【讨论】:

      猜你喜欢
      • 2021-09-12
      • 2022-11-27
      • 1970-01-01
      • 2018-07-10
      • 1970-01-01
      • 2018-07-09
      • 2019-02-02
      • 2020-04-01
      • 2017-09-10
      相关资源
      最近更新 更多