Я программирую на python 3.6 с использованием pyomo 5.3
Я хочу изменить тело неиндексированного ограничения (в случае, если оно не в требуемом стандартном формате).Проблема в том, что значение ограничения в конкретной точке вычисляется при вычитании из тела.Тем не менее, мне требуется тело в форме функции, потому что я должен построить Objective, который является максимумом всех нелинейных ограничений, приводящих к проблеме min-max.
Я попытался установитьТело ограничения передано функции, но я получаю вывод, что атрибут не может быть установлен.Есть ли функция для установки тела ограничения?
Редактировать: Вот решение, которое я нашел:
constraint._body = ...
Я хочу использоватьэто позволяет изменить форму задачи оптимизации.
(извините за неанглийские комментарии)
Вот функции, используемые в этом примере:
- Первый ослабляет домены всех переменных до действительных значений.
- Второй создает новую модель с использованием метода эпиграфа.(Здесь я использую
._body
для изменения ограничений.
def cont_relax_model_same_bounds(model_vars):
for var in model_vars:
if str(var.domain) in int_type:
var.domain = Reals
def epgraph_reformulation_without_bounds(model):
#Erstelle Epigraph-Modell
epi_model = model.clone()
epi_model.alpha_epi = Var(within = Reals)
#Speichere alle nichtlinearen Restriktionen des usprünglichen Modells in einer Liste
nonlinear_constrs = []
for constr in model.component_objects(Constraint):
if not (constr.body.polynomial_degree() in [0, 1]):
nonlinear_constrs.append(constr)
#Speichere alle nichtlinearen Restriktionen des umformulierten Modells in einer Liste
epi_nonlinear_constrs = []
for constr in epi_model.component_objects(Constraint):
if not (constr.body.polynomial_degree() in [0, 1]):
epi_nonlinear_constrs.append(constr)
#Kontrollausgabe, ob die Restriktionen richtig in der Liste gespeichert werden
for k, constr in enumerate(epi_nonlinear_constrs):
print(epi_nonlinear_constrs[k].body)
#Formuliere die nichtlinearen Restriktionen neu
for k, constr in enumerate(nonlinear_constrs):
epi_nonlinear_constrs[k]._body = (nonlinear_constrs[k].body - epi_model.alpha_epi)
epi_model.obj = Objective(expr = epi_model.alpha_epi, sense = minimize)
return epi_model
Вот исходная модель:
model_ESH = ConcreteModel(name = "Example 1")
model_ESH.x1 = Var(bounds=(1,20), domain=Reals)
model_ESH.x2 = Var(bounds=(1,20), domain=Integers)
model_ESH.obj = Objective(expr=(-1)*model_ESH.x1-model_ESH.x2)
model_ESH.g1 = Constraint(expr=0.15*((model_ESH.x1 - 8)**2)+0.1*((model_ESH.x2 - 6)**2)+0.025*exp(model_ESH.x1)*((model_ESH.x2)**(-2))-5<=0)
model_ESH.g2 = Constraint(expr=(model_ESH.x1)**(-1) + (model_ESH.x2)**(-1) - ((model_ESH.x1)**(0.5)) * ((model_ESH.x2) ** (0.5))+4<=0)
model_ESH.l1 = Constraint(expr=2 * (model_ESH.x1) - 3 * (model_ESH.x2) -2<=0)
model_ESH.pprint()
Затем я клонирую модель и ослабляю целочисленные переменные
NLP_model = model_ESH.clone()
#Relaxiere das Problem und deaktiviere die nichtlinearen Restriktionen
#Das funktioniert schonmal
cont_relax_model_same_bounds(get_model_vars(NLP_model))
NLP_model.pprint()
2 Var Declarations
x1 : Size=1, Index=None
Key : Lower : Value : Upper : Fixed : Stale : Domain
None : 1 : None : 20 : False : True : Reals
x2 : Size=1, Index=None
Key : Lower : Value : Upper : Fixed : Stale : Domain
None : 1 : None : 20 : False : True : Reals
1 Objective Declarations
obj : Size=1, Index=None, Active=True
Key : Active : Sense : Expression
None : True : minimize : - x1 - x2
3 Constraint Declarations
g1 : Size=1, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : -Inf : -5 + 0.15*( -8 + x1 )**2.0 + 0.1*( -6 + x2 )**2.0 + 0.025 * exp( x1 ) * x2**-2.0 : 0.0 : True
g2 : Size=1, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : -Inf : 4 + x1**-1.0 + x2**-1.0 - x1**0.5 * x2**0.5 : 0.0 : True
l1 : Size=1, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : -Inf : -2 + 2*x1 - 3*x2 : 0.0 : True
6 Declarations: x1 x2 obj g1 g2 l1
Теперь я использую свою функцию для изменения / модификации модели:
epi_model_ESH = epgraph_reformulation_without_bounds(NLP_model)
epi_model_ESH.pprint()
WARNING: Implicitly replacing the Component attribute obj (type=<class
'pyomo.core.base.objective.SimpleObjective'>) on block Example 1 with a
new Component (type=<class 'pyomo.core.base.objective.SimpleObjective'>).
This is usually indicative of a modelling error. To avoid this warning,
use block.del_component() and block.add_component().
3 Var Declarations
alpha_epi : Size=1, Index=None
Key : Lower : Value : Upper : Fixed : Stale : Domain
None : None : None : None : False : True : Reals
x1 : Size=1, Index=None
Key : Lower : Value : Upper : Fixed : Stale : Domain
None : 1 : 8.636750397018059 : 20 : False : False : Reals
x2 : Size=1, Index=None
Key : Lower : Value : Upper : Fixed : Stale : Domain
None : 1 : 12.335071455814422 : 20 : False : False : Reals
1 Objective Declarations
obj : Size=1, Index=None, Active=True
Key : Active : Sense : Expression
None : True : minimize : alpha_epi
3 Constraint Declarations
g1 : Size=1, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : -Inf : -5 + 0.15*( -8 + x1 )**2.0 + 0.1*( -6 + x2 )**2.0 + 0.025 * exp( x1 ) * x2**-2.0 - alpha_epi : 0.0 : True
g2 : Size=1, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : -Inf : 4 + x1**-1.0 + x2**-1.0 - x1**0.5 * x2**0.5 - alpha_epi : 0.0 : True
l1 : Size=1, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : -Inf : -2 + 2*x1 - 3*x2 : 0.0 : True
7 Declarations: x1 x2 g1 g2 l1 alpha_epi obj
Однако, если я пытаюсь использовать IPOPT для решения вновь созданной модели, я получаю следующую ошибку:
opt = SolverFactory('ipopt')
#opt.options['bonmin.algorithm'] = 'Bonmin'
print('using IPOPT')
# Set Options for solver.
#opt.options['bonmin.solution_limit'] = '1'
#opt.options['bonmin.time_limit'] = 1800
results = opt.solve(epi_model_ESH, tee = True)
results.write()
using IPOPT
ERROR: Variable 'x1' is not part of the model being written out, but appears
in an expression used on this model.
ERROR: Variable 'x2' is not part of the model being written out, but appears
in an expression used on this model.
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-22-dcc4023897c3> in <module>
5 #opt.options['bonmin.solution_limit'] = '1'
6 #opt.options['bonmin.time_limit'] = 1800
----> 7 results = opt.solve(epi_model_ESH, tee = True)
8 results.write()
~\Anaconda3\envs\seminarorsteinss2019\lib\site-packages\pyomo\opt\base\solvers.py in solve(self, *args, **kwds)
594 initial_time = time.time()
595
--> 596 self._presolve(*args, **kwds)
597
598 presolve_completion_time = time.time()
~\Anaconda3\envs\seminarorsteinss2019\lib\site-packages\pyomo\opt\solver\shellcmd.py in _presolve(self, *args, **kwds)
194 self._keepfiles = kwds.pop("keepfiles", False)
195
--> 196 OptSolver._presolve(self, *args, **kwds)
197
198 #
~\Anaconda3\envs\seminarorsteinss2019\lib\site-packages\pyomo\opt\base\solvers.py in _presolve(self, *args, **kwds)
691 self._problem_format,
692 self._valid_problem_formats,
--> 693 **kwds)
694 total_time = time.time() - write_start_time
695 if self._report_timing:
~\Anaconda3\envs\seminarorsteinss2019\lib\site-packages\pyomo\opt\base\solvers.py in _convert_problem(self, args, problem_format, valid_problem_formats, **kwds)
762 valid_problem_formats,
763 self.has_capability,
--> 764 **kwds)
765
766 def _default_results_format(self, prob_format):
~\Anaconda3\envs\seminarorsteinss2019\lib\site-packages\pyomo\opt\base\convert.py in convert_problem(args, target_problem_type, valid_problem_types, has_capability, **kwds)
108 tmpkw = kwds
109 tmpkw['capabilities'] = has_capability
--> 110 problem_files, symbol_map = converter.apply(*tmp, **tmpkw)
111 return problem_files, ptype, symbol_map
112
~\Anaconda3\envs\seminarorsteinss2019\lib\site-packages\pyomo\solvers\plugins\converter\model.py in apply(self, *args, **kwds)
190 format=args[1],
191 solver_capability=capabilities,
--> 192 io_options=io_options)
193 return (problem_filename,), symbol_map_id
194 else:
~\Anaconda3\envs\seminarorsteinss2019\lib\site-packages\pyomo\core\base\block.py in write(self, filename, format, solver_capability, io_options)
1645 filename,
1646 solver_capability,
-> 1647 io_options)
1648 smap_id = id(smap)
1649 if not hasattr(self, 'solutions'):
~\Anaconda3\envs\seminarorsteinss2019\lib\site-packages\pyomo\repn\plugins\ampl\ampl_.py in __call__(self, model, filename, solver_capability, io_options)
390 skip_trivial_constraints=skip_trivial_constraints,
391 file_determinism=file_determinism,
--> 392 include_all_variable_bounds=include_all_variable_bounds)
393
394 self._symbolic_solver_labels = False
~\Anaconda3\envs\seminarorsteinss2019\lib\site-packages\pyomo\repn\plugins\ampl\ampl_.py in _print_model_NL(self, model, solver_capability, show_section_timing, skip_trivial_constraints, file_determinism, include_all_variable_bounds)
959 ampl_repn,
960 list(self_varID_map[id(var)] for var in ampl_repn._linear_vars),
--> 961 list(self_varID_map[id(var)] for var in ampl_repn._nonlinear_vars))
962 except KeyError as err:
963 self._symbolMapKeyError(err, model, self_varID_map,
~\Anaconda3\envs\seminarorsteinss2019\lib\site-packages\pyomo\repn\plugins\ampl\ampl_.py in <genexpr>(.0)
959 ampl_repn,
960 list(self_varID_map[id(var)] for var in ampl_repn._linear_vars),
--> 961 list(self_varID_map[id(var)] for var in ampl_repn._nonlinear_vars))
962 except KeyError as err:
963 self._symbolMapKeyError(err, model, self_varID_map,
KeyError: (200822968, "Variable 'x1' is not part of the model being written out, but appears in an expression used on this model.", "Variable 'x2' is not part of the model being written out, but appears in an expression used on this model.")
В pprint () новой модели по-прежнему перечисляются x1 и x2 в качестве переменных.
Я вызвал constraint._body = ...
причиной этого?