What is "Pyomothonic" way to access variable values and objective function value?

3,035 views
Skip to first unread message

Mark

unread,
Jan 18, 2017, 9:41:30 PM1/18/17
to Pyomo Forum
Recently successfully ported pretty big, but old, Pyomo model to Pyomo 5.x compliant. It's awesome to see all the new developments. In doing so, realized I wasn't sure about suggested best way to access variable values and obj function value in a Python script. Found a few different approaches scattered across the Pyomo 4.x official docs and various GitHub repos of example Pyomo models and scripts. For example, in the sample production model there's an indexed variable X with index of ('bands', 'coils'). Which of the following is the suggested approach to accessing the variables value after solving? My created model instance is called, of course, instance.

instance.X['coils'].value
value(instance.X['coils'])
instance.X['coils']()

All three work and I found uses of all three approaches in various Pyomo example galleries and docs floating around. Is one of them the "right" way?

Similarly, for getting all variable values, current docs suggest approach like this:

for v in instance.component_objects(Var, active=True):
    varobject = getattr(instance, str(v))
    for index in varobject:
        print ("   ", index, varobject[index].value)

However, the following also works and made me wonder about the need for the indirect way of getting the value of a variable using getattr. Both v and varobject have
type class 'pyomo.core.base.var.IndexedVar'. Am I missing something?

for v in instance.component_objects(Var, active=True):
    print ("Variable component object",v)
    for index in v:
        print ("   ", index, v[index].value)

I found similar variants with accessing objective function value and couldn't find suggested approach in current docs. Rather than detail all the variants here, I'll just ask if there's a suggested approach. I actually wrote this exploration up in a little Jupyter notebook and blogged it at http://hselab.org/pyomo-get-variable-values.html. Once I know the suggested Pyomothonic way of accessing variable and obj func values, I can update the blog post in hopes of it being helpful to me and others.

Gabriel Hackebeil

unread,
Jan 19, 2017, 12:09:05 PM1/19/17
to pyomo...@googlegroups.com
instance.X['coils'].value
value(instance.X['coils'])
instance.X['coils']()

All three work and I found uses of all three approaches in various Pyomo example galleries and docs floating around. Is one of them the "right" way?

Using the .value attribute is specific to variable objects. If you are dealing with Pyomo expressions (or components that are used to generate expressions, such a Var), using the value function or the __call__ method will also work. We recommend using the value function in places where you are unsure of the component type. The reason is that in the case where you are using an indexed Param that is not mutable, when you access a particular index of that Param you are returned a simple numeric type, which will not have a __call__ method. The value function will check this and do the correct thing.

for v in instance.component_objects(Var, active=True):
    varobject = getattr(instance, str(v))
    for index in varobject:
        print ("   ", index, varobject[index].value)

The docs must be out of date. When you cast the variable object v to a string, it simply generates the variables name, which can be used to find the same variable object using the getattr call. You can simply delete that line and use v instead of varobject.

Gabe

--
You received this message because you are subscribed to the Google Groups "Pyomo Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyomo-forum...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mark

unread,
Jan 19, 2017, 12:16:56 PM1/19/17
to Pyomo Forum
Thanks Gabe. So, I'm assuming for objective function value, best approach is:

value(instance.Total_Profit)

If so, thanks, and mark as complete.

Gabriel Hackebeil

unread,
Jan 19, 2017, 12:18:56 PM1/19/17
to pyomo...@googlegroups.com
Correct. The __call__ method would also work (and would have less overhead), but value would always work as well.

Gabe

Reply all
Reply to author
Forward
0 new messages