如何让OpenMDAO中PyOptSparse SLSQP驱动严格执行设计变量边界,与SciPyOptimize版本表现一致
OpenMDAO中使PyOptSparse SLSQP严格执行设计变量边界的方法
PyOptSparse的SLSQP实现默认没有开启设计变量迭代点的边界强制裁剪逻辑,因此会出现评估越界工况的情况,要让它的表现和SciPyOptimize SLSQP完全一致,可通过以下两种方案实现:
- 方案1:开启优化器内置的边界强制执行开关
PyOptSparse v2.0及以上版本的SLSQP优化器原生支持enforce_bounds参数,在OpenMDAO中声明驱动时传入该参数设置为True即可,示例代码如下:
import openmdao.api as om from openmdao.drivers.pyoptsparse_driver import pyOptSparseDriver prob = om.Problem() # 定义组件、设计变量、约束、目标等逻辑省略 prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = 'SLSQP' # 开启边界强制,保证迭代点不会超出设计变量上下界 prob.driver.opt_settings['enforce_bounds'] = True
该设置会让优化器在生成每一步迭代点时主动裁剪超出边界的取值,和SciPyOptimize SLSQP的默认行为完全一致。
- 方案2:添加前置设计变量裁剪组件
如果你使用的PyOptSparse版本较低不支持enforce_bounds参数,可以在模型最上游添加一个自定义裁剪组件,每次迭代先将传入的设计变量裁剪到设定的上下界范围内,再传递给下游计算组件,示例代码如下:
import numpy as np class BoundClipComp(om.ExplicitComponent): def setup(self): # 按照你的设计变量数量、名称定义输入输出,此处以单设计变量x为例 self.add_input('x_in', val=0.0) self.add_output('x_out', val=0.0) # 记录设计变量的上下界 self.x_lower = 0.0 self.x_upper = 10.0 def compute(self, inputs, outputs): outputs['x_out'] = np.clip(inputs['x_in'], self.x_lower, self.x_upper)
将该组件放在模型的最前端,原设计变量关联到裁剪组件的输入,后续所有组件调用裁剪后的输出值即可,即可保证所有下游计算都不会接收到越界的设计变量取值。
注意:方案2需要你将所有设计变量都对应添加裁剪逻辑,适合版本兼容性要求高的场景,方案1配置更简单,优先推荐使用。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

