3

I'm using a toolbox that internally calls Pyomo to solve an optimization problem. I am interested in accessing the Pyomo model it constructs so I can modify the constraints/objective. So my question is, suppose I get the following output:

Problem:

Name: unknown Lower bound: 6250.0 Upper bound: 6250.0 Number of objectives: 1 Number of constraints: 11 Number of variables: 8 Number of nonzeros: 17 Sense: minimize

Solver:

Status: ok Termination condition: optimal Statistics: Branch and bound: Number of bounded subproblems: 0 Number of created subproblems: 0 Error rc: 0 Time: 0.015599727630615234

Solution:

number of solutions: 0 number of solutions displayed: 0

So the problem works well and I get a solution, the modeling was done internally via another too. Is it possible to access the constraints/objective so I can freely modify the optimization model in Pyomo syntax?

I tried to call the model and got something like this: <pyomo.core.base.PyomoModel.ConcreteModel at xxxxxxx>

ndmeiri
  • 4,979
  • 12
  • 37
  • 45
  • Include a code sample showing what you've tried so far and the full error message it generates. – Daz Jul 17 '18 at 13:35
  • I do not have an error message. I am trying to figure out how to access the model information and modify its constraints. Right now all I know is it is called 'network.model' and it is concrete. I did not construct the model, but I want to access it fully. – Khaled Alshehri Jul 17 '18 at 13:44

1 Answers1

4

It sounds like network.model is the Pyomo model and yes, if you have access to it, you can modify it. Try printing the model or individual model components using the pprint() method:

network.model.pprint()
network.model.con1.pprint()

or you can loop over specific types of components in the model:

for c in network.model.component_objects(Constraint):
    print(c)  # Prints the name of every constraint on the model

The easiest way to modify the objective would be to find the existing one, deactivate it, and add a new one

network.model.obj.deactivate()
network.model.new_obj = Objective(expr=network.model.x**2)

There are ways to modify constraints/objectives in place but they are not well-documented. I'd recommend using Python's dir() function and playing around with some of the component attributes and methods to get a feel for how they work.

dir(network.model.obj)
Bethany Nicholson
  • 2,723
  • 1
  • 11
  • 18
  • Thanks! That's very helpful. I am able to re-define simple constraints/objective. Now, I ran 'network.model.con1.pprint()' to see the constraint 'con1' and got the following: con1: Size=2, Index=c1, Active=True Key: Lower: Body: Upper : Active ('gen 0', 'now') : 0.0 : 100.0*gen_status[gen 0,now] - gen_p[gen 0,now] : +Inf : True ('gen 1', 'now') : 0.0 : 50*gen_status[gen 1,now] - gen_p[gen 1,now] : +Inf : True This is an indexed constraint. How can alter the first element? Let's say I only want to replace 100 with 25, without messing up with everything else? – Khaled Alshehri Jul 17 '18 at 14:28
  • Access a single index of an indexed components using square brackets `network.model.con1['gen 0','now']. The easiest way to change the value would be to modify the original Constraint rule to use a mutable Param in place of the numeric constant 100.0. Then you could change the value without directly modifying the constraint. – Bethany Nicholson Jul 17 '18 at 15:21
  • Thanks, Bethany. I cannot modify the original constraint because it came out of some other tool and unfortunately they did not use Param. I guess I'll build everything myself and use Pyomo directly. I love it so far! Big thanks to dev team. – Khaled Alshehri Jul 18 '18 at 14:05