1 opt.basinhopping()
使用盆地跳跃法(basin-hopping), 寻找函数func()的全局最小值。
basin-hopping算法包含两个阶段,将全局步进算法和每阶段局部最小化结合起来。
Designed to mimic the natural process of energy minimization of clusters of atoms, it works well for similar problems with “funnel-like, but rugged” energy landscapes
1.1 引用格式
scipy.optimize.basinhopping(func,x0,niter=100,T=1.0,stepsize=0.5,minimizer_kwargs=None,take_step=None,accept_test=None,callback=None,interval=50,disp=False,niter_success=None,seed=None)
1.2 Parameters
func: callable __f(x,_*args)_
待优化的函数。Args可以作为minimizer_kwargs的可选项
x0: array_like
初始的猜测值。
niter: integer, optional
迭代次数。
T: float, optional
参数T表示接受/拒绝标准。T越大,表示函数值允许有更大的跳跃。为了获得最佳结果,T应该与局部最小值之间的间隔(函数值)相当。
Stepsize: float, optional
随机数位移的最大步长。
minimizer_kwargs: dict, optional
额外的关键参数通过该字典参数传递给优化函数scipy.optimize.minimize()
比如:
method: str
最小化方法 (e.g."L-BFGS-B")
args: tuple
传递给待优化函数(func)的额外参数。
take_step:callable
take_step(x), optional
用来替换默认的逐步执行规则。默认的逐步执行规则是一种坐标轴上的随机移动,但是在某些场景中,其他的规则可能会效果更好。
accept_test:callable,
accept_test(f_new=f_new,__x_new=x_new,__f_old=fold,__x_old=x_old)__, optional
定义一个用于判断是否接受当前步骤的测试。除了使用基于参数T的默认Metropolis测试之外,还会使用这个额外的测试。返回结果可能是:True, False, or "forceaccept"。如果是True,则用该测试覆盖迷人的T测试。
callback:callable,
callback(x,__f,__accept), optional
一个回调函数(callback function),将为找到的所有最小值调用该函数。 X和f是试验最小值的坐标和函数值,accept是该最小值是否被接受。
interval:integer, optional
更新步长的间隔。
disp:bool, optional
为True时表示打印状态信息。
niter_success:integer, optional
如果全局最小候选数与此迭代次数保持相同,则停止运行。
seed:int or _np.random.RandomState_, optional
随机种子
1.3 Returns
res:OptimizeResult
优化结果表示为OptimizeResult对象。重要属性包括:
x:表示优化结果对应的参数数组。
fun:表示最优结果的值
message:描述终止原因的消息。
1.4 Examples
a. 求解二元函数的最小值:
通过minimizer_kwargs的method指定使用的最优化算法;
x0表示函数func2d的初始参数;
def func2d(x):
f = np.cos(14.5 * x[0] - 0.3) + (x[1] + 0.2) * x[1] + (x[0] + 0.2) * x[0]
df = np.zeros(2)
df[0] = -14.5 * np.sin(14.5 * x[0] - 0.3) + 2. * x[0] + 0.2
df[1] = 2. * x[1] + 0.2
return f, df
minimizer_kwargs = {"method":"L-BFGS-B", "jac":True}
x0 = [0.5, 0.1]
ret = basinhopping(func2d, x0, minimizer_kwargs=minimizer_kwargs, niter=200)
print(ret)
output:
fun: -1.0108761844426555
lowest_optimization_result: fun: -1.0108761844426555
hess_inv: <2x2 LbfgsInvHessProduct with dtype=float64>
jac: array([-5.94570468e-09, 2.26891561e-11])
message: b'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'
nfev: 11
nit: 5
status: 0
success: True
x: array([-0.19506755, -0.1 ])
message: ['requested number of basinhopping iterations completed successfully']
minimization_failures: 0
nfev: 2686
nit: 200
x: array([-0.19506755, -0.1 ])
b. 加上参数的边界
bnds:指定函数func2d的参数变化区间,加上边界之后,最小值与之前不一样,此时只能找到该区间内的最小值。
def func2d(x):
f = np.cos(14.5 * x[0] - 0.3) + (x[1] + 0.2) * x[1] + (x[0] + 0.2) * x[0]
df = np.zeros(2)
df[0] = -14.5 * np.sin(14.5 * x[0] - 0.3) + 2. * x[0] + 0.2
df[1] = 2. * x[1] + 0.2
return f, df
bnds = [(0.05,0.5), (0,1)]
minimizer_kwargs = {"method":"L-BFGS-B", "jac":True, 'bounds': bnds}
x0 = [0.5, 0.1]
ret = basinhopping(func2d, x0, minimizer_kwargs=minimizer_kwargs, niter=200)
print(ret)
print("global minimum: x = [%.4f, %.4f], f(x0) = %.4f" % (ret.x[0],ret.x[1], ret.fun))
output:
fun: -0.8972667196907541
lowest_optimization_result: fun: -0.8972667196907541
hess_inv: <2x2 LbfgsInvHessProduct with dtype=float64>
jac: array([-7.99192379e-11, 2.00000000e-01])
message: b'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'
nfev: 7
nit: 5
status: 0
success: True
x: array([0.23417129, 0. ])
message: ['requested number of basinhopping iterations completed successfully']
minimization_failures: 0
nfev: 1225
nit: 200
x: array([0.23417129, 0. ])
global minimum: x = [0.2342, 0.0000], f(x0) = -0.8973
c. 指定不同的优化算法
同样的初始值下,使用BFGS(拟牛顿法)的优化结果
BFGS不能指定边界,所以此时的优化结果与a一样。
minimizer_kwargs = {"method":"BFGS", "jac":True, 'bounds': bnds}
output:
fun: -1.0108761844426555
lowest_optimization_result: fun: -1.0108761844426555
hess_inv: array([[4.71187481e-03, 3.70410841e-06],
[3.70410841e-06, 5.00306300e-01]])
jac: array([-2.71034778e-10, -2.18089991e-10])
message: 'Optimization terminated successfully.'
nfev: 9
nit: 6
njev: 9
status: 0
success: True
x: array([-0.19506755, -0.1 ])
message: ['requested number of basinhopping iterations completed successfully']
minimization_failures: 0
nfev: 1953
nit: 200
njev: 1953
x: array([-0.19506755, -0.1 ])
d.
2 opt. minimize()
最小化一个或多个变量的标量函数。
2.1 引用格式
def minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None):
2.2 Parameters
fun : callable
目标函数。
x0 : ndarray, shape (n,)
初始参数,一维数组。
args : tuple, optional
传递给目标函数及其派生函数的额外参数(`fun`, `jac` and `hess` functions).
method : str or callable, optional
求解最优值的方法。如果没有指定,那么会根据是否有边界、约束来选择``BFGS``, ``L-BFGS-B``, ``SLSQP``中的一种方法。
jac : {callable, '2-point', '3-point', 'cs', bool}, optional
计算梯度向量的方法。Only for CG, BFGS, Newton-CG, L-BFGS-B, TNC, SLSQP, dogleg, trust-ncg, trust-krylov, trust-exact and trust-constr.
hess : {callable, '2-point', '3-point', 'cs', HessianUpdateStrategy}, optional
计算海赛矩阵的方法Only for Newton-CG, dogleg, trust-ncg, trust-krylov, trust-exact and trust-constr.
hessp : callable, optional
bounds : sequence or `Bounds`, optional
参数的边界。
constraints : {Constraint, dict} or List of {Constraint, dict}, optional
约束条件。
tol : float, optional
终止最优化过程的公差。
options : dict, optional
额外选项。所有的优化方法都可以使用一下格式:
maxiter : int,最大迭代次数
disp : bool, 为True时,返回收敛信息。
callback : callable, optional
每次迭代后调用。
2.3 Returns
res : OptimizeResult
优化结果表示为OptimizeResult对象。重要属性包括:
x表示优化结果对应的参数数组。
success表示是否计算出最优值
message描述终止原因的消息。
scipy.optimize.basinhopping
scipy.optimize.minimize()