在網上搜尋沒有發現比較完整用Python寫的CS算法,隻能自己動手編寫一個。
CS算法注意事項:
1.執行流程是,初始化 -> levy飛行變換巢穴位置 -> 與之前的巢穴對比保留好的巢穴 -> 按照發現機率值丢棄部分巢穴重新生成 ->
-> 再與之前的巢穴對比保留好的巢穴 ->判斷循環是否結束 -> ............
2.levy飛行步長的計算通常是使用Mantegna方法模拟二維平面萊維飛行
3.疊代公式中大量涉及随機數,需要注意的是一部分是服從均勻分布,還有部分是服從正态分布
4.編寫可以參照yang的matlab代碼源代碼(參考的連結中包含源代碼)
Python代碼如下:
公式就不寫了,可以參考連結。
from random import uniform
from random import randint
import math
import numpy as np
import matplotlib.pyplot as plt
'''
根據levy飛行計算新的巢穴位置
'''
def GetNewNestViaLevy(Xt,Xbest,Lb,Ub,lamuda):
beta = 1.5
sigma_u = (math.gamma(1 + beta) * math.sin(math.pi * beta / 2) / (
math.gamma((1 + beta) / 2) * beta * (2 ** ((beta - 1) / 2)))) ** (1 / beta)
sigma_v = 1
for i in range(Xt.shape[0]):
s = Xt[i,:]
u = np.random.normal(0, sigma_u, 1)
v = np.random.normal(0, sigma_v, 1)
Ls = u / ((abs(v)) ** (1 / beta))
stepsize = lamuda*Ls*(s-Xbest) #lamuda的設定關系到點的活力程度 方向是由最佳位置确定的 有點類似PSO算法 但是步長不一樣
s = s + stepsize * np.random.randn(1, len(s)) #産生滿足正态分布的序列
Xt[i, :] = s
Xt[i,:] = simplebounds(s,Lb,Ub)
return Xt
'''
按pa抛棄部分巢穴
'''
def empty_nests(nest,Lb,Ub,pa):
n = nest.shape[0]
nest1 = nest.copy()
nest2 = nest.copy()
rand_m =pa - np.random.rand(n,nest.shape[1])
rand_m = np.heaviside(rand_m,0)
np.random.shuffle(nest1)
np.random.shuffle(nest2)
# stepsize = np.random.rand(1,1) * (nest1 - nest)
stepsize = np.random.rand(1,1) * (nest1 - nest2)
new_nest = nest + stepsize * rand_m
nest = simplebounds(new_nest,Lb,Ub)
return nest
'''
獲得目前最優解
'''
def get_best_nest(nest, newnest,Nbest,nest_best):
fitall = 0
for i in range (nest.shape[0]):
temp1 = fitness(nest[i,:])
temp2 = fitness(newnest[i,:])
if temp1 > temp2:
nest[i, :] = newnest[i,:]
if temp2 < Nbest :
Nbest = temp2
nest_best = nest[i,:]
fitall = fitall + temp2
else:
fitall = fitall + temp1
meanfit = fitall/nest.shape[0]
return nest , Nbest , nest_best ,meanfit
'''
進行适應度計算
'''
def fitness(nest_n):
X = nest_n[0]
Y = nest_n[1]
# rastrigin函數
A = 10
Z = 2 * A + X ** 2 - A * np.cos(2 * np.pi * X) + Y ** 2 - A * np.cos(2 * np.pi * Y)
return Z
'''
進行全部适應度計算
'''
def fit_function(X,Y):
# rastrigin函數
A = 10
Z = 2 * A + X ** 2 - A * np.cos(2 * np.pi * X) + Y ** 2 - A * np.cos(2 * np.pi * Y)
return Z
'''
限制疊代結果
'''
def simplebounds(s,Lb,Ub):
for i in range(s.shape[0]):
for j in range(s.shape[1]):
if s[i][j] < Lb[j]:
s[i][j] = Lb[j]
if s[i][j] > Ub[j]:
s[i][j] = Ub[j]
return s
def Get_CS(lamuda = 1,pa =0.25):
Lb=[-5,-5] #下界
Ub=[5,5] #上界
population_size = 20
dim = 2
nest= np.random.uniform(Lb[0], Ub[0],(population_size,dim)) # 初始化位置
nest_best = nest[0,:]
Nbest =fitness(nest_best)
nest ,Nbest, nest_best ,fitmean = get_best_nest(nest,nest,Nbest,nest_best)
for i in range (30):
nest_c = nest.copy()
newnest = GetNewNestViaLevy(nest_c, nest_best, Lb, Ub,lamuda) # 根據萊維飛行産生新的位置
nest,Nbest, nest_best ,fitmean = get_best_nest(nest, newnest,Nbest, nest_best) # 判斷新的位置優劣進行替換
nest_e = nest.copy()
newnest = empty_nests(nest_e,Lb,Ub,pa) #丢棄部分巢穴
nest,Nbest, nest_best ,fitmean = get_best_nest(nest,newnest, Nbest, nest_best) # 再次判斷新的位置優劣進行替換
print("最優解的适應度函數值",Nbest)
return Nbest
Get_CS()
代碼如果需要使用的話,建議仔細檢查,雖然我檢查沒有發現問題。有不對的地方歡迎指正。
參考:
https://blog.csdn.net/zyqblog/article/details/80905019
https://vlight.me/2017/12/17/Cuckoo-Search/
文獻:動态适應布谷鳥搜尋算法 《控制與政策》 2014年