python - 修改约束的主体而不计算其值
问题描述
我正在使用 pyomo 5.3 在 python 3.6 中编程
我希望修改非索引约束的主体(以防它不是我需要的标准格式)。问题是在从body中减去时计算特定点的约束值。但是,我需要函数形式的主体,因为我必须构造一个目标,它是导致最小-最大问题的所有非线性约束中的最大值。
我试图直接设置传递给函数的约束体,但我得到了无法设置属性的输出。是否有设置约束主体的功能?
编辑:这是我找到的解决方案:
约束._body = ...
我希望用它来改变优化问题的形式。
(对不起,非英语评论)
以下是此示例中使用的函数:
- 第一个将所有变量的域放宽为实数。
- 第二个使用 Epigraph 方法创建一个新模型。(这里我
._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 = ...
是因为这个吗?
解决方案
我发现了错误。
在
epi_nonlinear_constrs[k]._body = (epi_nonlinear_constrs[k].body - epi_model.alpha_epi)
我使用了其他模型的约束体nonlinear_constrs[k].body
而不是同一模型的约束体。因此,约束具有模型中未引用的变量。因此,来自求解器的错误消息。
推荐阅读
- html - Angular Flex 是否可以有多个粘性列?
- java - 如何在验证侦听器事件 verifyText(...) 上获取选定的文本小部件文本
- android - 基于画布的自定义进度视图不圆
- c# - 在 ADO.NET 中密封数据提供程序类(如 SqlConnection、SqlCommand 等)背后的原因是什么?
- selenium - 单击添加按钮后如何在同一元素中输入不同的文本?
- swift - 如何将子上下文中的对象检索到另一个上下文中?
- rabbitmq - 如何找到队列长度限制值的rabbitmq设置
- image-segmentation - 生物医学图像分割
- ios - 最初从 firebase 获取无效的推送令牌,最后得到一个有效的推送令牌
- java - Spark scala非常规日期转换中的两个相似的udf产生不同的结果