从scipy.optimize到nlopt包使用的优化方法



我目前有一个目标函数的黑盒。它已经在scipy.optimize中成功地使用为"status=op.basinhopping(obj,sp,…(",然而,当我尝试相同的obj到NLPT包时,它会给出的消息

TypeError: <lambda>() takes exactly 1 argument (2 given). 

我假设scipy.optimize的obj有两个参数,一个是函数本身,另一个是每个维度的微分,而NLPT方法中使用的obj只需要函数本身。如果我是对的,我应该如何修改obj,使其可以在NLPT中使用?我使用非直瞄的代码

sys.path.insert(0,os.path.join(os.getcwd(),"build/R_ulp"))
import foo as foo_square
reload(foo_square)
sp=np.zeros(foo_square.dim)+args.startPoint
obj=lambda X:foo_square.R(* X)
opt = nlopt.opt(nlopt.GN_CRS2_LM, foo_square.dim)
opt.set_min_objective(obj)
opt.set_lower_bounds(-1e9)
opt.set_upper_bounds(1e9)
opt.set_stopval(0)
opt.set_xtol_rel(1e-9)
opt.set_initial_step(1)
opt.set_population(0)
opt.set_maxeval(100000) 
status = opt.optimize([0.111111111]*foo_square.dim)

如果您的目标需要额外的参数,您也可以考虑functools.partial

示例:代替

obj = lambda x, grad, y1: foo_square.R(x, y=y1)

您可以使用:

from functools import partial
[...]
obj = partial(foo_square.R, y=y1)

obj也将被NlOpt接受,因为现在函数签名再次匹配。

SciPy优化器和NLopt对目标函数的签名有不同的约定。NLopt中目标函数的文档显示

函数f的形式应该是:

def f(x, grad):
if grad.size > 0:

等。

因此,您需要创建一个接受两个参数xgrad的目标函数。如果是grad.size > 0,函数必须用梯度填充数组。

相关内容

  • 没有找到相关文章

最新更新