我传统上使用GAMS,并且依靠其内部数据存储机制来减小模型内存的大小。我们GAMS生成的模型通常在10Gb范围内。
我是Pyomo的新手,我想知道在许多大型域/索引中声明多维参数/变量的最佳方法,但是这种方法可能非常稀疏。
例如,假设集合i和j表示节点并且非常大,并且在这些集合上声明了参数和变量。还要想象一下,我们有一个子集告诉我们哪些组合是令人感兴趣的,并代表连接这些节点的弧,并且该子集是稀疏的。在GAMS中,我们将编写如下内容:
parameter flowCost(i,j); # parameter is declared across the full sets
flowCost(i,j)$arc(i,j) = 10; # but only populated for arcs of interest
类似地,对于变量,在方程式中,我们将具有以下内容:
variable flowVar(i,j); # declared across full set
flowVar(i,j)$arc(i,j) =L= 100; # the variable only every appears for arcs of interest.
所以我想知道的是,这是否是我们应该由Pyomo来处理的内存管理问题,还是我们需要自己明确地处理。考虑到我们期望填充的模型非常大,这一点很重要。
也许提出这个问题的另一种方式是,如果我们在整个索引集中声明参数/变量,则与我们是否手动强制参数/变量仅对感兴趣的圆弧存在相比,内存使用量会很大。
我在下面有一个示例模型
model3 = ConcreteModel()
# Create the nodes
model3.node = Set(dimen=1, initialize=['a', 'b', 'c', 'd'])
# Set up the arcs we want in the model
myList = []
myList.append(('a','b'))
myList.append(('a','c'))
myList.append(('a','d'))
myList.append(('b','a'))
model3.arc = Set(dimen=2, within=model3.node*model3.node, initialize=myList)
def calcFlowCost(model, node_i, node_j):
if (node_i, node_j) in model.arc:
return 10.0
model3.flowCost = Param(model3.node, model3.node, initialize=calcFlowCost)
如果我在整个节点集合中声明参数,则会得到以下信息
1 Param Declarations
flowCost : Size=16, Index=flowCost_index, Domain=Any, Default=None, Mutable=False
Key : Value
('a', 'a') : None
('a', 'b') : 10.0
('a', 'c') : 10.0
('a', 'd') : 10.0
('b', 'a') : 10.0
('b', 'b') : None
('b', 'c') : None
('b', 'd') : None
('c', 'a') : None
('c', 'b') : None
('c', 'c') : None
('c', 'd') : None
('d', 'a') : None
('d', 'b') : None
('d', 'c') : None
('d', 'd') : None
令我担心的是,这可能会耗尽内存,因为我可以看到不存在的弧的条目,但是这又可能只是该参数的解释/报告内容,实际上内存没有用完。因此,我的问题。
我确实只是尝试在弧之间声明了它,并且报告了一个减少得多的参数(没有任何“ None”条目),所以我怀疑它使用的内存更少:
model3.flowCost2 = Param(model3.arc, initialize=10.0)
返回
flowCost2 : Size=4, Index=arc, Domain=Any, Default=None, Mutable=False
Key : Value
('a', 'b') : 10.0
('a', 'c') : 10.0
('a', 'd') : 10.0
('b', 'a') : 10.0
但是我想确认。
您可以向我指出的其他任何内存管理建议或资源也将有所帮助。
预先感谢