Пьомо: Как мне добавить весь набор ограничений модели к другой модели?

Я хочу добавить все ограничения и переменные из модели в другую модель в Pyomo, но не могу понять, как это сделать. Вариант использования - это когда я хочу преобразовать свою модель в двойственную, и мне нужно добавить все двойные ограничения и переменные к основной задаче. Это действительно полезно, когда мы хотим добавить условия оптимальности одной модели к другой проблеме.

Возможно, в Pyomo есть другие функциональные преобразования, которые делают то же самое, и я не знаю о них, поэтому в случае, если такая функциональность существует, я был бы более чем счастлив, если бы кто-нибудь мог помочь.

Спасибо,


person AliRa    schedule 20.01.2021    source источник
comment
Вы действительно хотите добавить ограничения и объекты переменных или хотите добавить их вычисленные значения в ограничения другой модели?   -  person cookesd    schedule 23.01.2021
comment
Я хочу, чтобы к другой проблеме добавлялись фактические ограничения и переменные, а не их значение.   -  person AliRa    schedule 23.01.2021


Ответы (2)


Если вы хотите скопировать ограничения и переменные в совершенно новую модель, вы можете использовать clone метод модели, а затем удалить все ненужные объекты модели (целевые функции, параметры и т. Д.)

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
person cookesd    schedule 23.01.2021
comment
Спасибо, я думаю, вы забыли главную проблему, которая у меня есть! Я хотел бы добавить ограничения и переменные проблемы в другую четко определенную модель (с ее собственными ограничениями и переменными), а не клонировать свою первую модель и не переименовывать ее. Но я думаю, что взял то, что хотел, я мог перебрать все переменные или ограничения исходной проблемы и использовать add_component, чтобы добавить их в другую модель, верно? - person AliRa; 23.01.2021
comment
Я не был уверен, хотите ли вы добавить его к уже определенной модели. Add_component, похоже, работал с ограничениями, но я не мог заставить его работать с переменными, поскольку они привязаны к первой модели. Если у вас получится получить эту работу, было бы неплохо увидеть - person cookesd; 24.01.2021
comment
Вы правы, я пока не мог ничего добавить с помощью add_component, сначала я подумал, что он может обрабатывать новые переменные самостоятельно, но затем он продолжал запрашивать значение, поскольку для этой функции требуется две записи. Мне это нужно, чтобы каким-то образом сделать двойную проблему из основной проблемы, а затем добавить ограничения каждой из этих моделей в другую модель (условия оптимальности) - person AliRa; 24.01.2021

Я добавил ограничения модели model2 к другой модели model1, сначала удалив элемент из исходной модели, а затем добавив его в другую.

Вот пример кода, чтобы показать это:

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())
person AliRa    schedule 24.01.2021