如何在有界的python优化中找到全局最小值? [英] how to find global minimum in python optimization with bounds?

查看:136
本文介绍了如何在有界的python优化中找到全局最小值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有64个变量的Python函数,并且我尝试在最小函数中使用L-BFGS-B方法对其进行优化,但是该方法对初始猜测有很大的依赖性,并且未能找到全局最小值.

I have a Python function with 64 variables, and I tried to optimise it using L-BFGS-B method in the minimise function, however this method have quite a strong dependence on the initial guess, and failed to find the global minimum.

但是我喜欢它为变量设置界限的能力.有没有一种方法/函数可以找到全局最小值,同时具有变量的边界?

But I liked its ability to set bounds for the variables. Is there a way/function to find the global minimum while having boundaries for the variables ?

推荐答案

这可以通过scipy.optimize.basinhopping完成. Basinhopping是用来查找目标函数的 global 最小值的函数.它使用函数scipy.optimize.minimize进行重复的最小化,并在每次最小化后在坐标空间中采取随机步骤.通过使用实现边界的最小化器之一(例如L-BFGS-B),贝叶霍普仍然可以遵守边界.这是一些代码,展示了如何做到这一点

This can be done with scipy.optimize.basinhopping. Basinhopping is a function designed to find the global minimum of an objective function. It does repeated minimizations using the function scipy.optimize.minimize and takes a random step in coordinate space after each minimization. Basinhopping can still respect bounds by using one of the minimizers that implement bounds (e.g. L-BFGS-B). Here is some code that shows how to do this

# an example function with multiple minima
def f(x): return x.dot(x) + sin(np.linalg.norm(x) * np.pi)

# the starting point
x0 = [10., 10.]

# the bounds
xmin = [1., 1.]
xmax = [11., 11.]

# rewrite the bounds in the way required by L-BFGS-B
bounds = [(low, high) for low, high in zip(xmin, xmax)]

# use method L-BFGS-B because the problem is smooth and bounded
minimizer_kwargs = dict(method="L-BFGS-B", bounds=bounds)
res = basinhopping(f, x0, minimizer_kwargs=minimizer_kwargs)
print res

上面的代码仅适用于简单的情况,但是如果使用盆地跳跃随机位移例程将您带到那儿,您仍然可以最终进入禁区.幸运的是,可以通过使用关键字take_step

The above code will work for a simple case, but you can still end up in a forbidden region if basinhopping random displacement routine takes you there. Luckily that can be overridden by passing a custom step taking routine using the keyword take_step

class RandomDisplacementBounds(object):
    """random displacement with bounds"""
    def __init__(self, xmin, xmax, stepsize=0.5):
        self.xmin = xmin
        self.xmax = xmax
        self.stepsize = stepsize

    def __call__(self, x):
        """take a random step but ensure the new position is within the bounds"""
        while True:
            # this could be done in a much more clever way, but it will work for example purposes
            xnew = x + np.random.uniform(-self.stepsize, self.stepsize, np.shape(x))
            if np.all(xnew < self.xmax) and np.all(xnew > self.xmin):
                break
        return xnew

# define the new step taking routine and pass it to basinhopping
take_step = RandomDisplacementBounds(xmin, xmax)
result = basinhopping(f, x0, niter=100, minimizer_kwargs=minimizer_kwargs,
                      take_step=take_step)
print result

这篇关于如何在有界的python优化中找到全局最小值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆