在我的最小化问题中,所有有界最小化方法,例如'L-BFGS-B','TNC'都不收敛,但是'Nelder-Mead'很好地收敛。因此,我更喜欢使用经过修改的最小化功能的“ Nelder-Mead”,如下所示:
def outbound_penalty(x, bounds):
o1 = (bounds[:, 0]-x).max()
o2 = (x-bounds[:, 1]).max()
outbound = max(o1, o2, 0)
rez = 100500*outbound
def bounded_fun(x, bounds):
return fun(x) + outbound_penalty(x, bounds)
x是numpy数组形状(4),界限具有形状(2,4),界限[0]是底部边框,界限[1]-顶部边框。令人惊讶的是,它没有我预期的那么快。在4 * 10 ^ 6调用时,CPU占用自己的40秒时间。我当然记得了。但是我不得不问。 numpy / scipy中是否有一些非常优化的函数,可以用来构造出站罚分?
def outbound_penalty(x, bs):
o1 = (bs[:, 0] - x).max()
o2 = (x - bs[:, 1]).max()
outbound = max(o1, o2, 0)
return 1000000 * outbound
%timeit outbound_penalty(smpls [0],np_bounds)每个循环22.5 µs±123 ns(平均±标准偏差,共运行7次,每个循环10000个)%timeit outbound_penalty_fast(smpls [0],np_bounds)每个循环68.4 µs±390 ns(平均±标准偏差,共运行7次,每个10000个循环)
您可以使用广播一次性执行出站逐元素函数调用,并且当然可以使用np.max()
而不是在for循环中将y
与mx
进行比较:
import numpy as np
def outbound_penalty(x, bs):
o1 = (bs[:, 0] - x).max()
o2 = (x - bs[:, 1]).max()
outbound = max(o1, o2, 0)
return 1000000 * outbound
def outbound_penalty_fast(x, bs):
o1 = (bs[:, 0, None] - x).max(axis=0)
o2 = (x - bs[:, 1, None]).max(axis=0)
outbound = np.clip(np.maximum(o1, o2), a_max=None, a_min=0)
return 1000000 * outbound
bnd = np.random.randint(100, 200, size=(2, 2))
bnd[:, 0] = 0
sss = np.random.uniform(-100, 300, size=(2, 1000))
%timeit np.max(np.array([outbound_penalty(x, bnd) for x in sss.T]))
# 9.44 ms ± 166 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.max(outbound_penalty_fast(sss, bnd))
# 38.1 µs ± 1.33 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
mx = np.max(np.array([outbound_penalty(x, bnd) for x in sss.T]))
mx_fast = np.max(outbound_penalty_fast(sss, bnd))
mx == mx_fast # True