文档章节

鱼群算法

Brillou
 Brillou
发布于 2017/04/09 11:32
字数 1442
阅读 85
收藏 1

 

本算法是参照李晓磊博士的论文实现的,详细的算法原理可阅读《一种新型的智能优化方法_人工鱼群算法_李晓磊》

算法基于鱼群的生存行为:在一片水域中,鱼存在的数目最多的地方就是本水域中富含营养物质最多的地方,依据这一特点来模仿鱼群的觅食,聚群,追尾等行为,从而实现全局最优,这就是鱼群算法的基本思想。

鱼类的活动中,觅食行为,聚群行为,追尾行为和随机行为与寻优命题的解决有较密切的关系,如何利用简单有效的方式来构造实现这些行为将是算法实现的主要问题。

行为模式

  • 觅食行为(AF-prey):指鱼循着食物多的方向游动的一种行为,人工鱼Xi在其视野内随机选择一个状态Xj,分别计算它们的目标函数值进行比较,如果发现Yj比Yi优,则Xi向Xj的方向移动一步;否则,Xi继续在其视野内选择状态Xj,判断是否满足前进条件,反复尝试trynumber次后,仍没有满足前进条件,则随机移动一步使Xi到达一个新的状态。
  • 聚群行为(AF-swarm):鱼在游动过程中为了保证自身的生存和躲避危害会自然地聚集成群 。鱼聚群时所遵守的规则有三条:分隔规则:尽量避免与临近伙伴过于拥挤;对准规则:尽量与临近伙伴的平均方向一致;内聚规则:尽量朝临近伙伴的中心移动。 人工鱼Xi搜索其视野内的伙伴数目nf及中心位置Xc,若Yc/ nf  > δYi,表明伙伴中心位置状态较优且不太拥挤,则Xi朝伙伴的中心位置移动一步,否则执行觅食行为。
  • 追尾行为(AF-follow):指鱼向其可视区域内的最优方向移动的一种行为。人工鱼Xi搜索其视野内所有伙伴中的函数最优伙伴Xj,如果Yj/nf> δYi,表明最优伙伴的周围不太拥挤,则Xi朝Xj移动一步,否则执行觅食行为。

PS:公告板,是记录最优人工鱼个体状态的地方。每条人工鱼在执行完一次迭代后将自身当前状态与公告板中记录的状态进行比较,如果优于公告板中的状态则用自身状态更新公告板中的状态,否则公告板的状态不变。当整个算法的迭代结束后,输出公告板的值,就是我们所求的最优值。

模拟仿真:

参数设定:

初始鱼群数量N=20,移动步长AF_step=2.5,感知距离AF_visual=0.3 ,最大尝试次数try_number=50 ,拥挤度因子delta=0.618

(食物浓度)目标函数: sin(x)*sin(y)/(x*y)

编程语言:Python

绘图工具:matplotlib

 

AF.py

from __future__ import division
from random import uniform,random
from math import pi,sin,cos,sqrt


def Y(fish_pos):
    return sin(fish_pos[0])*sin(fish_pos[1])/(fish_pos[0]*fish_pos[1])

def distance(x , y):
    return sqrt((x[0]-y[0])**2+(x[1]-y[1])**2)

class AF():
    def __init__(self, AF_X, AF_step, AF_visual, try_number,delta):
        self.AF_step = AF_step
        self.AF_visual = AF_visual
        self.try_number = try_number
        self.AF_X = AF_X
        self.delta = delta
        self.forumboard = None    #定义公告板

    #定义觅食行为
    def AF_prey(self, fish_pos):
        for i in range(self.try_number):
            randangle = uniform(0, 2 * pi)
            randlength = uniform(0, self.AF_visual)
            tempa, tempb = fish_pos[0] + cos(randangle) * randlength, fish_pos[1] + sin(randangle) * randlength
            if Y((fish_pos[0], fish_pos[1])) < Y((tempa, tempb)):
                r = random()
                fish_pos = (fish_pos[0] + r * cos(randangle) * self.AF_step,
                                fish_pos[1] + r * sin(randangle) * self.AF_step)
                return fish_pos
            else:
                fish_pos = self.AF_move(fish_pos)
                return fish_pos

    #定义聚群行为
    def AF_swarm(self, fish_pos):
        nf = 0
        AF_XC = (0, 0)
        for j in range(len(self.AF_X)):
            if distance(fish_pos, self.AF_X[j]) < self.AF_visual:
                nf += 1
                AF_XC = (AF_XC[0] + self.AF_X[j][0], AF_XC[1] + self.AF_X[j][1])
        AF_XC = (AF_XC[0] / nf, AF_XC[1] / nf)
        if distance(fish_pos, AF_XC) != 0 and (Y(AF_XC) / nf) > (self.delta * Y(fish_pos)):
            r = random()
            fish_pos = ((AF_XC[0] + fish_pos[0]) * (r * self.AF_step / distance(fish_pos, AF_XC)),
                            (AF_XC[1] + fish_pos[1]) * (r * self.AF_step / distance(fish_pos, AF_XC)))
            return fish_pos
        else:
            fish_pos = self.AF_prey(fish_pos)
            return fish_pos

    #定义追尾行为
    def AF_follow(self,fish_pos):
        dis_dic= {}
        nf = 0
        dis_dic[fish_pos] = Y(fish_pos)
        for j in range(len(self.AF_X)):
            if distance(fish_pos, self.AF_X[j]) < self.AF_visual:
                dis_dic[self.AF_X[j]] = Y(self.AF_X[j])
                nf += 1
        max_Element = max(dis_dic.items(), key=lambda x: x[1])
        max_X = max_Element[0]
        #更新公告板
        if self.forumboard == None:
            self.forumboard = max_Element[1]
        self.forumboard = self.forumboard if self.forumboard > max_Element[1] else max_Element[1]
        print(self.forumboard)

        if Y(max_X) / nf > self.delta * Y(fish_pos) and distance(fish_pos, max_X) != 0:
            r = random()
            fish_pos = ((max_X[0] + fish_pos[0]) * (r * self.AF_step / distance(fish_pos, max_X)),
                            (max_X[1] + fish_pos[1]) * (r * self.AF_step / distance(fish_pos, max_X)))
            return fish_pos
        else:
            fish_pos = self.AF_prey(fish_pos)
            return fish_pos

    #定义随机行为
    def AF_move(self, fish_pos):
        randangle = uniform(0,2*pi)
        fish_pos = (fish_pos[0] + cos(randangle)*self.AF_step, fish_pos[1] + sin(randangle)*self.AF_step)
        return fish_pos

主函数

import random
from AF import AF
import numpy as np
import matplotlib.pyplot as plt

#定义随机生成number个点
def randpoint(number):
    init = []
    for i in range(number):
        a = random.uniform(-10, 10)
        b = random.uniform(-10, 10)
        init.append((a, b))
    return init

init1 = randpoint(20)
init2 = init1[:]
init3 = init1[:]

af1 = AF(init1,AF_step=2.5, AF_visual=0.3, try_number=50, delta=0.618)
af2 = AF(init2,AF_step=2.5, AF_visual=0.3, try_number=50, delta=0.618)
af3 = AF(init3,AF_step=2.5, AF_visual=0.3, try_number=50, delta=0.618)


optimum = []
iteration = []

for i in range(20):
    for j in range(len(init1)):
        init1[j]=af1.AF_swarm(init1[j])
        init1[j]=af1.AF_follow(init1[j])

for i in range(50):
    for j in range(len(init2)):
        init2[j]=af2.AF_swarm(init2[j])
        init2[j]=af2.AF_follow(init2[j])

for i in range(100):
    for j in range(len(init3)):
        init3[j]=af3.AF_swarm(init3[j])
        init3[j]=af3.AF_follow(init3[j])
    optimum.append(af3.forumboard)
    iteration.append(i)

x1 = [i[0] for i in init1]
y1 = [i[1] for i in init1]

x2 = [i[0] for i in init2]
y2 = [i[1] for i in init2]

x3 = [i[0] for i in init3]
y3 = [i[1] for i in init3]

fig = plt.figure()
ax1 = fig.add_subplot(221)
ax1.scatter(x1,y1)
ax1.set_xlabel("迭代20次")
ax2 = fig.add_subplot(222)
ax2.scatter(x2,y2)
ax2.set_xlabel("迭代50次")
ax3 = fig.add_subplot(223)
ax3.scatter(x3, y3)
ax3.set_xlabel("迭代100次")
ax4 = fig.add_subplot(224)
ax4.plot(iteration, optimum)
ax4.set_xlabel("迭代100次时的最优解")
plt.show()

分别迭代20次,50次,100次的情况:

以上结果表明:在(0,0)时目标函数取得最大值为1

© 著作权归作者所有

Brillou
粉丝 1
博文 1
码字总数 1442
作品 0
杭州
私信 提问
北京大学工学院教授谢广明-智能仿生机器鱼 | CCF-GAIR 2018

雷锋网 AI 科技评论按:2018 年 6 月 29 日至 7 月 1 日全球人工智能与机器人峰会(CCF-GAIR)在深圳召开,峰会由中国计算机学会(CCF)主办,雷锋网(公众号:雷锋网) (公众号:雷锋网)、香港...

sanman
2018/07/16
0
0
python粒子群算法的实现

参考博客: http://blog.csdn.net/zuochao_2013/article/details/53431767?ref=myread http://blog.csdn.net/chen_jp/article/details/7947059 算法介绍 粒子群算法(particle swarm optimiz......

winycg
2018/01/21
0
0
麻省理工学院研发出鱼形机器人,不仅用于通讯,还可保护海下鱼群

  近日,一如下图所示的奇特鱼种在游曳于珊瑚礁时被发现,它通体白色,游动姿势和速率与普通鱼类无异,不过此前并无关于它的观测记录。      图 | 一条罕见的鱼   好了,关子就卖到这...

DeepTech深科技
2018/03/26
0
0
以大自然为师,可上天入地的11款仿生机器人

来源:资本实验室 尽管人类已经借助科技的力量改造了世界,但许多技能仍然为人类所不拥有,很多恶劣的环境仍然是人类的禁区。而经过大自然的“公平选择”,使得某些生物具有我们所不具备的独...

cf2suds8x8f0v
2018/05/12
0
0
C语言实现粒子群算法(PSO)一

最近在温习C语言,看的书是《C primer Plus》,忽然想起来以前在参加数学建模的时候,用过的一些智能算法,比如遗传算法、粒子群算法、蚁群算法等等。当时是使用MATLAB来实现的,而且有些MAT...

lyrichu
2016/12/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java FOR-EACH循环

FOR-EACH循环使得代码更加的简短,也让代码更加易懂,其实他并没有加入什么新的功能。他的功能完全可以用简单的FOR循环代替。 for-each的用法: int a[] = {1,2,3,4,5,6} for(int s:a){ Syst...

无名氏的程序员
28分钟前
3
0
使用HTML5的History API

本文转载于:专业的前端网站➣使用HTML5的History API   HTML5 History API提供了一种功能,能让开发人员在不刷新整个页面的情况下修改站点的URL。这个功能很有用,例如通过一段JavaScript代...

前端老手
31分钟前
4
0
JAVA 编写redisUtils工具类,防止高并发获取缓存出现并发问题

import lombok.extern.slf4j.Slf4j;import org.springframework.data.redis.core.BoundHashOperations;import org.springframework.data.redis.core.BoundValueOperations;import org.......

huangkejie
今天
7
0
JMM内存模型(一)&volatile关键字的可见性

在说这个之前,我想先说一下计算机的内存模型: CPU在执行的时候,肯定要有数据,而数据在内存中放着呢,这里的内存就是计算机的物理内存,刚开始还好,但是随着技术的发展,CPU处理的速度越...

走向人生巅峰的大路
今天
101
0
你对AJAX认知有多少(2)?

接着昨日内容,我们几天继续探讨ajax的相关知识点 提到ajax下面几个问题又是必须要了解的啦~~~ 8、在浏览器端如何得到服务器端响应的XML数据。 通过XMLHttpRequest对象的responseXMl属性 9、 ...

理性思考
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部