Reputation: 83
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
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
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
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()
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