1 原理
粒子群算法是群智能一種,是基于對鳥群覓食行為的研究和模擬而來的。假設在鳥群覓食范圍,只在一個地方有食物,所有鳥兒看不到食物(不知道食物的具體位置),但是能聞到食物的味道(能知道食物距離自己位置)。最好的策略就是結合自己的經驗在距離鳥群中距離食物最近的區域搜索。
利用粒子群算法解決實際問題本質上就是利用粒子群算法求解函數的最值。因此需要事先把實際問題抽象為一個數學函數,稱之為適應度函數。在粒子群算法中,每只鳥都可以看成是問題的一個解,這里我們通常把鳥稱之為粒子,每個粒子都擁有:
位置,可以理解函數的自變量的值;
經驗,也即是自身經歷過的距離食物最近的位置;
速度,可以理解為自變量的變化值;
適應度,距離食物的位置,也就是函數值。
粒子群算法的過程
PSO流程圖
初始化。包括根據給定的粒子個數,初始化粒子,包括初始化一下的值:
位置:解空間內的隨機值;
經驗:與初始位置相等;
速度:0;
適應度:根據位置,帶入適應度函數,得到適應度值。
更新。包括兩部分:
粒子自身信息:包括根據下面的公式更新粒子的速度、位置,根據適應度函數更新適應度,然后和用更新后的適應度和自身經驗進行比較,如果新的適應度由于經驗的適應度,就利用當前位置更新經驗;
速度更新公式
位置更新公式
上面公式中:i表示粒子編號;t表示時刻,反映在迭代次數上;w是慣性權重,一般設置在0.4左右;c表示學習因子,一般都取值為2;Xpbest表示的是粒子i的經驗,也即是粒子i所到過最佳位置;Xgbest代表的是全局最優粒子的位置;r是0到1之間的隨機值。
種群信息:把當前適應度和全局最優位置的適應度進行比較,如果當前適應度優于全局最優的適應度,那么久用當前粒子替換群居最優。
判斷結束條件。結束條件包括最大迭代次數和適應度的閾值。
2 代碼
實驗環境為python 2.7.11。
這個代碼最初是用于求解一維最大熵分割圖像問題的,因此是求解函數最大值,如果需要求解最小值,把代碼中的大于號全部改成小于號就可以了。
首先需要解決的是粒子的存儲,我第一反應是利用結構體來存儲,但是python并沒有相應的數據結構,所以我選擇用一個類來表示粒子結構,該類的一個對象就是一個粒子,上代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class bird: """ speed:速度 position:位置 fit:適應度 lbestposition:經歷的最佳位置 lbestfit:經歷的最佳的適應度值 """ def __init__( self , speed, position, fit, lBestPosition, lBestFit): self .speed = speed self .position = position self .fit = fit self .lBestFit = lBestPosition self .lBestPosition = lPestFit |
接下來就是粒子群算法的主干部分,用一個類來封裝,代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
import random class PSO: """ fitFunc:適應度函數 birdNum:種群規模 w:慣性權重 c1,c2:個體學習因子,社會學習因子 solutionSpace:解空間,列表類型:[最小值,最大值] """ def __init__( self , fitFunc, birdNum, w, c1, c2, solutionSpace): self .fitFunc = fitFunc self .w = w self .c1 = c1 self .c2 = c2 self .birds, self .best = self .initbirds(birdNum, solutionSpace) def initbirds( self , size, solutionSpace): birds = [] for i in range (size): position = random.uniform(solutionSpace[ 0 ], solutionSpace[ 1 ]) speed = 0 fit = self .fitFunc(position) birds.append(bird(speed, position, fit, position, fit)) best = birds[ 0 ] for bird in birds: if bird.fit > best.fit: best = bird return birds,best def updateBirds( self ): for bird in self .birds: # 更新速度 bird.speed = self .w * bird.speed + self .c1 * random.random() * (bird.lBestPosition - bird.position) + self .c2 * random.random() * ( self .best.position - bird.position) # 更新位置 bird.position = bird.position + bird.speed # 跟新適應度 bird.fit = self .fitFunc(bird.position) # 查看是否需要更新經驗最優 if bird.fit > bird.lBestFit: bird.lBestFit = bird.fit bird.lBestPosition = bird.position def solve( self , maxIter): # 只考慮了最大迭代次數,如需考慮閾值,添加判斷語句就好 for i in range (maxIter): # 更新粒子 self .updateBirds() for bird in self .birds: # 查看是否需要更新全局最優 if bird.fit > self .best.fit: self .best = bird |
有了以上代碼,只需要自定義適應度函數fitFunc就可以進行求解,但是需要注意的是只適用于求解 一維問題 。
總結
以上就是本文關于Python編程實現粒子群算法(PSO)詳解的全部內容,希望對大家有所幫助。有什么問題可以隨時留言,小編會及時回復大家的。感謝朋友們對本站的支持!
原文鏈接:http://www.jianshu.com/p/2bf2c07110e2