Pyomo :行级别的求和约束 <= 1

Pyomo : summation constraint on row level <= 1

在 Pyomo 中设置具体模型时,我需要设置以下约束 sum_of_perc[次,公司] <= 1

目前我有以下代码

m.cons.add(sum(m.key_optimized[t, c] for t, c in itertools.product(m.times, m.companies)) <= 1)

itertools.product让我可以在不同的时间和公司之间循环。

考虑以下二维数组的 hypothetical/random 示例。每行是一个t,每个元素是c

[0.1 , 0.4 , 0.0 , 0.5] <= 1
[0.2 , 0.2 , 0.6 , 0.0] <= 1

目前我的约束试图让整个 2D 矩阵 <= 1。但我希望这是 t 级或行级的求和。我的代码的示例结果如下。这加起来正好是 1.

(0, 0) 0.34
(0, 1) 0.42
(0, 2) 0.0
(0, 3) 0.16
(1, 0) 0.005
(1, 1) 0.075
(1, 2) 0.0
(1, 3) 0.0

感谢您的协助!

我想这会回答你的问题...

首先,如果您想在没有 itertools 的情况下复制刚才所做的事情,则很容易制作 2 组的完整叉积。请参阅下面的第一部分。

如果您要为某物的每个设置约束,您应该立即考虑设置一个函数规则组合,为每个调用函数 您在约束中提供的集合成员。见下文后半部分。

In [22]: from pyomo.environ import *                                            

In [23]: m = ConcreteModel('example')                                           

In [24]: m.a = Set(initialize=[1,2,3])                                          

In [25]: m.b = Set(initialize=list('abc'))                                      

In [26]: from pyomo.environ import *                                            

In [27]: m = ConcreteModel('example')                                           

In [28]: m.A = Set(initialize=[1,2,3])                                          

In [29]: m.B = Set(initialize=list('abc'))                                      

In [30]: m.X = Var(m.A, m.B, domain=NonNegativeReals)                           

In [31]: # example constraint for "the whole matrix" like you have now          

In [32]: m.C1 = Constraint(expr=sum(m.X[a,b] for a in m.A for b in m.B)<=1)     

In [33]: m.pprint()                                                             
3 Set Declarations
    A : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :    3 : {1, 2, 3}
    B : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :    3 : {'a', 'b', 'c'}
    X_index : Size=1, Index=None, Ordered=True
        Key  : Dimen : Domain : Size : Members
        None :     2 :    A*B :    9 : {(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c')}

1 Var Declarations
    X : Size=9, Index=X_index
        Key      : Lower : Value : Upper : Fixed : Stale : Domain
        (1, 'a') :     0 :  None :  None : False :  True : NonNegativeReals
        (1, 'b') :     0 :  None :  None : False :  True : NonNegativeReals
        (1, 'c') :     0 :  None :  None : False :  True : NonNegativeReals
        (2, 'a') :     0 :  None :  None : False :  True : NonNegativeReals
        (2, 'b') :     0 :  None :  None : False :  True : NonNegativeReals
        (2, 'c') :     0 :  None :  None : False :  True : NonNegativeReals
        (3, 'a') :     0 :  None :  None : False :  True : NonNegativeReals
        (3, 'b') :     0 :  None :  None : False :  True : NonNegativeReals
        (3, 'c') :     0 :  None :  None : False :  True : NonNegativeReals

1 Constraint Declarations
    C1 : Size=1, Index=None, Active=True
        Key  : Lower : Body                                                                           : Upper : Active
        None :  -Inf : X[1,a] + X[1,b] + X[1,c] + X[2,a] + X[2,b] + X[2,c] + X[3,a] + X[3,b] + X[3,c] :   1.0 :   True

5 Declarations: A B X_index X C1

In [34]: # OK, now if we want to make the row summation "for each a in m.A"     

In [35]: # we want to use a function-rule combo is easiest...                   

In [36]: def sum_over_b(m, a): 
    ...:     return sum(m.X[a,b] for b in m.B) <= 1 
    ...:                                                                        

In [37]: m.C2 = Constraint(m.A, rule=sum_over_b)                                

In [38]: m.C2.pprint()                                                          
C2 : Size=3, Index=A, Active=True
    Key : Lower : Body                     : Upper : Active
      1 :  -Inf : X[1,a] + X[1,b] + X[1,c] :   1.0 :   True
      2 :  -Inf : X[2,a] + X[2,b] + X[2,c] :   1.0 :   True
      3 :  -Inf : X[3,a] + X[3,b] + X[3,c] :   1.0 :   True

In [39]: