人工鱼群算法及其python实现过程
得益于仿生學(xué)的研究和發(fā)展,群智能優(yōu)化領(lǐng)域近年來衍生出了多種細化的方法,包括遺傳算法、粒子群優(yōu)化算法(附代碼)、雜草算法(附代碼)、果蠅算法以及人工魚群算法。其中,李曉磊博士于2003年提出的魚群算法具有避免最優(yōu)解提前收斂即能夠跳出局部最優(yōu)解而尋求全局最優(yōu)解的優(yōu)點。
0 自然界中的魚群特征
捕食行為:魚向著生存環(huán)境中富集度高的地方游去并捕食。
追尾行為:魚A能夠察覺視線范圍內(nèi)魚B所處的富集度最高,若魚B周圍不太擁擠,那么魚A朝著魚B游去。
聚群行為:魚找到視線范圍內(nèi)所有的魚,并能夠衡量這些魚的中間位置,如果這個中間位置不是很擁擠,那么魚朝著中間位置游去
隨機行為:魚在當(dāng)前環(huán)境中隨機游動
1 人工魚群算法
1.0 初始化魚群及算法參數(shù)
div-----------------解的自變量個數(shù)。 e.g: div = 3 --> X = x1, x2, x3
number----------自變量向量?
visual-------------魚群視覺范圍
step---------------魚移動一步的最大步長
try_time----------魚進行捕食行為時搜索周圍環(huán)境更優(yōu)解的次數(shù)
delta--------------擁擠程度,[0, 1),影響追尾和聚群
tag----------------公告牌,記錄每次循環(huán)過后,目標函數(shù)的最優(yōu)值
1.1 進入循環(huán),魚群中的魚分別進行如下操作:(偽代碼如下)
捕食行為
def prey()pre_score = fish.func() # 原來fish的目標函數(shù)值for(i in 0 : try_time) newfish = new Fish(rnorm(fish.number, sigma)) # 以fish為中心生成新的new_fishif(newfish.func() > pre_score) # 產(chǎn)生了更優(yōu)解fish = new_fish追尾行為
def follow()fo = 魚fish視線范圍內(nèi)所有魚的集合best_fish = fo集合中目標函數(shù)值最高的魚if(best_fish周圍擁擠)執(zhí)行其他操作,如捕食行為、隨機行為elsefish向best_fish移動,最大移動距離為step聚群行為
def swarm()sw = 魚fish視線范圍內(nèi)所有魚的集合center_fish = sw的中心位置if(center_fish周圍擁擠)執(zhí)行其他行為,如隨機操作、捕食操作elsefish向center_fish移動,最大移動step長隨機行為
def rand()以當(dāng)前fish位置為中心,隨機向四周移動,每個維度上最多移動step長2 python實現(xiàn)過程
import math import matplotlib.pyplot as plt import numpymy_flag = 1 # my_flag == 0 計算第一個函數(shù)最大值 # my_flag == 1 計算第二個函數(shù)最大值class fish:def __init__(self, div, number, visual, step, try_time, delta):# 初始化self.div = divself.number = numberself.visual = visualself.step = stepself.try_time = try_timeself.delta = deltadef distance(self, f):# 計算self魚和f魚之間的距離ll = len(self.number)res = 0.0for i in range(ll):res = res + (self.number[i] - f.number[i]) * (self.number[i] - f.number[i])return math.sqrt(res)def func(self, flag):# 計算魚在當(dāng)前位置的函數(shù)ll = len(self.number)if flag == 0:res = 0for i in range(ll):res = res + self.number[i] * self.number[i]return 500-reselse:res = 0mul = 1for i in range(ll):res = res + math.fabs(self.number[i])mul = mul * math.fabs(self.number[i])return 500-(res + mul)def prey(self):# 捕食操作pre = self.func(my_flag)for i in range(self.try_time):rand = numpy.random.randint(-99, 99, self.div) / 100 * self.visualfor j in range(self.div):self.number[j] = self.number[j] + rand[j]cur = self.func(my_flag)if cur > pre:# 捕食成功# print('原始分數(shù):' + str(pre) + '新分數(shù):' + str(cur) + '捕食成功!!')return curelse:# 捕食失敗for j in range(self.div):self.number[j] = self.number[j] - rand[j]# print("捕食失敗!")return predef swarm(self, fishes):# 聚群行為:向視覺內(nèi)魚群中心前進stepclose_swarm = find_close_swarm(fishes, self)center_f = center_fish(close_swarm)n = len(close_swarm) - 1if n != 0 and (center_f.func(my_flag) / n > self.delta * self.func(my_flag)):# print("聚群運動")for i in range(self.div):self.number[i] = self.number[i] + self.step * center_f.number[i]return self.func(my_flag)else:# print("隨機運動")return self.rand()def rand(self):for i in range(self.div):self.number[i] = self.number[i] + self.step * numpy.random.uniform(-1, 1, 1)def follow(self, fishes):# 追尾行為:向著視覺內(nèi)魚群中目標函數(shù)值最優(yōu)的魚前進stepclose_swarm = find_close_swarm(fishes, self)best_f = best_fish(close_swarm)n = len(close_swarm) - 1if n != 0 and (best_f.func(my_flag) / n > self.delta * self.func(my_flag)):# 向前移動# print("向前移動")for i in range(self.div):self.number[i] = self.number[i] + self.step * (best_f.number[i] - self.number[i])return self.func(my_flag)else:# 隨機運動# print("隨機運動")return self.rand()def find_close_swarm(fishes, fish_):# 在種群fishes中查找fish_視覺范圍內(nèi)的魚# 輸入為fishes,是一個list型變量 和一個fish對象# 輸出為一個fish listres = []for fi in fishes:if fish_.distance(fi) < fish_.visual:res.append(fi)return resdef center_fish(fishes):# 計算當(dāng)前種群的中心位置,并將其中心位置記為certer_fish以完成聚群操作# 輸入為fishes,是一個list型變量# 輸出為一個fish對象ll = len(fishes)if ll == 0 or ll == 1:return Noneres = fish(fishes[0].div, fishes[0].number, fishes[0].visual, fishes[0].step, fishes[0].try_time, fishes[0].delta)for i in range(fishes[0].div):res.number[i] = 0for i in range(ll):for j in range(res.div):res.number[j] = res.number[j] + fishes[i].number[j]return resdef best_fish(fishes):# 計算當(dāng)前種群最優(yōu)個體的位置,并將其返回用于追尾操作# 輸入為fishes,是一個list型變量# 輸出為一個fish對象ll = len(fishes)if ll == 0 or ll == 1:return Noneindex = -1max = 0for i in range(ll):if index == -1 or max < fishes[i].func(my_flag):index = imax = fishes[i].func(my_flag)return fishes[index]def main(): # 主函數(shù)fishes = []div = 3 # xi中i的大小,e.g. div == 3 --> x1, x2, x3fish_num = 50 # 魚群個體數(shù)目gmax = 100 # 循環(huán)最大次數(shù)tag = 0 # 公告牌visual = 1step = 0.2try_time = 10delta = 0.3list_of_fishes = []# 初始化魚群for i in range(fish_num):num = numpy.random.uniform(10, 20, div)fi = fish(div, num, visual, step, try_time, delta)fishes.append(fi)for i in range(fish_num):list_of_fishes.append([])for g in range(gmax):for i in range(fish_num):if fishes[i].func(my_flag) > tag:tag = fishes[i].func(my_flag)# print(g, tag)for i in range(fish_num):if g >= 50:list_of_fishes[i].append(fishes[i].func(my_flag))for i in range(fish_num):if tag == fishes[i].func(my_flag):fishes[i].prey()continuetmp = numpy.random.randint(0, 3, 1)if tmp == 0:fishes[i].swarm(fishes)elif tmp == 1:fishes[i].follow(fishes)else:fishes[i].prey()print(tag)x = [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, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]# print(x)for i in range(fish_num):# print(list_of_fishes[i][49] < 0.5)if math.fabs(list_of_fishes[i][49] - 500) < 20:plt.plot(x, list_of_fishes[i], color='orangered', marker='o', linestyle='-', label='A')else:plt.plot(x, list_of_fishes[i], color='green', marker='*', linestyle=':', label='C')plt.ylim(20, 50)plt.ylim(-500, 500)plt.xlabel("Loop_time") # X軸標簽plt.ylabel("Value") # Y軸標簽plt.show()if __name__ == '__main__':main()3 結(jié)果展示
目標函數(shù)為F(X) = 500 - x1^2 - x2 ^ 2 - x3 ^2
最優(yōu)解為F(0, 0, 0) = 500 (最大值)
?
附:
其他群智能優(yōu)化算法:
粒子群優(yōu)化算法(附代碼)https://blog.csdn.net/cccddduil/article/details/123671197?spm=1001.2014.3001.5501
雜草算法(附代碼)https://blog.csdn.net/cccddduil/article/details/124843486?spm=1001.2014.3001.5502
總結(jié)
以上是生活随笔為你收集整理的人工鱼群算法及其python实现过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 服务端配置实现AJAX跨域请求
- 下一篇: python如何获取免费的可以商用的字体