使用scipy.optimize.brute最小化给定时间间隔内的函数

时间:2014-01-23 13:45:46

标签: python scipy mathematical-optimization

我试图在给定的时间间隔内最小化一个函数;在我的情况下,间隔为[-pi/2, pi/2]

以下是我在剧本中写的内容:

ranges = slice(-pi/2, pi/2, pi/200)
res = optimize.brute(g, (ranges,))

def g(x):
    # z and a are global
    (-(z+1) * (((a/4) * (3*cos(x/3) + cos(3*x/2)) +
                (b/4) * (-3*sin(x/2)-3*sin(3*x/2)))**2 +
               ((a/4‌​) * (sin(x/3) + sin(3*x/2)) + (b/4)*
                (cos(x/2) + 3*cos(3*x/2)))**2) + 4*(c*cos(x/2))**2)

,结果res

array([-3.14159265])

我在绘制解决方案时遇到的问题是最小化的一些解决方案超出了区间[-pi/2, pi/2]。有什么帮助吗?

2 个答案:

答案 0 :(得分:9)

“问题”是默认的“修整功能”:brute可以选择提供完成最小化功能。这样做是为了使蛮力方法可以作为第一个猜测,然后使用更好的最小化函数对结果进行“抛光”。

如果此功能设置为无,则不会发生任何事情,这可能是您想要的。不幸的是,在这种情况下,默认设置为fmin,这是下坡单面(Nelder-Mead)方法,这将忽略任何范围/网格规范。因此,对于像sin(0.5 * x)这样的函数,它将从brute函数找到的最低点开始(-pi/2)并从那里继续,找到-pi为(res = optimize.brute(g, (ranges,), finish=None) 全球最小值。

解决方案很简单:

{{1}}

会给你想要的东西。

scipy.optimize.brute documentation的强制性链接。

答案 1 :(得分:0)

如果传递的参数超出了您想要的范围,您可以编写目标函数来返回np.inf。所以,例如:

def g(x, x_limit):

if x > x_limit:
    return np.inf
else:
    return (-(z+1) * (((a/4) * (3*cos(x/3) + cos(3*x/2)) +
           (b/4) * (-3*sin(x/2)-3*sin(3*x/2)))**2 +
           ((a/4‌​) * (sin(x/3) + sin(3*x/2)) + (b/4)*
           (cos(x/2) + 3*cos(3*x/2)))**2) + 4*(c*cos(x/2))**2)