python - Scipy:最小化违反给定界限

标签 python scipy

我正在尝试使用 scipy.optimize.minimize简单 a <= x <= b界限。然而,我的目标函数经常会在边界之外被评估。据我了解,这发生在 minimize 时。尝试确定目标函数在边界处的梯度。


最小的例子:

import math
import numpy as np
from scipy.optimize import Bounds, minimize

constraint = Bounds([-1, -1], [1, 1], True)
def fun(x):
    print(x)
    return -math.exp(-np.dot(x,x))
result = minimize(fun, [-1, -1], bounds=constraint)

输出显示最小化器跳转到点 [1,1]然后尝试在 [1.00000001, 1] 处进行评估:

[-1. -1.]
[-0.99999999 -1.        ]
[-1.         -0.99999999]
[-0.72932943 -0.72932943]
[-0.72932942 -0.72932943]
[-0.72932943 -0.72932942]
[-0.22590689 -0.22590689]
[-0.22590688 -0.22590689]
[-0.22590689 -0.22590688]
[1. 1.]
[1.00000001 1.        ]
[1.         1.00000001]
[-0.03437328 -0.03437328]
...

这个例子当然没有问题,如fun也可以在那里进行评估。但情况可能并非总是如此......


在我的实际问题中,最小值不能在边界上,我有向边界添加一个 epsilon 的简单解决方法。 但是人们会期望应该有一个简单的解决方案来解决这个问题,如果最小值可以在边界上也能起作用?

PS:如果我是第一个遇到这个问题的人,那会很奇怪 -- 抱歉,如果这个问题以前曾在某个地方被问过,但我没有在任何地方找到它。

最佳答案

讨论 here (感谢@“Welcome to Stack Overflow”给我的评论),问题确实是梯度例程不遵守边界。 我写了一个新的来完成这项工作:

import math
import numpy as np
from scipy.optimize import minimize

def gradient_respecting_bounds(bounds, fun, eps=1e-8):
    """bounds: list of tuples (lower, upper)"""
    def gradient(x):
        fx = fun(x)
        grad = np.zeros(len(x))
        for k in range(len(x)):
            d = np.zeros(len(x))
            d[k] = eps if x[k] + eps <= bounds[k][1] else -eps
            grad[k] = (fun(x + d) - fx) / d[k]
        return grad
    return gradient

bounds = ((-1, 1), (-1, 1))
def fun(x):
    print(x)
    return -math.exp(-np.dot(x,x))
result = minimize(fun, [-1, -1], bounds=bounds,
                  jac=gradient_respecting_bounds(bounds, fun))

请注意,这可能会有点低效,因为 fun(x) 现在在每个点被计算两次。 这似乎是不可避免的,来自 lbfgsb.py 中 _minimize_lbfgsb 的相关片段:

if jac is None:
    def func_and_grad(x):
        f = fun(x, *args)
        g = _approx_fprime_helper(x, fun, epsilon, args=args, f0=f)
        return f, g
else:
    def func_and_grad(x):
        f = fun(x, *args)
        g = jac(x, *args)
        return f, g

如您所见,f 的值只能由内部 _approx_fprime_helper 函数重用。

关于python - Scipy:最小化违反给定界限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52208363/

相关文章:

python - Python 中的随机优化

python - 导入 _tkinter 还是 tkinter?

python - 关于 Python 上的 ETL 工作的问题/一般情况

python - 是否可以在 pdfquery 中使用正则表达式?

python - 最小化多变量函数 Python SciPy

Python 不会将所有值返回到系统,而是将其替换为...

python - 构建一个 conda 包,从 env.yaml 文件创建一个 conda 环境

python - 在线性时间内寻找包含特定字符的最短子串

Python 停止在 loadmat 上工作

python - scipy.optimize.curve_fit : Default value of max_nfev broken?