Python中的盆地跳跃(Basin Hopping)优化

盆地跳跃是一种全局优化算法。它是为解决化学物理学中的问题而开发的,尽管它是一种适用于具有多个最优条件的非线性目标函数的有效算法。

在本教程中,您将发现盆地跳跃全局优化算法。完成本教程后,您将知道:

  • 盆地跳跃优化是一种全局优化,它使用随机扰动来跳跃盆地,并使用局部搜索算法来优化每个盆地。

  • 如何在python中使用盆地跳跃优化算法API。

  • 使用流域跳跃来解决具有多个最优解的全局优化问题的示例。

教程概述

本教程分为三个部分:他们是:

  • 盆地跳跃优化

  • 盆地跳跃API

  • 盆地跳跃的例子 局部最优的多峰优化 具有多个全局最优的多峰优化

盆地跳跃优化

Basin Hopping是为化学物理领域开发的一种全局优化算法。局部优化是指旨在为单变量目标函数定位最优值或在认为存在最优值的区域中运行的优化算法。而全局优化算法旨在将单个全局最优定位在潜在的多个局部(非全局)最优之中。David Wales和Jonathan Doye在1997年的论文中描述了“盆地跳跃”,题目是“通过盆地跳跃进行的全局优化和包含110个原子的Lennard-Jones团簇的最低能级结构”。

该算法包括循环两个步骤,一个是好的候选解的扰动,另一个是将本地搜索应用于被扰动的解。

扰动允许搜索算法跳到搜索空间的新区域,并可能找到导致不同最优值的新盆地,例如技术名称中的“跳槽”。局部搜索使算法可以遍历新盆地达到最佳状态。新的最优值可以作为新的随机扰动的基础,否则将被丢弃。保留新解决方案的决策是由具有“温度”变量的随机决策函数控制的,这与模拟退火非常相似。温度根据算法的迭代次数进行调整。这样可以在高温时在运行的早期就接受任意解决方案,而更严格的策略是在低温时在搜索的后期仅接受质量更好的解决方案。这样,该算法非常类似于具有不同(扰动)起始点的迭代局部搜索。该算法运行指定的迭代次数或函数求值,并且可以多次运行以提高对找到全局最优值或找到相对好的解决方案的信心。

现在,我们已经从较高的层次熟悉了基本的跳变算法,下面让我们看一下Python中用于盆地跳变的API。

盆地跳跃API

在Python中,可以通过Basinhopping()SciPy函数来进行盆地跳跃。

  1. # perform the basin hopping search

  2. result = basinhopping(objective, pt)

另一个重要的超参数是通过“ niter”参数运行搜索集的迭代次数,默认为100。可以将其设置为数千次迭代或更多次迭代。

  1. # perform the basin hopping search

  2. result = basinhopping(objective, pt, niter=10000)

可以通过“步长”控制应用于候选解的扰动量,该“步长”定义了在问题域的边界范围内施加的最大变化量。默认情况下,将其设置为0.5,但应在域中将其设置为合理的值,以允许搜索找到新的盆地。例如,如果搜索空间的合理范围是-100到100,则步长为5.0或10.0个单位可能是合适的(例如,域的2.5%或5%)。

  1. # perform the basin hopping search

  2. result = basinhopping(objective, pt, stepsize=10.0)

默认情况下,使用的本地搜索算法是“ L-BFGS-B”算法。可以通过将“ minimizer_kwargs”参数设置为关键字为“ method”且值作为要使用的本地搜索算法的名称(例如“ nelder-mead”)的目录来更改此设置。可以使用SciPy库提供的任何本地搜索算法。

  1. # perform the basin hopping search

  2. result = basinhopping(objective, pt, minimizer_kwargs={'method':'nelder-mead'})

搜索的结果是一个OptimizeResult对象,可以在其中像字典一样访问属性。可以通过“成功”或“消息”键来访问搜索的成功与否。

可以通过“ nfev”访问功能评估的总数,并且可以通过“ x”键访问为搜索找到的最佳输入。

现在,我们已经熟悉了Python中的盆地跳跃API,下面我们来看一些可行的示例。

盆地跳跃的例子

在本节中,我们将研究在多模态目标函数上使用盆地跳跃算法的一些示例。多峰目标函数是具有多个最优值的函数,例如全局最优值和许多局部最优值,或者具有相同目标函数输出的多个全局最优值。我们将在这两个函数上查看流域跳跃的示例。

局部最优的多峰优化

Ackley函数是目标函数的一个示例,该目标函数具有单个全局最优值和多个局部最优值,可能会在其中陷入局部搜索。因此,需要全局优化技术。这是一个二维目标函数,其全局最佳值为[0,0],其值为0.0。下面的示例实现了Ackley,并创建了一个三维表面图,显示了全局最优值和多个局部最优值。

  1. # ackley multimodal function

  2. from numpy import arange

  3. from numpy import exp

  4. from numpy import sqrt

  5. from numpy import cos

  6. from numpy import e

  7. from numpy import pi

  8. from numpy import meshgrid

  9. from matplotlib import pyplot

  10. from mpl_toolkits.mplot3d import Axes3D

  11. # objective function

  12. def objective(x, y):

  13. return -20.0 * exp(-0.2 * sqrt(0.5 * (x**2 + y**2))) - exp(0.5 * (cos(2 * pi * x) + cos(2 * pi * y))) + e + 20

  14. # define range for input

  15. r_min, r_max = -5.0, 5.0

  16. # sample input range uniformly at 0.1 increments

  17. xaxis = arange(r_min, r_max, 0.1)

  18. yaxis = arange(r_min, r_max, 0.1)

  19. # create a mesh from the axis

  20. x, y = meshgrid(xaxis, yaxis)

  21. # compute targets

  22. results = objective(x, y)

  23. # create a surface plot with the jet color scheme

  24. figure = pyplot.figure()

  25. axis = figure.gca(projection='3d')

  26. axis.plot_surface(x, y, results, cmap='jet')

  27. # show the plot

  28. pyplot.show()

运行示例将创建Ackley函数的表面图,以显示大量的局部最优值。

我们可以将盆地跳跃算法应用于Ackley目标函数。

在这种情况下,我们将使用从-5到5之间的输入域绘制的随机点开始搜索。

  1. # define the starting point as a random sample from the domain

  2. pt = r_min + rand(2) * (r_max - r_min)

我们将使用0.5的步长,200次迭代和默认的本地搜索算法。经过一番尝试和错误后,才选择此配置。

  1. # perform the basin hopping search

  2. result = basinhopping(objective, pt, stepsize=0.5, niter=200)

搜索完成后,它将报告搜索状态,执行的迭代次数以及通过评估发现的最佳结果。

  1. # summarize the result

  2. print('Status : %s' % result['message'])

  3. print('Total Evaluations: %d' % result['nfev'])

  4. # evaluate solution

  5. solution = result['x']

  6. evaluation = objective(solution)

  7. print('Solution: f(%s) = %.5f' % (solution, evaluation))

结合在一起,下面列出了将盆地跳跃应用于Ackley目标函数的完整示例。

  1. # basin hopping global optimization for the ackley multimodal objective function

  2. from scipy.optimize import basinhopping

  3. from numpy.random import rand

  4. from numpy import exp

  5. from numpy import sqrt

  6. from numpy import cos

  7. from numpy import e

  8. from numpy import pi

  9. # objective function

  10. def objective(v):

  11. x, y = v

  12. return -20.0 * exp(-0.2 * sqrt(0.5 * (x**2 + y**2))) - exp(0.5 * (cos(2 * pi * x) + cos(2 * pi * y))) + e + 20

  13. # define range for input

  14. r_min, r_max = -5.0, 5.0

  15. # define the starting point as a random sample from the domain

  16. pt = r_min + rand(2) * (r_max - r_min)

  17. # perform the basin hopping search

  18. result = basinhopping(objective, pt, stepsize=0.5, niter=200)

  19. # summarize the result

  20. print('Status : %s' % result['message'])

  21. print('Total Evaluations: %d' % result['nfev'])

  22. # evaluate solution

  23. solution = result['x']

  24. evaluation = objective(solution)

  25. print('Solution: f(%s) = %.5f' % (solution, evaluation))

运行示例将执行优化,然后报告结果。

注意:由于算法或评估程序的随机性,或者数值精度的不同,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。

在这种情况下,我们可以看到该算法将最优值定位为非常接近零的输入,并且目标函数的评估值实际上为零。我们可以看到,该算法的200次迭代产生了86,020个函数求值。

  1. Status: ['requested number of basinhopping iterations completed successfully']

  2. Total Evaluations: 86020

  3. Solution: f([ 5.29778873e-10 -2.29022817e-10]) = 0.00000

具有多个全局最优的多峰优化

Himmelblau函数是具有多个全局最优值的目标函数的示例。

具体来说,它具有四个最优值,并且每个都有相同的目标函数评估。这是一个二维目标函数,其全局最佳值分别为[3.0,2.0],[-2.805118、3.113112],[-3.779310,-3.283186],[3.584428,-1.848126]。这意味着全局优化算法的每次运行都可能找到不同的全局最优值。下面的示例实现了Himmelblau并创建了一个三维表面图,以直观地说明目标函数。

  1. # himmelblau multimodal test function

  2. from numpy import arange

  3. from numpy import meshgrid

  4. from matplotlib import pyplot

  5. from mpl_toolkits.mplot3d import Axes3D

  6. # objective function

  7. def objective(x, y):

  8. return (x**2 + y - 11)**2 + (x + y**2 -7)**2

  9. # define range for input

  10. r_min, r_max = -5.0, 5.0

  11. # sample input range uniformly at 0.1 increments

  12. xaxis = arange(r_min, r_max, 0.1)

  13. yaxis = arange(r_min, r_max, 0.1)

  14. # create a mesh from the axis

  15. x, y = meshgrid(xaxis, yaxis)

  16. # compute targets

  17. results = objective(x, y)

  18. # create a surface plot with the jet color scheme

  19. figure = pyplot.figure()

  20. axis = figure.gca(projection='3d')

  21. axis.plot_surface(x, y, results, cmap='jet')

  22. # show the plot

  23. pyplot.show()

运行示例将创建Himmelblau函数的表面图,该图将四个全局最优值显示为深蓝色盆地。

我们可以将盆地跳跃算法应用于Himmelblau目标函数。

与前面的示例一样,我们将使用从-5到5之间的输入域绘制的随机点开始搜索。

我们将使用0.5的步长,200次迭代和默认的本地搜索算法。搜索结束时,我们将报告最佳位置的最佳输入。

  1. # basin hopping global optimization for the himmelblau multimodal objective function

  2. from scipy.optimize import basinhopping

  3. from numpy.random import rand

  4. # objective function

  5. def objective(v):

  6. x, y = v

  7. return (x**2 + y - 11)**2 + (x + y**2 -7)**2

  8. # define range for input

  9. r_min, r_max = -5.0, 5.0

  10. # define the starting point as a random sample from the domain

  11. pt = r_min + rand(2) * (r_max - r_min)

  12. # perform the basin hopping search

  13. result = basinhopping(objective, pt, stepsize=0.5, niter=200)

  14. # summarize the result

  15. print('Status : %s' % result['message'])

  16. print('Total Evaluations: %d' % result['nfev'])

  17. # evaluate solution

  18. solution = result['x']

  19. evaluation = objective(solution)

  20. print('Solution: f(%s) = %.5f' % (solution, evaluation))

运行示例将执行优化,然后报告结果。

在这种情况下,我们可以看到该算法在[3.0,2.0]处确定了一个最佳值。

我们可以看到,该算法的200次迭代产生了7,660个函数评估。

  1. Status : ['requested number of basinhopping iterations completed successfully']

  2. Total Evaluations: 7660

  3. Solution: f([3. 1.99999999]) = 0.00000

如果我们再次运行搜索,则可能期望找到其他全局最优值。

例如,下面,我们可以看到一个最佳值位于[-2.805118,3.131312]处,与之前的运行不同。

  1. Status : ['requested number of basinhopping iterations completed successfully']

  2. Total Evaluations: 7636

  3. Solution: f([-2.80511809 3.13131252]) = 0.00000

作者:沂水寒城,CSDN博客专家,个人研究方向:机器学习、深度学习、NLP、CV
(0)

相关推荐

  • 【优秀作业】粒子群优化算法

    粒子群优化算法 一.概述 粒子群优化算法(Particle Swarm Optimization,PSO)的思想来源于对鸟捕食行为的模仿,最初,Reynolds.Heppner 等科学家研究的是鸟类飞 ...

  • ICML2019论文 | 炼丹?找到神经网络的全局最优解

    训练好神经网络是个老大难问题.其中一个难点,就在调参以使训练数据上的损失(loss)收敛.领域中流传有各类调参技巧.然而,很多技巧并无理论支持,时灵时不灵,以致调参被称为炼丹,是成不成全靠天的玄学.这 ...

  • 梯度下降法的三种形式BGD、SGD以及MBGD

    阅读目录 1. 批量梯度下降法BGD 2. 随机梯度下降法SGD 3. 小批量梯度下降法MBGD 4. 总结 在应用机器学习算法时,我们通常采用梯度下降法来对采用的算法进行训练.其实,常用的梯度下降法 ...

  • 【学术论文】基于蝴蝶优化的粒子滤波算法

    摘要: 针对标准粒子滤波采用次优的重要性函数而导致的粒子退化问题,提出一种基于蝴蝶优化的改进粒子滤波算法.通过蝴蝶算法优化粒子滤波的重要性采样过程,使得远离真实状态的粒子向真实状态可能性较大的区域移动 ...

  • 瞎扯最优化【算法大神力作】

    图:十二少摄于某山洞 前言:这篇是跟算法大神"不如再见"的约稿,相当不容易约到啊,因为大神很忙,百忙之中还能按时履约,真是非常不容易,还用visio画了插图,这认真负责的态度,真是 ...

  • 无人机航迹规划常用算法综述

    王 琼1a,1b, 刘美万1a,1b, 任伟建1a,1b, 王天任2 (1. 东北石油大学 a. 电气信息工程学院; b. 黑龙江省网络化与智能控制重点实验室, 黑龙江 大庆 163318;2. 中国 ...

  • 模拟退火算法超详细教程,请收好!

    预计读完 5 分钟 今天,小编将带大家学习一个经典算法--模拟退火算法. 前排提醒,本文全程干货,建议收藏. 以下为本文框架: 一.什么是模拟退火算法? 模拟退火算法(simulated anneal ...

  • Python 中的函数装饰器和闭包

    函数装饰器可以被用于增强方法的某些行为,如果想自己实现装饰器,则必须了解闭包的概念. 装饰器的基本概念 装饰器是一个可调用对象,它的参数是另一个函数,称为被装饰函数.装饰器可以修改这个函数再将其返回, ...

  • 【回到写生】光影中的欢腾跳跃——管朴学新作

    <紫丁香>100x100cm 2021 <谷雨>130x100cm  2021年 <杏花云腿>80x60cm  2021年 <杏花面具>80x80cm ...

  • Python中tuple和list的区别?基础学习!

    想必大家都知道,Python数据类型有很多种,其中有两个对象的写法非常相似,它就是tuple元组和list列表,让人傻傻分不清楚.那么你知道Python中tuple和list有什么区别吗?我们来看看具 ...

  • Python中缩进是什么?入门分享!

    众所周知,Python是一门独特的编程语言,它语法清晰.简单易学,而且Python是通过缩进来识别代码块的,因为一般的语言都是通过{}或者end来作为代码块标记. Python中缩进是什么? 要求严格 ...

  • python中的内置函数

    前言 本人只在csdn写博客 内置函数 介绍 一. 数学运算 abs()求绝对值函数 round() 近似取值 pow()求指数 divmod()求商和余数 max()求最大值和min()求最小值 s ...

  • 【Python核心编程笔记】一、Python中一切皆对象

    Python中一切皆对象 本章节首先对比静态语言以及动态语言,然后介绍 python 中最底层也是面向对象最重要的几个概念-object.type和class之间的关系,以此来引出在python如何做 ...

  • 【青少年编程】Python中的分号

    今天有小朋友问我以下的选择题: 关于Python赋值语句,以下选项中不合法的是() A. x = (y=1) B. x, y = y, x C. x = y = 1 D. x = 1; y = 1 这 ...

  • 关于python中if __name__ == '__main__':的理解

    调试代码的时候都会写上if __name__ == '__main__':,然后写上数据进行调试,一直没有理解到这句的含义,就照搬着写,到现在才算理解到,大概说下自己的见解. 1.在python里__ ...

  • 彻底搞懂Python 中的 import 与 from import

    对不少 Python 初学者来说,Python 导入其他模块的方式让他们很难理解.什么时候用import xxx?什么时候用from xxx import yyy?什么时候用from xxx.yyy ...