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]:
在 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]: