0

I want to add all constraints and variables from a model to a different model in Pyomo, but I cannot figure out how. The use case is when I want to transform my model to its dual, and I need to add all dual constraints and variables to the primal problem. This is actually useful when we want to add optimality conditions of a certain model to another problem.

Maybe there are other functional transformations in Pyomo that do the same, and I am not aware of them, so in a case such functionality exists, I would be more than happy if anybody could assist.

Thanks,

AliRa
  • 51
  • 6
  • Do you actually want to add the constraint and variable objects or do you want to add their computed values into the constraints of another model? – cookesd Jan 22 '21 at 23:39
  • I want the actual constraints and variables to be added to the other problem, not their value. – AliRa Jan 23 '21 at 01:55

2 Answers2

0

If you want to copy the constraints and variables to a brand new model, you can use the clone method of the model then remove any un-required model objects (objective functions, parameters, etc.)

import pyomo.environ as pyo

#%% Build initial model
my_set = [1,2,3]
m1 = pyo.ConcreteModel()
m1.x = pyo.Var(my_set,within=pyo.NonNegativeReals)
m1.y = pyo.Var(within=pyo.Binary)
m1.con1 = pyo.Constraint(expr = sum([m1.x[i] for i in my_set]) <= 3)
m1.obj = pyo.Objective(expr = m1.y + sum([m1.x[i] for i in my_set]),
                       sense=-1)

#%% Solve initial model
solver = pyo.SolverFactory('glpk')
res1 = solver.solve(m1)

#%% Clone initial model
m2 = m1.clone()

#%% Verify objects copied to other model
m1.pprint()

# 1 Set Declarations
#     x_index : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(1, 3)
#         [1, 2, 3]

# 2 Var Declarations
#     x : Size=3, Index=x_index
#         Key : Lower : Value : Upper : Fixed : Stale : Domain
#           1 :     0 :   3.0 :  None : False : False : NonNegativeReals
#           2 :     0 :   0.0 :  None : False : False : NonNegativeReals
#           3 :     0 :   0.0 :  None : False : False : NonNegativeReals
#     y : Size=1, Index=None
#         Key  : Lower : Value : Upper : Fixed : Stale : Domain
#         None :     0 :   1.0 :     1 : False : False : Binary

# 1 Objective Declarations
#     obj : Size=1, Index=None, Active=True
#         Key  : Active : Sense    : Expression
#         None :   True : maximize : x[1] + x[2] + x[3] + y

# 1 Constraint Declarations
#     con1 : Size=1, Index=None, Active=True
#         Key  : Lower : Body               : Upper : Active
#         None :  -Inf : x[1] + x[2] + x[3] :   3.0 :   True

# 5 Declarations: x_index x y con1 obj

m2.pprint()
# 1 Set Declarations
#     x_index : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(1, 3)
#         [1, 2, 3]

# 2 Var Declarations
#     x : Size=3, Index=x_index
#         Key : Lower : Value : Upper : Fixed : Stale : Domain
#           1 :     0 :   3.0 :  None : False : False : NonNegativeReals
#           2 :     0 :   0.0 :  None : False : False : NonNegativeReals
#           3 :     0 :   0.0 :  None : False : False : NonNegativeReals
#     y : Size=1, Index=None
#         Key  : Lower : Value : Upper : Fixed : Stale : Domain
#         None :     0 :   1.0 :     1 : False : False : Binary

# 1 Objective Declarations
#     obj : Size=1, Index=None, Active=True
#         Key  : Active : Sense    : Expression
#         None :   True : maximize : x[1] + x[2] + x[3] + y

# 1 Constraint Declarations
#     con1 : Size=1, Index=None, Active=True
#         Key  : Lower : Body               : Upper : Active
#         None :  -Inf : x[1] + x[2] + x[3] :   3.0 :   True

# 5 Declarations: x_index x y con1 obj

#%% Remove objective if desired
for obj in m2.component_objects(pyo.Objective):
    m2.del_component(obj)

#%% See that objective is removed
m2.pprint()

# 1 Set Declarations
#     x_index : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(1, 3)
#         [1, 2, 3]

# 2 Var Declarations
#     x : Size=3, Index=x_index
#         Key : Lower : Value : Upper : Fixed : Stale : Domain
#           1 :     0 :   3.0 :  None : False : False : NonNegativeReals
#           2 :     0 :   0.0 :  None : False : False : NonNegativeReals
#           3 :     0 :   0.0 :  None : False : False : NonNegativeReals
#     y : Size=1, Index=None
#         Key  : Lower : Value : Upper : Fixed : Stale : Domain
#         None :     0 :   1.0 :     1 : False : False : Binary

# 1 Constraint Declarations
#     con1 : Size=1, Index=None, Active=True
#         Key  : Lower : Body               : Upper : Active
#         None :  -Inf : x[1] + x[2] + x[3] :   3.0 :   True

# 4 Declarations: x_index x y con1
cookesd
  • 1,296
  • 1
  • 5
  • 6
  • Thanks, I think you forgot the main issue I have! I would like to add the constraints and variables of a problem to another well-defined model (with its own constraints and variables), not cloning my first model and renaming it. But I think I took what I wanted, I could iterate over all Vars or Constraints of the initial problem and use add_component to add them to the another model, is that right? – AliRa Jan 23 '21 at 19:15
  • I wasn't sure if you wanted to add it to an already defined model. The add_component seemed to work for the constraints but I couldn't quite get it to work for the variables since they're tied to the first model. If you're able to get that working that would be good to see – cookesd Jan 23 '21 at 22:00
  • You're right, I couldn't add anything using add_component yet, I first thought it might handle new variables by itself but then it kept asking for a value as this function requires two entries. I needed this to somehow make the dual problem from a primal problem and then add the constraints of each of these models to another model (optimality conditions) – AliRa Jan 23 '21 at 22:32
0

I added the constraints of a model "model2" to another model "model1" with first deleting the item from the initial model and then adding it to the other.

Here is a sample code to show that:

from pyomo.environ import *

model1 = ConcreteModel()
model2 = ConcreteModel()

model1.a = Var([1,2,3,4,5,6], within=NonNegativeReals)
model2.b = Var([1,2,3,4,5,6], within=NonNegativeReals)

model1.c = Constraint(expr= model1.a[1] + model1.a[3] == 3)
model2.d = Constraint(expr= model2.b[1] + model2.b[3] == 3)

  
for con in model2.component_objects(Constraint):
    model2.del_component(con)
    model1.add_component('d', con)

for var in model2.component_objects(Var):
    model2.del_component(var)
    model1.add_component('b', var)

model1.objective = Objective(expr = model1.a[1] + model1.b[3], sense=minimize)

solver = SolverFactory('glpk')
res = solver.solve(model1)

print(model1.display())
AliRa
  • 51
  • 6