Python中文社区(ID:python-china)BasinHopping是一种全局优化算法。它是为解决化学物理问题而开发的,尽管它是具有多个最优条件的非线性目标函数的有效算法。在本教程中,您将了解basinhopping全局优化算法。完成本教程后,您将了解:Basinhoppingoptimization是一种全局优化,它使用随机扰动来跳跃盆地,并使用局部搜索算法来优化每个盆地。如何在python中使用basinhopping优化算法API。使用分水岭跳跃解决具有多个最优解的全局优化问题的示例。教程概述本教程分为三个部分:它们是:BasinHoppingOptimizationBasinHoppingAPIBasinHoppingExamplesLocalOptimaMultimodalOptimizationwithMultipleGlobalOptimasMultimodalOptimizationBasinHoppingOptimizationBasinHopping是为化学物理领域开发的一种全局优化算法。局部优化是指旨在为单变量目标函数定位最优值或在认为存在最优值的区域中运行的优化算法。另一方面,全局优化算法旨在在潜在的多个局部(非全局)最优值中定位单个全局最优值。“Basinhopping”由DavidWales和JonathanDoye在他们1997年题为“GlobaloptimizationbybasinhoppingandthelowestenergylevelstructureofaLennard-Jonesclustercontaining110atoms”的论文中描述。该算法包括两个循环步骤,一个是对好的候选解进行扰动,另一个是将局部搜索应用于扰动解。扰动允许搜索算法跳到搜索空间的新区域,并可能找到导致不同最优值的新盆地,例如技术名称中的“跳槽”。局部搜索允许算法遍历新的盆地以达到最佳状态。新的最优值可以用作新的随机扰动的基础,否则这些扰动将被丢弃。保留新解决方案的决定由具有“温度”变量的随机决策函数控制,很像模拟退火。温度根据算法的迭代次数进行调整。这允许在高温运行的早期接受任意解决方案,而更严格的策略是在低温搜索的后期只接受质量更好的解决方案。这样,该算法非常类似于具有不同(扰动)起点的迭代局部搜索。该算法运行指定次数的迭代或函数评估,并且可以运行多次以增加找到全局最优解或找到相对好的解决方案的信心。现在我们已经在较高层次上熟悉了基本的跳跃算法,让我们看看Python中用于盆地跳跃的API。BasinhoppingAPI在Python中,可以通过Basinhopping()SciPy函数执行basinhopping。#performthebasinhoppingsearchresult=basinhopping(objective,pt)另一个重要的超参数是通过“niter”参数运行搜索集的迭代次数,默认为100。它可以设置为数千次迭代或更多。#performthebasinhoppingsearchresult=basinhopping(objective,pt,niter=10000)应用于候选解的扰动量可以通过“步长”来控制,它定义了问题域范围内施加的最大变化量。默认情况下,该值设置为0.5,但应在域中设置为合理的值以允许搜索找到新的盆地。例如,如果搜索空间的合理范围是-100到100,则5.0或10.0单位的步长可能是合适的(例如,域的2.5%或5%)。#performthebasinhoppingsearchresult=basinhopping(objective,pt,stepsize=10.0)默认情况下,使用的局部搜索算法是“L-BFGS-B”算法。这可以通过将“minimizer_kwargs”参数设置为一个目录来更改,该目录的键为“method”,值为要使用的本地搜索算法的名称(例如“nelder-mead”)。可以使用SciPy库提供的任何本机搜索算法。#performthebasinhoppingsearchresult=basinhopping(objective,pt,minimizer_kwargs={'method':'nelder-mead'})搜索的结果是一个OptimizeResult对象,其中的属性可以像字典一样访问。可以通过“成功”或“消息”键访问搜索的成功或失败。可以通过“nfev”键访问特征评估的总数,可以通过“x”键访问为搜索找到的最佳输入。现在我们已经熟悉了Python中的basinhoppingAPI,让我们看一些工作示例。BasinHopping示例在本节中,我们将研究在多峰目标函数上使用BasinHopping算法的一些示例。多峰目标函数是具有多个最优值的函数,例如一个全局最优值和多个局部最优值,或者具有相同目标函数输出的多个全局最优值。我们将查看这两个函数的盆地跳跃示例。局部最优多峰优化Ackley函数是具有单个全局最优值和多个局部最优值的目标函数的示例,其中局部搜索可能被困住。因此,需要全局优化技术。这是一个二维目标函数,其全局最优值为[0,0],值为0.0。以下示例实现Ackley并创建显示全局最优值和多个局部最优值的3D曲面图。#ackleymultimodalfunctionfromnumpyimportarangefromnumpyimportexpfromnumpyimportsqrtfromnumpyimportcosfromnumpyimportpipfromnumpyimportmeshgridfrommatplotlibimportpyplotfrommpl_toolkits.mplot3dimportAxes3D#objectivefunctiondefobjective(x,y):return-20.0*exp(-0.2*sqrt(0.5*(x**2)*(pi**5)(pi**2)x)+cos(2*pi*y)))+e+20#definerangeforinputr_min,r_max=-5.0,5.0#sampleinputrangeuniformlyat0.1incrementsxaxis=arange(r_min,r_max,0.1)yaxis=arange(r_min,r_max,0.1)#createameshfromtheaxisx,y=meshgrid(xaxis,yaxis)#computetargetsresults=objective(x,y)#createasurfaceplotwiththejetcolorschemefigure=pyplot.figure()axis=figure.gca(projection='3d')axis.plot_surface(x,y,结果,cmap='jet')#showtheplotpyplot.show()运行示例将创建Ackley函数的曲面图以显示大量局部最优值。我们可以将basinhopping算法应用于Ackley目标函数。在这种情况下,我们将从-5到5之间的输入域中抽取的随机点开始搜索。#definethestartingpointasarandomsamplefromthedomainpt=r_min+rand(2)*(r_max-r_min)我们将使用步长0.5,200迭代和默认的本地搜索算法。此配置是经过反复试验后选择的。#performthebasinhoppingsearchresult=basinhopping(objective,pt,stepsize=0.5,niter=200)搜索完成后会报告搜索状态,执行的迭代次数,评估找到的最佳结果。#summarizetheresultprint('Status:%s'%result['message'])print('TotalEvaluations:%d'%result['nfev'])#evaluatesolutionsolution=result['x']evaluation=objective(solution)print('Solution:f(%s)=%.5f'%(solution,evaluation))组合,下面列出了将basinhopping应用于Ackley目标函数的完整示例。#basinhoppingglobaloptimizationfortheackleymultimodalobjectivefunctionfromscipy.optimizeimportbasinhoppingfromnumpy.randomimportrandfromnumpyimportsqrtfromnumpyimportcosfromnumpyimportefromnumpyimportpi#objectivefunctiondefobjective(v):x,y=vreturn-20.0*exp(-0.2*sqrt(0.5*(x**2+y**co(2)*))-exp2*pi*x)+cos(2*pi*y)))+e+20#definerangeforinputr_min,r_max=-5.0,5.0#definethestartingpointasarandomsamplefromthedomainpt=r_min+rand(2)*(r_max-r_min)#performthebasinhoppingsearchresult=basinhopping(objective,pt,stepsize=0.5,niter=200)#summarizetheresultprint('Status:%s'%result['message'])print('TotalEvaluations:%d'%result['nfev'])#evaluatesolutionsolution=result['x']evaluation=objective(solution)print('Solution:f(%s)=%.5f'%(solution,evaluation))运行示例将执行优化,然后报告结果。注意:您的结果可能会因算法或评估器中的随机性或数值精度的差异而有所不同。考虑运行该示例几次并比较平均结果。在这种情况下,我们可以看到该算法为非常接近于零的输入找到了最优值,并且目标函数的计算结果实际上为零。我们可以看到算法的200次迭代产生了86,020次函数评估。Status:['requestednumberofbasinhoppingiterationscompletedsuccessfully']TotalEvaluations:86020Solution:f([5.29778873e-10-2.29022817e-10])=0.00000MultimodaloptimizationwithmultipleglobaloptimaHimmelblau函数是一个目标函数具有多个全局最优的例子。具体来说,它有四个最优值,每个最优值对目标函数的评价相同。这是一个二维目标函数,其全局最优值为[3.0,2.0],[-2.805118,3.113112],[-3.779310,-3.283186],[3.584428,-1.848126]。这意味着全局优化算法的每次运行都可能找到不同的全局最优值。下面的示例实现了Himmelblau并创建了一个3D曲面图来直观地说明目标函数。#himmelblaummultimodaltestfunctionfromnumpyimportarangefromnumpyimportmeshgridfrommatplotlibimportpyplotfrommpl_toolkits.mplot3dimportAxes3D#objectivefunctiondefobjective(x,y):return(x**2+y-11)**2+(x+y**2-7)**2#definerange5.r_max.5sampleinputrangeuniformlyat0.1incrementsxaxis=排列(r_min,r_max,0.1)yaxis=arange(r_min,r_max,0.1)#createameshfromtheaxisx,y=meshgrid(xaxis,yaxis)#computetargetsresults=objective(x,y)#createasurfaceplotwiththejetcolorschemefigureaxis=figure.gca(projection='3d')axis.plot_surface(x,y,results,cmap='jet')#showtheplotpyplot.show()运行示例会创建Himmelblau函数的曲面图,它结合了四个全局最优值显示为深蓝色盆地。我们可以将basinhopping算法应用于Himmelblau目标函数。与前面的示例一样,我们将从输入域中-5到5之间的随机点开始搜索。我们将使用0.5的步长、200次迭代和默认的局部搜索算法。在搜索结束时,我们将报告最佳位置的最佳输入。#basinhoppingglobaloptimizationforthehimmelblaummultimodalobjectivefunctionfromscipy.optimizeimportbasinhoppingfromnumpy.randomimportrand#objectivefunctiondefobjective(v):x,y=vreturn(x**2+y-11)**2+(x+y**2-7)**2#define-mineranger_forinputr5.0,5.0#definethestartingpointasarandomsamplefromthedomainpt=r_min+rand(2)*(r_max-r_min)#performthebasinhoppingsearchresult=basinhopping(objective,pt,stepsize=0.5,niter=200)#summarizetheresultprint('Status:%s'%result['message'])print('TotalEvaluations:%d'%result['nfev'])#evaluatesolutionsolution=result['x']evaluation=objective(solution)print('Solution:f(%s)=%.5f'%(解决方案,evaluation))运行示例将执行优化,然后报告结果。在这种情况下,我们可以看到该算法已在[3.0,2.0]处确定了最佳值。我们可以看到算法的200次迭代产生了7,660次函数评估。Status:['requestednumberofbasinhoppingiterationscompletedsuccessfully']TotalEvaluations:7660Solution:f([3.1.99999999])=0.00000如果我们再次运行搜索,我们可能期望找到其他全局最优解。例如,在下面,我们可以看到最优位于[-2.805118,3.131312],这与之前的运行不同。状态:['requestednumberofbasinhoppingiterationscompletedsuccessfully']TotalEvaluations:7636Solution:f([-2.805118093.13131252])=0.00000
