Search code examples
pythonvariablessetpyomo

pyomo: get all variables with different sets


I'm working on a quiet big optimization problem containing different parameters and variables. These parameters and variables deal with different sets, e.g.:

mdl.A = Var(mdl.t, mdl.X, domain=NonNegativeReals)
mdl.B = var(mdl.X, domain=NonNegativeReals)
mdl.C = Var(mdl.t, mdl.X, mdl.Y, domain=NonNegativeReals)

After sovling the model, I try to get all data from every parameter and variable. But right now, I am struggeling with some code, which should deal with it. Right now, I get all names of every parameter and variable by

model_vars = mdl.component_map(ctype=pyo.Var)

and can itterate through model_vars like

for k in model_vars.keys():
v = model_vars[k]

Now, I have to decide which set is dealing with the parameter or model. I already tried v.index_set().name, with which I got in some cases the set of the parameter. However, not in every case, then the output is like "variablename_index"

Did someone know a smart way, how I can imagine the set of the variable while iterating through all parameters and variables of my model?

Thanks a lot in advance! Mathias


Solution

  • I think you'll have better luck with component_objects(). I'm not sure what the return object from component_map() is or how to work with it. The doc says it is a PseudoMap.

    The below is shown in ipython, which I like using for experiments because you can get the auto-complete to suggest things and view the dox, etc.

    Note that when you construct things that are multi-indexed, like m.y, pyomo creates a synthetic index that rolls them up. I do not know how to unwind that back to the basic elements, if you need to do that... Which seems a bit odd. But it probably isn't necessary as you can just as easily interact with the synthetic index (my term.)

    In [36]: from pyomo.environ import *
    
    In [37]: m = ConcreteModel()
    
    In [38]: m.A = Set(initialize=[1,2,3])
    
    In [39]: m.B = Set(initialize=['A', 'B', 'C'])
    
    In [40]: m.x = Var(m.A, initialize=2.0)
    
    In [41]: m.y = Var(m.A, m.B, initialize=3.0)
    
    In [42]: for mv in m.component_objects(ctype=Var):
        ...:     print(mv, mv.index_set().name)
        ...:     for idx in mv.index_set():
        ...:         print(f'   {mv.name} {idx}: {value(mv[idx])}')
        ...: 
    x A
       x 1: 2.0
       x 2: 2.0
       x 3: 2.0
    y y_index
       y (1, 'A'): 3.0
       y (1, 'B'): 3.0
       y (1, 'C'): 3.0
       y (2, 'A'): 3.0
       y (2, 'B'): 3.0
       y (2, 'C'): 3.0
       y (3, 'A'): 3.0
       y (3, 'B'): 3.0
       y (3, 'C'): 3.0
    
    In [43]: m.y.index_set().dimen
    Out[43]: 2