自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Python中的盆地跳躍(Basin Hopping)優(yōu)化

開發(fā) 后端
在本教程中,您將發(fā)現(xiàn)盆地跳躍全局優(yōu)化算法。一起來看看吧。

 [[407724]]

 Python中文社區(qū)(ID:python-china)

盆地跳躍是一種全局優(yōu)化算法。它是為解決化學(xué)物理學(xué)中的問題而開發(fā)的,盡管它是一種適用于具有多個(gè)最優(yōu)條件的非線性目標(biāo)函數(shù)的有效算法。

在本教程中,您將發(fā)現(xiàn)盆地跳躍全局優(yōu)化算法。完成本教程后,您將知道:

  •  盆地跳躍優(yōu)化是一種全局優(yōu)化,它使用隨機(jī)擾動(dòng)來跳躍盆地,并使用局部搜索算法來優(yōu)化每個(gè)盆地。
  •  如何在python中使用盆地跳躍優(yōu)化算法API。
  •  使用流域跳躍來解決具有多個(gè)最優(yōu)解的全局優(yōu)化問題的示例。

教程概述

本教程分為三個(gè)部分:他們是:

  •  盆地跳躍優(yōu)化
  •  盆地跳躍API
  •  盆地跳躍的例子 局部最優(yōu)的多峰優(yōu)化 具有多個(gè)全局最優(yōu)的多峰優(yōu)化

盆地跳躍優(yōu)化

Basin Hopping是為化學(xué)物理領(lǐng)域開發(fā)的一種全局優(yōu)化算法。局部優(yōu)化是指旨在為單變量目標(biāo)函數(shù)定位最優(yōu)值或在認(rèn)為存在最優(yōu)值的區(qū)域中運(yùn)行的優(yōu)化算法。而全局優(yōu)化算法旨在將單個(gè)全局最優(yōu)定位在潛在的多個(gè)局部(非全局)最優(yōu)之中。David Wales和Jonathan Doye在1997年的論文中描述了“盆地跳躍”,題目是“通過盆地跳躍進(jìn)行的全局優(yōu)化和包含110個(gè)原子的Lennard-Jones團(tuán)簇的最低能級結(jié)構(gòu)”。

該算法包括循環(huán)兩個(gè)步驟,一個(gè)是好的候選解的擾動(dòng),另一個(gè)是將本地搜索應(yīng)用于被擾動(dòng)的解。

擾動(dòng)允許搜索算法跳到搜索空間的新區(qū)域,并可能找到導(dǎo)致不同最優(yōu)值的新盆地,例如技術(shù)名稱中的“跳槽”。局部搜索使算法可以遍歷新盆地達(dá)到最佳狀態(tài)。新的最優(yōu)值可以作為新的隨機(jī)擾動(dòng)的基礎(chǔ),否則將被丟棄。保留新解決方案的決策是由具有“溫度”變量的隨機(jī)決策函數(shù)控制的,這與模擬退火非常相似。溫度根據(jù)算法的迭代次數(shù)進(jìn)行調(diào)整。這樣可以在高溫時(shí)在運(yùn)行的早期就接受任意解決方案,而更嚴(yán)格的策略是在低溫時(shí)在搜索的后期僅接受質(zhì)量更好的解決方案。這樣,該算法非常類似于具有不同(擾動(dòng))起始點(diǎn)的迭代局部搜索。該算法運(yùn)行指定的迭代次數(shù)或函數(shù)求值,并且可以多次運(yùn)行以提高對找到全局最優(yōu)值或找到相對好的解決方案的信心。

現(xiàn)在,我們已經(jīng)從較高的層次熟悉了基本的跳變算法,下面讓我們看一下Python中用于盆地跳變的API。

盆地跳躍API

在Python中,可以通過Basinhopping()SciPy函數(shù)來進(jìn)行盆地跳躍。   

  1. # perform the basin hopping search  
  2. result = basinhopping(objective, pt)  

另一個(gè)重要的超參數(shù)是通過“ niter”參數(shù)運(yùn)行搜索集的迭代次數(shù),默認(rèn)為100。可以將其設(shè)置為數(shù)千次迭代或更多次迭代。 

  1. # perform the basin hopping search  
  2. result = basinhopping(objective, pt, niter=10000

可以通過“步長”控制應(yīng)用于候選解的擾動(dòng)量,該“步長”定義了在問題域的邊界范圍內(nèi)施加的最大變化量。默認(rèn)情況下,將其設(shè)置為0.5,但應(yīng)在域中將其設(shè)置為合理的值,以允許搜索找到新的盆地。例如,如果搜索空間的合理范圍是-100到100,則步長為5.0或10.0個(gè)單位可能是合適的(例如,域的2.5%或5%)。 

  1. # perform the basin hopping search  
  2. result = basinhopping(objective, pt, stepsize=10.0) 

默認(rèn)情況下,使用的本地搜索算法是“ L-BFGS-B”算法??梢酝ㄟ^將“ minimizer_kwargs”參數(shù)設(shè)置為關(guān)鍵字為“ method”且值作為要使用的本地搜索算法的名稱(例如“ nelder-mead”)的目錄來更改此設(shè)置??梢允褂肧ciPy庫提供的任何本地搜索算法。 

  1. # perform the basin hopping search  
  2. result = basinhopping(objective, pt, minimizer_kwargs={'method':'nelder-mead'})  

搜索的結(jié)果是一個(gè)OptimizeResult對象,可以在其中像字典一樣訪問屬性??梢酝ㄟ^“成功”或“消息”鍵來訪問搜索的成功與否。

可以通過“ nfev”訪問功能評估的總數(shù),并且可以通過“ x”鍵訪問為搜索找到的最佳輸入。

現(xiàn)在,我們已經(jīng)熟悉了Python中的盆地跳躍API,下面我們來看一些可行的示例。

盆地跳躍的例子

在本節(jié)中,我們將研究在多模態(tài)目標(biāo)函數(shù)上使用盆地跳躍算法的一些示例。多峰目標(biāo)函數(shù)是具有多個(gè)最優(yōu)值的函數(shù),例如全局最優(yōu)值和許多局部最優(yōu)值,或者具有相同目標(biāo)函數(shù)輸出的多個(gè)全局最優(yōu)值。我們將在這兩個(gè)函數(shù)上查看流域跳躍的示例。

局部最優(yōu)的多峰優(yōu)化

Ackley函數(shù)是目標(biāo)函數(shù)的一個(gè)示例,該目標(biāo)函數(shù)具有單個(gè)全局最優(yōu)值和多個(gè)局部最優(yōu)值,可能會(huì)在其中陷入局部搜索。因此,需要全局優(yōu)化技術(shù)。這是一個(gè)二維目標(biāo)函數(shù),其全局最佳值為[0,0],其值為0.0。下面的示例實(shí)現(xiàn)了Ackley,并創(chuàng)建了一個(gè)三維表面圖,顯示了全局最優(yōu)值和多個(gè)局部最優(yōu)值。 

  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() 

運(yùn)行示例將創(chuàng)建Ackley函數(shù)的表面圖,以顯示大量的局部最優(yōu)值。

我們可以將盆地跳躍算法應(yīng)用于Ackley目標(biāo)函數(shù)。

在這種情況下,我們將使用從-5到5之間的輸入域繪制的隨機(jī)點(diǎn)開始搜索。 

  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次迭代和默認(rèn)的本地搜索算法。經(jīng)過一番嘗試和錯(cuò)誤后,才選擇此配置。 

  1. # perform the basin hopping search  
  2. result = basinhopping(objective, pt, stepsize=0.5, niter=200

搜索完成后,它將報(bào)告搜索狀態(tài),執(zhí)行的迭代次數(shù)以及通過評估發(fā)現(xiàn)的最佳結(jié)果。 

  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)) 

結(jié)合在一起,下面列出了將盆地跳躍應(yīng)用于Ackley目標(biāo)函數(shù)的完整示例。   

  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)) 

運(yùn)行示例將執(zhí)行優(yōu)化,然后報(bào)告結(jié)果。

注意:由于算法或評估程序的隨機(jī)性,或者數(shù)值精度的不同,您的結(jié)果可能會(huì)有所不同??紤]運(yùn)行該示例幾次并比較平均結(jié)果。

在這種情況下,我們可以看到該算法將最優(yōu)值定位為非常接近零的輸入,并且目標(biāo)函數(shù)的評估值實(shí)際上為零。我們可以看到,該算法的200次迭代產(chǎn)生了86,020個(gè)函數(shù)求值。 

  1. Status: ['requested number of basinhopping iterations completed successfully']  
  2.  Total Evaluations: 86020  
  3.  Solution: f([ 5.29778873e-10 -2.29022817e-10]) = 0.00000 

具有多個(gè)全局最優(yōu)的多峰優(yōu)化

Himmelblau函數(shù)是具有多個(gè)全局最優(yōu)值的目標(biāo)函數(shù)的示例。

具體來說,它具有四個(gè)最優(yōu)值,并且每個(gè)都有相同的目標(biāo)函數(shù)評估。這是一個(gè)二維目標(biāo)函數(shù),其全局最佳值分別為[3.0,2.0],[-2.805118、3.113112],[-3.779310,-3.283186],[3.584428,-1.848126]。這意味著全局優(yōu)化算法的每次運(yùn)行都可能找到不同的全局最優(yōu)值。下面的示例實(shí)現(xiàn)了Himmelblau并創(chuàng)建了一個(gè)三維表面圖,以直觀地說明目標(biāo)函數(shù)。 

  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() 

運(yùn)行示例將創(chuàng)建Himmelblau函數(shù)的表面圖,該圖將四個(gè)全局最優(yōu)值顯示為深藍(lán)色盆地。

我們可以將盆地跳躍算法應(yīng)用于Himmelblau目標(biāo)函數(shù)。

與前面的示例一樣,我們將使用從-5到5之間的輸入域繪制的隨機(jī)點(diǎn)開始搜索。

我們將使用0.5的步長,200次迭代和默認(rèn)的本地搜索算法。搜索結(jié)束時(shí),我們將報(bào)告最佳位置的最佳輸入。 

  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)) 

運(yùn)行示例將執(zhí)行優(yōu)化,然后報(bào)告結(jié)果。

在這種情況下,我們可以看到該算法在[3.0,2.0]處確定了一個(gè)最佳值。

我們可以看到,該算法的200次迭代產(chǎn)生了7,660個(gè)函數(shù)評估。 

  1. Status : ['requested number of basinhopping iterations completed successfully']  
  2.  Total Evaluations: 7660  
  3.  Solution: f([3. 1.99999999]) = 0.00000 

如果我們再次運(yùn)行搜索,則可能期望找到其他全局最優(yōu)值。

例如,下面,我們可以看到一個(gè)最佳值位于[-2.805118,3.131312]處,與之前的運(yùn)行不同。 

  1. Status : ['requested number of basinhopping iterations completed successfully']  
  2. Total Evaluations: 7636  
  3. Solution: f([-2.80511809 3.13131252]) = 0.00000  

 

責(zé)任編輯:龐桂玉 來源: Python中文社區(qū)
相關(guān)推薦

2020-01-17 18:40:38

Python游戲代碼

2009-04-15 08:54:19

Windows 7微軟操作系統(tǒng)

2024-12-05 09:02:00

Pythonif?

2021-08-03 10:24:59

數(shù)據(jù)跳躍鏈表結(jié)構(gòu)

2021-03-12 08:19:20

數(shù)組跳躍游戲

2013-03-12 10:35:06

CSS 3

2020-05-06 18:53:23

Go編程語言

2023-09-22 22:55:05

Pythonmap()

2009-08-20 15:33:03

C#跳躍語句

2025-04-16 10:19:21

Python列表推導(dǎo)式

2020-01-13 11:51:31

云計(jì)算技術(shù)混合云

2017-08-07 15:52:33

Oracleonnect by優(yōu)化

2023-06-27 08:53:05

跳躍表Redis

2020-07-07 07:34:29

RedisSDS數(shù)據(jù)結(jié)構(gòu)

2022-08-31 14:51:36

programmerDevelopmen

2017-08-08 09:45:43

Python性能優(yōu)化

2012-11-08 11:07:36

網(wǎng)絡(luò)優(yōu)化白金定律

2023-06-23 15:22:28

JettyJava

2015-09-08 14:42:17

Android性能優(yōu)化

2025-04-25 08:50:00

JavaScript代碼開發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)