Search code examples
pythonpyomo

How, using Pyomo, can I create indexed VarList?


I understand that VarList is used to add variables on the fly in Pyomo. But I've never seen a VarList that allows adding variables "on-the-fly" with indices.

Below I've shown the actual and desired behavior:

import pyomo.environ as pe

### actual behavior
m = pe.ConcreteModel()
m.x = pe.VarList()
for i in range(2):
    for j in range(2):
        new_v = m.x.add()

print(list(m.x._index_set))
### desired behavior
m = pe.ConcreteModel()
m.x = pe.VarList()
for i in range(2):
    for j in range(2):
        new_v = m.x.add((i,j))

print(list(m.x._index_set))
### ideally this would print: [(0,0), (1,0), (0,1), (1,1)]

Such a feature would allow me to access the VarList in the future like so: m.x[i,j].

I've seen this question: Pyomo and VarList - generate variables automatically, but it doesn't use VarList in the answer, and therefore won't support adding variables on the fly.


Solution

  • The short answer is that you cannot create indexed VarList components. The reasons boil down to how Pyomo implements indexing sets: for an "indexed VarList," you really want a Set of independent Sets (which Pyomo supports) - but you would want to index the Var by the set of sets (which Pyomo currently does not support for a number of reasons).

    That said, you can get (almost exactly) the behavior you want by indexing a Var with a non-finite Set:

    >>> m = ConcreteModel()
    >>> m.x = Var(PositiveIntegers, PositiveIntegers, dense=False)
    >>> m = ConcreteModel()
    >>> m.x = Var(NonNegativeIntegers, NonNegativeIntegers, dense=False)
    >>> for i in range(2):
    ...     for j in range(2):
    ...         new_v = m.x[i,j] = 0
    ...
    >>> m.x.pprint()
    x : Size=4, Index=x_index
        Key    : Lower : Value : Upper : Fixed : Stale : Domain
        (0, 0) :  None :     0 :  None : False : False :  Reals
        (0, 1) :  None :     0 :  None : False : False :  Reals
        (1, 0) :  None :     0 :  None : False : False :  Reals
        (1, 1) :  None :     0 :  None : False : False :  Reals