限制 scipy 最小化的结果 (SLSQP)

Restricting result of scipy minimization (SLSQP)

我想最小化一个 objective 函数,它在每一步都调用模拟软件,return 是一个标量。有什么方法可以限制 objective 函数的结果吗?例如,我想获得使结果尽可能接近 1 的变量值。

我试图简单地从 objective 函数的结果中减去 1,但这没有帮助。我也玩过 coinstraints,但如果我理解正确的话,它们只适用于输入变量。另一种方法是创建一个日志,在每次迭代后存储所有变量的值(我已经在做)。最后,应该可以搜索结果最接近 1 且 return 它是可变配置的迭代。问题是最小化可能运行的时间太长并产生无用的结果。有没有更好的方法?

def objective(data):
     """
     Optimization Function
     :param data: list containing the current guess (list of float values)
     :return: each iteration returns a scalar which should be minimized
     """

     # do simulation and calculate scalar

     return result - 1.0   # doesn't work since result is becoming negative
def optimize(self):
     """
     daemon which triggers input, reads output and optimizes results
     :return: optimized results
     """

     # initialize log, initial guess etc.

     sol = minimize(self.objective, x0, method='SLSQP', options={'eps': 1e-3, 'ftol': 1e-9}, bounds=boundList)

目标是找到一个可以适应任何目标值的解决方案。用户应该能够输入一个值,最小化将return这个目标值的最佳变量配置。

如评论中所述,实现此目的的一种方法是使用

return (result - 1.0) ** 2

objective 中。这样结果就不会变成负数,优化将尝试以接近您的目标值的方式找到 result(例如,在您的情况下为 1.0)。

插图,首先使用您当前的set-up:

from scipy.optimize import minimize


def objective(x, target_value):

    # replace this by your actual calculations
    result = x - 9.0

    return result - target_value


# add some bounds for all the parameters you have
bnds = [(-100, 100)]

# target_value is passed in args; feel free to add more
res = minimize(objective, (1), args=(1.0,), bounds=bnds)

if res.success:
    # that's the optimal x
    print(f"optimal x: {res.x[0]}")
else:
    print("Sorry, the optimization was not successful. Try with another initial"
          " guess or optimization method")

因为我们选择 -100 作为 x 的下界,并要求最小化 objective,最优的 x-100(将是如果你 运行 上面的代码打印)。如果我们现在替换行

return result - target_value

来自

return (result - target_value) ** 2

其余不变,最优的x是预期的10

请注意,我将您的目标值作为附加参数传递,以便您的函数稍微灵活一些。