在 Pyomo 中通过叉积添加变量

Adding variables by a cross-product in Pyomo

我正在尝试使用 Pyomo 创建一个 ConcreteModel。我有一个列表,其中包含变量 x_ij.

的索引
Xindex = [(619, 0), (620, 0), (621, 0), (622, 0), (623, 0), (624, 0), (625, 0), (626, 0), (627, 0), (628, 0), (619, 1), (620, 1), (621, 1), (622, 1), (623, 1), (624, 1), (625, 1), (626, 1), (627, 1), (628, 1), (1098, 2), (1099, 2), (1100, 2), (1101, 2), (1102, 2), (1103, 2), (1104, 2), (1105, 2), (1106, 2), (1107, 2), (1098, 3), (1099, 3), (1100, 3), (1101, 3), (1102, 3), (1103, 3), (1104, 3), (1105, 3), (1106, 3), (1107, 3), (619, 4), (620, 4), (621, 4), (622, 4), (623, 4), (624, 4), (625, 4), (626, 4), (627, 4), (628, 4), (1098, 5), (1099, 5), (1100, 5), (1101, 5), (1102, 5), (1103, 5), (1104, 5), (1105, 5), (1106, 5), (1107, 5), (1098, 6), (1099, 6), (1100, 6), (1101, 6), (1102, 6), (1103, 6), (1104, 6), (1105, 6), (1106, 6), (1107, 6), (1098, 7), (1099, 7), (1100, 7), (1101, 7), (1102, 7), (1103, 7), (1104, 7), (1105, 7), (1106, 7), (1107, 7), (1098, 8), (1099, 8), (1100, 8), (1101, 8), (1102, 8), (1103, 8), (1104, 8), (1105, 8), (1106, 8), (1107, 8), (1098, 9), (1099, 9), (1100, 9), (1101, 9), (1102, 9), (1103, 9), (1104, 9), (1105, 9), (1106, 9), (1107, 9), (1098, 10), (1099, 10), (1100, 10), (1101, 10), (1102, 10), (1103, 10), (1104, 10), (1105, 10), (1106, 10), (1107, 10), (1098, 11), (1099, 11), (1100, 11), (1101, 11), (1102, 11), (1103, 11), (1104, 11), (1105, 11), (1106, 11), (1107, 11), (1098, 12), (1099, 12), (1100, 12), (1101, 12), (1102, 12), (1103, 12), (1104, 12), (1105, 12), (1106, 12), (1107, 12)]

每个元组的第一个元素对应 i,第二个元素对应 j。使用此列表,我想将我的变量添加到模型 m。但是,我在 Pyomo User Manual 中没有看到直接的方法。我尝试了以下但没有用。

m.Xindexi = Set(initialize=[i[0] for i in Xindex])
m.Xindexj = Set(initialize=[j[1] for j in Xindex])
m.Xindex = Set(within = m.Xindexi*m.Xindexj)
m.x = Var(m.Xindexi, m.Xindexj,domain=NonNegativeReals)

有没有办法像创建字典一样(类似于 Gurobi Python 使用的方法)?例如:

m.x = {}
for i in Xindex:
    m.x[i[0],i[1]] = Var(domain=NonNegativeReals)

根据已接受的答案,这就是我为解决问题所做的工作。将其添加到此处以供将来参考...

m.Xindexi = Set(initialize=set([i[0] for i in Xindex]))
m.Xindexj = Set(initialize=set([j[1] for j in Xindex]))
m.Xindex = Set(within = m.Xindexi*m.Xindexj,
                  initialize=Xindex)
m.x = Var(m.Xindex,domain=NonNegativeReals)

有很多方法可以做到这一点。这里的基本思想是制作一组稀疏的 (i, j) 组合。您可以严格枚举该稀疏集,或者如果对于模型的其他部分,您需要更完整的 (i, j) 集,而您只需要 variables/parameters 中的一些稀疏集,您可以在- 从数据或您制定的任何设定规则中飞速发展。

这里有一些例子:

# pyomo set patterns
from pyomo.environ import *

m = ConcreteModel()

# initialize two sets from data
I_vals = {1, 5, 9}
m.I = Set(initialize=I_vals)
m.J = Set(initialize={2, 4, 88})  # either way works

# crossed set from list of known combinations
my_sparse_indices = {(1, 4), (1, 88), (5, 4)}
m.IJ = Set(within=m.I * m.J, initialize=my_sparse_indices)

# make a variable X, indexed by this sparse set
m.X = Var(m.IJ, domain=NonNegativeReals)

# make a parameter from the same sparse indices
limit_dict = {(1, 4): 10, (1, 88): 20, (5,4): 30}
m.lim = Param(m.IJ, initialize=limit_dict)

m.pprint()

#############

m2 = ConcreteModel()

m2.I = Set(initialize=range(4))
m2.J = Set(initialize=range(3))

# make full x-product
m2.IJ = Set(within=m2.I * m2.J, 
            initialize=[(i, j) for i in m2.I for j in m2.J])

# make a sparse set from selected values
selected_vals = [(2,1), (1,1)]
m2.IJ_selected = Set(within=m2.IJ, initialize=selected_vals)

# make a sparse set by excluding prohibited values
prohibited={(2,2), (3,1), (0,0)}
IJ_without_prohibited = {(i, j) for i in m2.I
                                for j in m2.J
                                if (i, j) not in prohibited}
m2.IJ_without_prohibited = Set(within=m2.IJ, initialize=IJ_without_prohibited)

m2.pprint()

这些的输出是:

4 Set Declarations
    I : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(1, 9)
        [1, 5, 9]
    IJ : Dim=0, Dimen=2, Size=3, Domain=IJ_domain, Ordered=False, Bounds=None
        [(1, 4), (1, 88), (5, 4)]
    IJ_domain : Dim=0, Dimen=2, Size=9, Domain=None, Ordered=False, Bounds=None
        Virtual
    J : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(2, 88)
        [2, 4, 88]

1 Param Declarations
    lim : Size=3, Index=IJ, Domain=Any, Default=None, Mutable=False
        Key     : Value
         (1, 4) :    10
        (1, 88) :    20
         (5, 4) :    30

1 Var Declarations
    X : Size=3, Index=IJ
        Key     : Lower : Value : Upper : Fixed : Stale : Domain
         (1, 4) :     0 :  None :  None : False :  True : NonNegativeReals
        (1, 88) :     0 :  None :  None : False :  True : NonNegativeReals
         (5, 4) :     0 :  None :  None : False :  True : NonNegativeReals

6 Declarations: I J IJ_domain IJ X lim

第二个模型:

6 Set Declarations
    I : Dim=0, Dimen=1, Size=4, Domain=None, Ordered=False, Bounds=(0, 3)
        [0, 1, 2, 3]
    IJ : Dim=0, Dimen=2, Size=12, Domain=IJ_domain, Ordered=False, Bounds=None
        [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2)]
    IJ_domain : Dim=0, Dimen=2, Size=12, Domain=None, Ordered=False, Bounds=None
        Virtual
    IJ_selected : Dim=0, Dimen=2, Size=2, Domain=IJ, Ordered=False, Bounds=None
        [(1, 1), (2, 1)]
    IJ_without_prohibited : Dim=0, Dimen=2, Size=9, Domain=IJ, Ordered=False, Bounds=None
        [(0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (3, 0), (3, 2)]
    J : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(0, 2)
        [0, 1, 2]

6 Declarations: I J IJ_domain IJ IJ_selected IJ_without_prohibited
[Finished in 2.6s]