basinhopping_bounds() 得到了意外的关键字参数 'f_new'
basinhopping_bounds() got an unexpected keyword argument 'f_new'
我在使用 basin-hopping 时遇到这个错误:
basinhopping_bounds() got an unexpected keyword argument 'f_new'
我正在尝试执行 X,F models in Python to solving a DTLZ7 problem 的分析。
所以,我从 4 线性 FO 的问题开始,结果我知道了。当尝试使用 basin-hopping 进行全局最小化来解决问题时,我遇到了上述错误 (scipy-1.2.1.)。有人知道出了什么问题吗?
部分代码如下:
f1 = f_linear([0.06, 0.53, 0.18, 0.18, 0.06], "max")
f2 = f_linear([25, 70, 60, 95, 45], "max")
f3 = f_linear([0, 32.5, 300, 120, 0], "min")
f4 = f_linear([0.1, 0.1, 0.11, 0.35, 0.33], "min")
A_eq = np.array([[1, 1, 1, 1, 1]])
b_eq = np.array([3000])
x0_bounds = (0, 850)
x1_bounds = (0, 220)
x2_bounds = (0, 1300)
x3_bounds = (0, 1615)
x4_bounds = (0, 700)
F = [f1, f2, f3, f4]
def mu_D(x, F):
x = np.array(x)
return max([f_.mu(x) for f_ in F])
def basinhopping_bounds(x):
resp = True
if np.dot(x, A_eq[0]) != b_eq[0]:
resp = False
if x[0] < x0_bounds[0] or x[0] > x0_bounds[1]:
resp = False
if x[1] < x1_bounds[0] or x[1] > x1_bounds[1]:
resp = False
if x[2] < x2_bounds[0] or x[2] > x2_bounds[1]:
resp = False
if x[3] < x3_bounds[0] or x[3] > x3_bounds[1]:
resp = False
if x[4] < x4_bounds[0] or x[4] > x4_bounds[1]:
resp = False
return resp
cobyla_constraints = [
{"type": "ineq", "fun": lambda x: x[0]},
{"type": "ineq", "fun": lambda x: x0_bounds[1] - x[0]},
{"type": "ineq", "fun": lambda x: x[1]},
{"type": "ineq", "fun": lambda x: x1_bounds[1] - x[1]},
{"type": "ineq", "fun": lambda x: x[2]},
{"type": "ineq", "fun": lambda x: x2_bounds[1] - x[2]},
{"type": "ineq", "fun": lambda x: x[3]},
{"type": "ineq", "fun": lambda x: x3_bounds[1] - x[3]},
{"type": "ineq", "fun": lambda x: x[4]},
{"type": "ineq", "fun": lambda x: x4_bounds[1] - x[4]},
{"type": "eq", "fun": lambda x: np.dot(x, A_eq[0]) - b_eq[0]},
]
minimizer_kwargs = {"args": F, "method": "SLSQP", "constraints": cobyla_constraints}
opt.basinhopping(
mu_D,
f1.x_max,
minimizer_kwargs=minimizer_kwargs,
accept_test=basinhopping_bounds,
disp=True,
)
basinhopping step 0: f 1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-11-ba4f3efaec5d> in <module>
5 minimizer_kwargs=minimizer_kwargs,
6 accept_test=basinhopping_bounds,
----> 7 disp=True,
8 )
~/anaconda3/lib/python3.6/site-packages/scipy/optimize/_basinhopping.py in basinhopping(func, x0, niter, T, stepsize, minimizer_kwargs, take_step, accept_test, callback, interval, disp, niter_success, seed)
674 " successfully"]
675 for i in range(niter):
--> 676 new_global_min = bh.one_cycle()
677
678 if callable(callback):
~/anaconda3/lib/python3.6/site-packages/scipy/optimize/_basinhopping.py in one_cycle(self)
152 new_global_min = False
153
--> 154 accept, minres = self._monte_carlo_step()
155
156 if accept:
~/anaconda3/lib/python3.6/site-packages/scipy/optimize/_basinhopping.py in _monte_carlo_step(self)
127 for test in self.accept_tests:
128 testres = test(f_new=energy_after_quench, x_new=x_after_quench,
--> 129 f_old=self.energy, x_old=self.x)
130 if testres == 'force accept':
131 accept = True
TypeError: basinhopping_bounds() got an unexpected keyword argument 'f_new'
https://docs.scipy.org/doc/scipy-0.19.0/reference/generated/scipy.optimize.basinhopping.html
此文档描述了 accept_test
参数。它必须是可调用的,可以识别一组关键字参数(或者至少在给定它们时不会阻塞):
accept_test : callable, accept_test(f_new=f_new, x_new=x_new, f_old=fold, x_old=x_old), optional
Define a test which will be used to judge whether or not to accept the step.
This will be used in addition to the Metropolis test based on “temperature” T.
The acceptable return values are True, False, or "force accept". If any of the
tests return False then the step is rejected. If the latter, then this will
override any other tests in order to accept the step. This can be used, for
example, to forcefully escape from a local minimum that basinhopping is
trapped in.
你的函数只接受位置参数:
def basinhopping_bounds(x):
您还可以在错误回溯中看到 minimize
如何调用您的函数:
testres = test(f_new=energy_after_quench, x_new=x_after_quench,
--> 129 f_old=self.energy, x_old=self.x)
您的边界定义不正确。在 basinhopping
中,您的边界应定义为 class 实例。您应该使用以下内容:
import numpy as np
import scipy.optimize as opt
class MyBounds(object):
'''
bounds class to make sure your variable is with in the inspected bounds
'''
def __init__(self, xmin, xmax):
self.xmax = np.array(xmax)
self.xmin = np.array(xmin)
def __call__(self, **kwargs):
x = kwargs["x_new"]
tmax = bool(np.all(x <= self.xmax))
tmin = bool(np.all(x >= self.xmin))
return tmax and tmin
# init bounds
lower_bounds = [ 0, 0, 0, 0, 0]
upper_bounds = [850, 220, 1300, 1615, 700]
my_bounds = MyBounds(lower_bounds, upper_bounds)
...
# optimize
result = opt.basinhopping(mu_D,
f1.x_max,
minimizer_kwargs = minimizer_kwargs,
accept_test = my_bounds,
disp = True)
同时考虑合并您的约束。如果您使用数组而不是 element-wise 约束,您将只有三个约束。然而,看看你的约束(除了最后一个)你只是再次定义你的边界。
我在使用 basin-hopping 时遇到这个错误:
basinhopping_bounds() got an unexpected keyword argument 'f_new'
我正在尝试执行 X,F models in Python to solving a DTLZ7 problem 的分析。
所以,我从 4 线性 FO 的问题开始,结果我知道了。当尝试使用 basin-hopping 进行全局最小化来解决问题时,我遇到了上述错误 (scipy-1.2.1.)。有人知道出了什么问题吗?
部分代码如下:
f1 = f_linear([0.06, 0.53, 0.18, 0.18, 0.06], "max")
f2 = f_linear([25, 70, 60, 95, 45], "max")
f3 = f_linear([0, 32.5, 300, 120, 0], "min")
f4 = f_linear([0.1, 0.1, 0.11, 0.35, 0.33], "min")
A_eq = np.array([[1, 1, 1, 1, 1]])
b_eq = np.array([3000])
x0_bounds = (0, 850)
x1_bounds = (0, 220)
x2_bounds = (0, 1300)
x3_bounds = (0, 1615)
x4_bounds = (0, 700)
F = [f1, f2, f3, f4]
def mu_D(x, F):
x = np.array(x)
return max([f_.mu(x) for f_ in F])
def basinhopping_bounds(x):
resp = True
if np.dot(x, A_eq[0]) != b_eq[0]:
resp = False
if x[0] < x0_bounds[0] or x[0] > x0_bounds[1]:
resp = False
if x[1] < x1_bounds[0] or x[1] > x1_bounds[1]:
resp = False
if x[2] < x2_bounds[0] or x[2] > x2_bounds[1]:
resp = False
if x[3] < x3_bounds[0] or x[3] > x3_bounds[1]:
resp = False
if x[4] < x4_bounds[0] or x[4] > x4_bounds[1]:
resp = False
return resp
cobyla_constraints = [
{"type": "ineq", "fun": lambda x: x[0]},
{"type": "ineq", "fun": lambda x: x0_bounds[1] - x[0]},
{"type": "ineq", "fun": lambda x: x[1]},
{"type": "ineq", "fun": lambda x: x1_bounds[1] - x[1]},
{"type": "ineq", "fun": lambda x: x[2]},
{"type": "ineq", "fun": lambda x: x2_bounds[1] - x[2]},
{"type": "ineq", "fun": lambda x: x[3]},
{"type": "ineq", "fun": lambda x: x3_bounds[1] - x[3]},
{"type": "ineq", "fun": lambda x: x[4]},
{"type": "ineq", "fun": lambda x: x4_bounds[1] - x[4]},
{"type": "eq", "fun": lambda x: np.dot(x, A_eq[0]) - b_eq[0]},
]
minimizer_kwargs = {"args": F, "method": "SLSQP", "constraints": cobyla_constraints}
opt.basinhopping(
mu_D,
f1.x_max,
minimizer_kwargs=minimizer_kwargs,
accept_test=basinhopping_bounds,
disp=True,
)
basinhopping step 0: f 1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-11-ba4f3efaec5d> in <module>
5 minimizer_kwargs=minimizer_kwargs,
6 accept_test=basinhopping_bounds,
----> 7 disp=True,
8 )
~/anaconda3/lib/python3.6/site-packages/scipy/optimize/_basinhopping.py in basinhopping(func, x0, niter, T, stepsize, minimizer_kwargs, take_step, accept_test, callback, interval, disp, niter_success, seed)
674 " successfully"]
675 for i in range(niter):
--> 676 new_global_min = bh.one_cycle()
677
678 if callable(callback):
~/anaconda3/lib/python3.6/site-packages/scipy/optimize/_basinhopping.py in one_cycle(self)
152 new_global_min = False
153
--> 154 accept, minres = self._monte_carlo_step()
155
156 if accept:
~/anaconda3/lib/python3.6/site-packages/scipy/optimize/_basinhopping.py in _monte_carlo_step(self)
127 for test in self.accept_tests:
128 testres = test(f_new=energy_after_quench, x_new=x_after_quench,
--> 129 f_old=self.energy, x_old=self.x)
130 if testres == 'force accept':
131 accept = True
TypeError: basinhopping_bounds() got an unexpected keyword argument 'f_new'
https://docs.scipy.org/doc/scipy-0.19.0/reference/generated/scipy.optimize.basinhopping.html
此文档描述了 accept_test
参数。它必须是可调用的,可以识别一组关键字参数(或者至少在给定它们时不会阻塞):
accept_test : callable, accept_test(f_new=f_new, x_new=x_new, f_old=fold, x_old=x_old), optional
Define a test which will be used to judge whether or not to accept the step.
This will be used in addition to the Metropolis test based on “temperature” T.
The acceptable return values are True, False, or "force accept". If any of the
tests return False then the step is rejected. If the latter, then this will
override any other tests in order to accept the step. This can be used, for
example, to forcefully escape from a local minimum that basinhopping is
trapped in.
你的函数只接受位置参数:
def basinhopping_bounds(x):
您还可以在错误回溯中看到 minimize
如何调用您的函数:
testres = test(f_new=energy_after_quench, x_new=x_after_quench,
--> 129 f_old=self.energy, x_old=self.x)
您的边界定义不正确。在 basinhopping
中,您的边界应定义为 class 实例。您应该使用以下内容:
import numpy as np
import scipy.optimize as opt
class MyBounds(object):
'''
bounds class to make sure your variable is with in the inspected bounds
'''
def __init__(self, xmin, xmax):
self.xmax = np.array(xmax)
self.xmin = np.array(xmin)
def __call__(self, **kwargs):
x = kwargs["x_new"]
tmax = bool(np.all(x <= self.xmax))
tmin = bool(np.all(x >= self.xmin))
return tmax and tmin
# init bounds
lower_bounds = [ 0, 0, 0, 0, 0]
upper_bounds = [850, 220, 1300, 1615, 700]
my_bounds = MyBounds(lower_bounds, upper_bounds)
...
# optimize
result = opt.basinhopping(mu_D,
f1.x_max,
minimizer_kwargs = minimizer_kwargs,
accept_test = my_bounds,
disp = True)
同时考虑合并您的约束。如果您使用数组而不是 element-wise 约束,您将只有三个约束。然而,看看你的约束(除了最后一个)你只是再次定义你的边界。