如何在 OpenMDAO 中使用整数参数进行优化

How to optimize with integer parameters in OpenMDAO

我目前正在尝试使用 OpenMDAO 1.7.2 对地图上的位置进行一些优化。进行计算的(预先存在的)模块仅支持整数坐标(一米的分辨率)。

现在我正在使用 IndepVarComp 对每个方向进行优化,每个方向都包含一个 float 向量。然后在使用这些值之前对其进行四舍五入,但这是非常低效的,因为求解器主要尝试小于一的变化。

当我尝试用整数向量初始化 IndepVarComp 时,第一次迭代工作正常(使用初始值),但在第二次迭代中失败,因为 IndepVarComp 中的数据设置为空 ndarray.

翻阅OpenMDAO源码发现这是因为

indep_var_comp._init_unknowns_dict['x']['size'] == 0

只要数据类型不可区分,就会在 Component_add_variable() 方法中发生。

这是一个示例问题,它说明了定义整数 IndepVarComp 是如何失败的:

from openmdao.api import Component, Group, IndepVarComp, Problem, ScipyOptimizer

INITIAL_X = 1

class ResultCalculator(Component):
    def __init__(self):
        super(ResultCalculator, self).__init__()
        self.add_param('x', INITIAL_X)
        self.add_output('y', 0.)

    def solve_nonlinear(self, params, unknowns, resids):
        unknowns['y'] = (params['x'] - 3) ** 2 - 4

problem = Problem()
problem.root = Group()
problem.root.add('indep_var_comp', IndepVarComp('x', INITIAL_X))
problem.root.add('calculator', ResultCalculator())
problem.root.connect('indep_var_comp.x', 'calculator.x')

problem.driver = ScipyOptimizer()
problem.driver.options['optimizer'] = 'COBYLA'
problem.driver.add_desvar('indep_var_comp.x')
problem.driver.add_objective('calculator.y')

problem.setup()
problem.run()

失败

ValueError: setting an array element with a sequence.

请注意,如果我设置 INITIAL_X = 0.,一切正常。

我应该如何针对整数进行优化?

如果你想使用整数变量,你需要选择不同类型的优化器。您无法强制 COBYLA 尊重完整性。此外,如果您确实有某种整数舍入导致分析不连续,那么您真的根本不能使用 COBYLA(或任何其他连续优化器)。他们都对您将违反的功能的平滑性做出了基本假设。

听起来您应该考虑使用粒子群算法或遗传算法来解决您的问题。或者,您可以专注于使分析平滑且可微分,并缩放您的一些输入以获得更合理的分辨率。您还可以放宽优化器的收敛容差,使其在设计变量低于物理意义时停止迭代。