How to programmatically add an objective to an instance ?

22 views
Skip to first unread message

dschroetter

unread,
Sep 28, 2010, 3:27:51 PM9/28/10
to coopr forum
Folks,


would someone have a recipe on how to add the (only) objective to an
instance ? I tried to emulate the mechanisms described and shown in
the benders example for constraints, but so far I am at a loss.

Thanks,

/Dirk

Watson, Jean-paul

unread,
Sep 28, 2010, 4:41:22 PM9/28/10
to dschroetter, coopr forum
Hi Dirk,

Here’s an example of what I do in PySP to create an objective on-the-fly, with some culling to keep the snippet size manageable:

            opt_expression = node_expected_cost_variable

            if generate_weighted_cvar is True:
               cvar_cost_variable_name = "CVAR_COST_" + tree_node._name
               cvar_cost_variable = getattr(binding_instance, cvar_cost_variable_name)
               if cvar_weight == 0.0:
                  # if the cvar weight is 0, then we're only doing cvar - no mean.                                                                                                            
                  opt_expression = cvar_cost_variable
               else:
                  opt_expression += cvar_weight * cvar_cost_variable

            new_objective = Objective(name="MASTER", sense=opt_sense)
            new_objective._data[None].expr = opt_expression
            setattr(binding_instance, "MASTER", new_objective)

For now, let’s assume you are only worried about a single-objective problem – in which case the “None” index in the expression set (second-to-last line) refers to the one-and-only expression.

This should do it – at least it works in the examples I have deployed.

I will readily admit, after reading the code snippet, that the line “new_objective._data[None].expr = opt_expression” is one ugly and non-intuitive syntax. I just put in a reminder to myself to mirror the functionality of “add(index, expression)” that we have in the Constraint class.

I hope this helps – if things still don’t work, let me/us know.

jpw

Bill Hart

unread,
Sep 30, 2010, 8:27:01 AM9/30/10
to coopr forum
I'm less sure of what you mean than JP was. ;)

Do you mean you want to add an objective after a model instance has
been constructed?

Bill Hart

unread,
Sep 30, 2010, 8:35:31 AM9/30/10
to coopr forum
JP:

Most of your example is constructing an expression. The rest is
ugliness that I think we can work around! We want the following to
work:

expr = 3.0 * instance.x + 4.0 * instance.y
model.MASTER = Objective(expr=expr)

Right? I think we can do this by telling model instances that they
are concrete! That's a simple change.

I can't log in right now, but I'll try this out shortly...

--Bill


On Sep 28, 2:41 pm, "Watson, Jean-paul" <jwat...@sandia.gov> wrote:
> Hi Dirk,
>
> Here's an example of what I do in PySP to create an objective on-the-fly, with some culling to keep the snippet size manageable:
>
>             opt_expression = node_expected_cost_variable
>
>             if generate_weighted_cvar is True:
>                cvar_cost_variable_name = "CVAR_COST_" + tree_node._name
>                cvar_cost_variable = getattr(binding_instance, cvar_cost_variable_name)
>                if cvar_weight == 0.0:
>                   # if the cvar weight is 0, then we're only doing cvar - no mean.
>                   opt_expression = cvar_cost_variable
>                else:
>                   opt_expression += cvar_weight * cvar_cost_variable
>
>             new_objective = Objective(name="MASTER", sense=opt_sense)
>             new_objective._data[None].expr = opt_expression
>             setattr(binding_instance, "MASTER", new_objective)
>
> For now, let's assume you are only worried about a single-objective problem - in which case the "None" index in the expression set (second-to-last line) refers to the one-and-only expression.
>
> This should do it - at least it works in the examples I have deployed.
>
> I will readily admit, after reading the code snippet, that the line "new_objective._data[None].expr = opt_expression" is one ugly and non-intuitive syntax. I just put in a reminder to myself to mirror the functionality of "add(index, expression)" that we have in the Constraint class.
>
> I hope this helps - if things still don't work, let me/us know.
>
> jpw

Watson, Jean-paul

unread,
Sep 30, 2010, 12:29:43 PM9/30/10
to coopr...@googlegroups.com
Bill brings up a good point – do you mean modifying an objective (which I was perhaps incorrectly assuming, probably because I do this all the time) or constructing one from scratch? If we haven’t covered the bases between our two examples, let us know...

jpw

Dirk Schroetter

unread,
Oct 3, 2010, 1:56:15 PM10/3/10
to coopr...@googlegroups.com
Hi Jean-PAul,

thanks fro your response, you interpreted my question correctly. I tried your recipe, but a pyomo --debug=normal never showed a "generating Constraint" output in the log.

I worked around that by refactoring the program itself and being able to use Objective statements that work on the model instead of the instance.

Which brought me the next puzzler, that an expression of the form:

def cost_rule(model):
    return sum([model.Ifs[j] for j in model.nodeset])

model.TotalCost = Objective(rule=cost_rule,sense=minimize)

is interpreted as a constant objective .. even though model.Ifs is a variable that is being pulled up to "1" through contraints.

Thanks for your help 

/Dirk

Watson, Jean-paul

unread,
Oct 4, 2010, 11:16:09 PM10/4/10
to coopr...@googlegroups.com
Hi Dirk,

Any chance you can send us your (even culled) model and data file? This would help speed resolution significantly, and will undoubtedly be less frustrating on your end :)

jpw
Reply all
Reply to author
Forward
0 new messages