Christian P
Christian P

Reputation: 83

How to check which are the indexes of a pyomo variable

After solving my pyomo model I iterate over the variables to do some stuff with the data. Now I am trying to make the code depending on the indexes of the variable which are pyomo sets. I am looking for a way to do something like the following:

model = ConcreteModel()
model.I = Set()
model.p = Var(model.I)

#objective, etc.
...
# solve model
...

for v in instance.component_objects(pyo.Var, active=True):
# Now the next line is what I try to achieve:
    used_sets = v.get_sets()
    if model.I in used_sets:
        # Do stuff

Is there any easy way to do that? Thanks for your help!

Upvotes: 1

Views: 2359

Answers (3)

Swatz
Swatz

Reputation: 1

I also needed something like that.
PS: The print for m.Z was missing with the second proposal. By combining the 2 proposals and with .subsets() we have that

def as_set_in_index(str):
    s = getattr(m, str)
    for v in m.component_objects(Var):
        idx_set = v.index_set()
        for subs in idx_set.subsets():
            my_index_name = subs.getname()
            if my_index_name == s.name:
                print(f'variable {v.getname()} is indexed by {s.name}')

as_set_in_index(str='I')

results:

variable X is indexed by I
variable Z is indexed by I

Upvotes: 0

brentertainer
brentertainer

Reputation: 2188

I needed to do something similar today. I got something working, but it depends on a "private" attribute which is, of course, not ideal.

from pyomo.environ import *

m = ConcreteModel()
m.I = Set(initialize=[1, 2, 3])
m.J = Set(initialize=list('abc'))
m.X = Var(m.I)
m.Y = Var(m.J)
m.Z = Var(m.J, m.I)

for v in m.component_objects(Var):
    if v.index_set()._implicit_subsets is None:
        index_set = v.index_set()
        index_set_name = index_set.name
        print('{} is indexed in {}'.format(v.name, index_set_name))
        print('{} indexed in I? {}'.format(v.name, index_set is m.I))
    else:
        index_sets = v.index_set()._implicit_subsets
        index_sets_names = [index_set.name for index_set in index_sets]
        print('{} is multi-indexed in {}'.format(v.name, ', '.join(index_sets_names)))
        print('{} indexed in I? {}'.format(v.name, m.I in index_sets))

Output:

X is indexed in I
X indexed in I? True
Y is indexed in J
Y indexed in I? False
Z is multi-indexed in J, I
Z indexed in I? True

Upvotes: 1

AirSquid
AirSquid

Reputation: 11913

Some variant of this below will likely work. You can ask the Var for the name of the index set. Note that 2-d indices are internally constructed as virtual sets. Not sure if there is a way to unwind that to native components or not. (see the m.display() results below.)

I will say that your construction seems odd. If you are making a concrete model, you already know the Variables...so testing them to see what their index is seems somewhat circular. Perhaps there is an easier alternative.

# accessing indexing sets...

from pyomo.environ import *
m = ConcreteModel()
m.I = Set(initialize=[1,2,3])
m.J = Set(initialize=list('abc'))
m.X = Var(m.I)
m.Y = Var(m.J)
m.Z = Var(m.J, m.I)
for v in m.component_objects(Var):
    my_index_name = v.index_set().getname()
    if my_index_name == 'I':
        print(f'variable {v.getname()} is indexed by I')


m.display()

Output:

variable X is indexed by I
Model unknown

  Variables:
    X : Size=3, Index=I
        Key : Lower : Value : Upper : Fixed : Stale : Domain
          1 :  None :  None :  None : False :  True :  Reals
          2 :  None :  None :  None : False :  True :  Reals
          3 :  None :  None :  None : False :  True :  Reals
    Y : Size=3, Index=J
        Key : Lower : Value : Upper : Fixed : Stale : Domain
          a :  None :  None :  None : False :  True :  Reals
          b :  None :  None :  None : False :  True :  Reals
          c :  None :  None :  None : False :  True :  Reals
    Z : Size=9, Index=Z_index
        Key      : Lower : Value : Upper : Fixed : Stale : Domain
        ('a', 1) :  None :  None :  None : False :  True :  Reals
        ('a', 2) :  None :  None :  None : False :  True :  Reals
        ('a', 3) :  None :  None :  None : False :  True :  Reals
        ('b', 1) :  None :  None :  None : False :  True :  Reals
        ('b', 2) :  None :  None :  None : False :  True :  Reals
        ('b', 3) :  None :  None :  None : False :  True :  Reals
        ('c', 1) :  None :  None :  None : False :  True :  Reals
        ('c', 2) :  None :  None :  None : False :  True :  Reals
        ('c', 3) :  None :  None :  None : False :  True :  Reals

  Objectives:
    None

  Constraints:
    None

Upvotes: 1

Related Questions