文章目录

  • 蚁群算法的背景
  • 蚁群算法的思想
  • 蚁群算法的python实现实例
  • 总结

蚁群算法的背景

古有牛顿在苹果树下被苹果砸中发现万有引力,三十年前有人观察蚂蚁觅食发明蚁群算法。蚁群算法是意大利学者Dorigo、Maniezzo等人于20世纪90年代看蚂蚁觅食发明的。蹲在地上看蚂蚁,也能发明新成果,曾经的我咋就光看蚂蚁,给蚂蚁的觅食捣蛋呢。这意大利的大兄弟在看蚂蚁觅食的时候呢,发现单个蚂蚁的行为比较简单,但是蚂蚁群却能体现一些智能行为,比如蚂蚁能在不同环境中,寻找最短的从蚂蚁窝到达食物的路径。经过进一步研究发现,蚂蚁在找食物的路径会留下记号(生物学称之为“信息素”),蚂蚁群里的蚂蚁会根据这个记号,也就是信息素行走,每个蚂蚁都做记号,经过一段时间后,整个蚂蚁群就会找到一个最短的到达食物的路径了。

蚁群算法的思想

蚁群算法具体的思想是什么呢?我是一只小蚂蚁,我要去找食儿。我带上几个兄弟一起走,一起去找事儿。可是食物在哪儿呢?我们也不知。那我们分头行动随机找,记得做标记。过了很久很久之后,我找到了食物,带着食物原路返回告诉大家我找到食物了。在蚂蚁窝里,我和兄弟们分享了找食物的路线,有的长,有的短。这些食物还不够,我们继续又出发。沿着大家新的路径去搬食物。有时候我会走错路,走了弯路;有时候,我走错路,却发现一条捷径。经过一次又一次的外出搬运食物,回到蚂蚁窝,我们找到了一个最方便的路径。这就是蚁群算法的基本思想。

蚁群算法可以很好的解决旅行商问题。所谓旅行商问题,是存在一些城市,旅行商如何从某个城市出发,经过所有城市后返回出发城市的最短路径。

下面用旅行商问题来继续阐述蚁群算法。
1、首先有一组蚂蚁,也就是小蚂蚁和它的兄弟们,从某个城市出发,完成一个城市遍历的路径。
2、当某个小蚂蚁站在人生的十字路口,哦不,是城市交叉路况,那么必须要走向一个城市,如果某个城市越远,那么将更有可能先不走。比如,当小蚂蚁站在天津,有一条路上北京,有一条路去深圳,那么小蚂蚁最有可能先踏上进京之路,因为近啊。
3、当某个城市边际上的记号信息素越多,则更有可能被选中。比如在天津,如果去深圳上记号信息素多,则可能先去深圳,尽管进京之路比较短,这是其他蚂蚁兄弟的记号表示的,相信蚂蚁兄弟。
4、每次回到出发点,蚂蚁兄弟标记在路上的记号信息素会挥发。
这里有两个关键点,即下一个城市的选择和信息素的更新。

现在给出一些数字表示:
城市数量为M,蚁群规模(蚂蚁数量)m、信息素重要程度因子α、启发函数重要程度因子β,即启发式信息的相对重要程度、信息素会发银子ρ、信息素释放总量Q、最大迭代次数iter_max、迭代次数初值iter=1。

小蚂蚁现在位于城市iii,到其他城市jjj的距离为 dijd_{ij}dij​,信息素浓度为pijp_{ij}pij​,那么小蚂蚁朝哪个城市前进呢。从当前城市iii到城市jjj的概率是qij=pijα∗(1/dij)βq_{ij}=p^\alpha_{ij}*(1/d_{ij})^\betaqij​=pijα​∗(1/dij​)β。
现在小蚂蚁知道了到其他城市的概率,可是该走哪条路呢。小蚂蚁拿出勇闯天涯的雪花啤酒瓶放在地上转个圈,瓶口指向哪个城市就去哪个城市吧。这就是轮盘对赌。把每个城市的转移概率除以所有城市的转移概率之和,那就是该城市被选中的概率,然后随机一个0到1的数,该随机数落到哪个区间就被选中。现在有ABCDE四个城市可以选择,那么可以看到下图里,D城市在所有城市中占据的分量最大,则最有可能被选中。可以参考这里轮盘对赌

当小蚂蚁走完所有的城市,那就对应着一条路径。蚂蚁兄弟也有搜索路径。根据小蚂蚁和蚂蚁兄弟的探路结果,更新下蚂蚁群体对路径的认识,那就是信息素的更新。两个城市之间的信息素更新公式为
pij=ρ∗pij+Q/sump_{ij}=\rho*p_{ij}+Q/sumpij​=ρ∗pij​+Q/sum
其中sum是每个蚂蚁走过的距离之和。

蚁群算法的python实现实例

我们用python的GUI模块Tkinter来验证我们的小蚂蚁是怎么寻找最优路径的。python代码如下:

# -*- coding: utf-8 -*-
# @Time    : 2019/12/25 16:23
# @Author  : HelloWorld!
# @FileName: ant.py
# @Software: PyCharm
# @Operating System: Windows 10
# @Python.version: 3.6#城市数量为M,
# 蚁群规模(蚂蚁数量)m、
# 信息素重要程度因子α、
# 启发函数重要程度因子β,即启发式信息的相对重要程度、
# 信息素会发银子ρ、
# 信息素释放总量Q、
# 最大迭代次数iter_max、迭代次数初值iter=1。
import random
import copy
import sys
import math
import tkinter
import threading
from functools import reduce
(ALPHA,BETA,RHO,Q)=(1,2,0.5,100)
#城市数,小蚂蚁个数
(city_num,ant_num)=(50,50)
#城市坐标
distance_x = [178, 272, 176, 171, 650, 499, 267, 703, 408, 437, 491, 74, 532,416, 626, 42, 271, 359, 163, 508, 229, 576, 147, 560, 35, 714,757, 517, 64, 314, 675, 690, 391, 628, 87, 240, 705, 699, 258,428, 614, 36, 360, 482, 666, 597, 209, 201, 492, 294]
distance_y = [170, 395, 198, 151, 242, 556, 57, 401, 305, 421, 267, 105, 525,381, 244, 330, 395, 169, 141, 380, 153, 442, 528, 329, 232, 48,498, 265, 343, 120, 165, 50, 433, 63, 491, 275, 348, 222, 288,490, 213, 524, 244, 114, 104, 552, 70, 425, 227, 331]
#城市距离和初始信息素
distance_graph=[[0 for col in range(city_num)] for raw in range(city_num)]
print(distance_graph)
pheromone_graph=[[1 for col in range(city_num)] for raw in range(city_num)]#------------------小蚂蚁好多个,有灵魂,值得用一个类表示----------------------
class Ant():def __init__(self,ID):self.ID=ID #蚂蚁公民怎么能没有身份证呢。self.__clean_data()#小蚂蚁初始化出生地def __clean_data(self):self.path=[]#小蚂蚁的路径self.total_distance=0 #小蚂蚁当前路径的总距离self.move_count=0 #小蚂蚁的移动次数self.current_city=-1 #小蚂蚁的当前所在城市self.open_table_city=[True for i in range(city_num)] #标记哪个城市去过,哪个没去过;也称为禁忌表city_index=random.randint(0,city_num-1)#随机初始化出生地self.current_city=city_indexself.path.append(city_index)self.open_table_city[city_index]=Falseself.move_count=1#小蚂蚁如何选择下一个城市def __choice_next_city(self):next_city=-1select_citys_prob=[0 for i in range(city_num)]#去下一个城市的概率total_prob=0#小蚂蚁掐指一算,去下一个城市的概率for i in range(city_num):if self.open_table_city[i]: #如果下一个城市没去过,还可以去try:#选中概率:与信息素浓度呈正比,与距离呈反比select_citys_prob[i]=pow(pheromone_graph[self.current_city][i],ALPHA)*\pow(1/distance_graph[self.current_city][i],BETA)total_prob+=select_citys_prob[i]except ZeroDivisionError as e:print('Ant ID: {ID}, current city: {current}, target city: {target}'.format(ID=self.ID,current=self.current_city,target=i))sys.exit(1)#勇闯天涯啤酒瓶,轮盘对赌if total_prob>0:#产生随机概率temp_prob=random.uniform(0,total_prob)for i in range(city_num):if self.open_table_city[i]:temp_prob-=select_citys_prob[i]if temp_prob<0:next_city=ibreak#如果没有从轮盘对赌中选出,则顺序选择一个未访问城市if next_city==-1:for i in range(city_num):if self.open_table_city[i]:next_city=ibreakif next_city==-1:next_city=random.randint(0,city_num-1)while False==self.open_table_city[next_city]:next_city=random.randint(0,city_num-1)#返回下一个城市序号return next_city#计算路径总距离def __cal_total_distance(self):temp_distance=0for i in range(1,city_num):start, end =self.path[i],self.path[i-1]temp_distance+=distance_graph[start][end]#回路end=self.path[0]temp_distance+=distance_graph[start][end]self.total_distance=temp_distance#小蚂蚁移动操作def __move(self,next_city):self.path.append(next_city)self.open_table_city[next_city]=Falseself.total_distance+=distance_graph[self.current_city][next_city]self.current_city=next_cityself.move_count+=1#小蚂蚁踏上寻路之旅def search_path(self):#初始化数据self.__clean_data()#搜索路径,遍历完所有城市为止while self.move_count<city_num:next_city=self.__choice_next_city()self.__move(next_city)#计算路径总长度self.__cal_total_distance()# 搜索路径,一直到遍历完所有城市路径#------------------------------小蚂蚁来解决TSP问题--------------------------------------------------
class TSP():def __init__(self,root,width=800,height=600,n=city_num):self.root=rootself.width=widthself.height=height#城市数目self.n=n#tkinter 来画布self.canvas=tkinter.Canvas(root,width=self.width,height=self.height,bg= "#EBEBEB", xscrollincrement=1,yscrollincrement=1)self.canvas.pack(expand=tkinter.YES,fill=tkinter.BOTH)self.title("TSP蚁群算法(n:初始化 e:开始搜索 s:停止搜索 q:退出程序)")self.__r = 5self.__lock = threading.RLock()  # 线程锁self.__bindEvents()self.new()#计算城市之间的距离,欧拉距for i in range(city_num):for j in range(city_num):temp_distance = pow((distance_x[i] - distance_x[j]), 2) + pow((distance_y[i] - distance_y[j]), 2)temp_distance = pow(temp_distance, 0.5)distance_graph[i][j] = float(int(temp_distance + 0.5))# 按键响应程序def __bindEvents(self):self.root.bind("q", self.quite)  # 退出程序self.root.bind("n", self.new)  # 初始化self.root.bind("e", self.search_path)  # 开始搜索self.root.bind("s", self.stop)  # 停止搜索
# 更改标题def title(self, s):self.root.title(s)# 初始化def new(self, evt=None):# 停止线程self.__lock.acquire()self.__running = Falseself.__lock.release()self.clear()  # 清除信息self.nodes = []  # 节点坐标self.nodes2 = []  # 节点对象# 初始化城市节点for i in range(len(distance_x)):# 在画布上随机初始坐标x = distance_x[i]y = distance_y[i]self.nodes.append((x, y))# 生成节点椭圆,半径为self.__rnode = self.canvas.create_oval(x - self.__r,y - self.__r, x + self.__r, y + self.__r,fill="#ff0000",  # 填充红色outline="#000000",  # 轮廓白色tags="node",)self.nodes2.append(node)# 显示坐标self.canvas.create_text(x, y - 10,  # 使用create_text方法在坐标(302,77)处绘制文字text='(' + str(x) + ',' + str(y) + ')',  # 所绘制文字的内容fill='black'  # 所绘制文字的颜色为灰色)# 顺序连接城市# self.line(range(city_num))# 初始城市之间的距离和信息素for i in range(city_num):for j in range(city_num):pheromone_graph[i][j] = 1.0self.ants = [Ant(ID) for ID in range(ant_num)]  # 初始蚁群self.best_ant = Ant(-1)  # 初始最优解self.best_ant.total_distance = 1 << 31  # 初始最大距离self.iter = 1  # 初始化迭代次数# 将节点按order顺序连线def line(self, order):# 删除原线self.canvas.delete("line")def line2(i1, i2):p1, p2 = self.nodes[i1], self.nodes[i2]self.canvas.create_line(p1, p2, fill="#000000", tags="line")return i2# order[-1]为初始值reduce(line2, order, order[-1])# 清除画布def clear(self):for item in self.canvas.find_all():self.canvas.delete(item)# 退出程序def quite(self, evt):self.__lock.acquire()self.__running = Falseself.__lock.release()self.root.destroy()print(u"\n程序已退出...")sys.exit()# 停止搜索def stop(self, evt):self.__lock.acquire()self.__running = Falseself.__lock.release()#开始搜索,小蚂蚁开始行动# 开始搜索def search_path(self, evt=None):# 开启线程self.__lock.acquire()self.__running = Trueself.__lock.release()while self.__running:#遍历每一只蚂蚁for ant in self.ants:ant.search_path() #小蚂蚁ant完成一个路径搜索#我们的小蚂蚁是不是找到比当前最优的路径了if ant.total_distance<self.best_ant.total_distance:#更新最优self.best_ant=copy.deepcopy(ant)# 更新信息素self.__update_pheromone_gragh()print(u"迭代次数:", self.iter, u"最佳路径总距离:", int(self.best_ant.total_distance))# 连线self.line(self.best_ant.path)# 设置标题self.title("TSP蚁群算法(n:随机初始 e:开始搜索 s:停止搜索 q:退出程序) 迭代次数: %d" % self.iter)# 更新画布self.canvas.update()self.iter += 1# 更新信息素def __update_pheromone_gragh(self):# 获取每只蚂蚁在其路径上留下的信息素temp_pheromone = [[0.0 for col in range(city_num)] for raw in range(city_num)]for ant in self.ants:for i in range(1, city_num):start, end = ant.path[i - 1], ant.path[i]# 在路径上的每两个相邻城市间留下信息素,与路径总距离反比temp_pheromone[start][end] += Q / ant.total_distancetemp_pheromone[end][start] = temp_pheromone[start][end]# 更新所有城市之间的信息素,旧信息素衰减加上新迭代信息素for i in range(city_num):for j in range(city_num):pheromone_graph[i][j] = pheromone_graph[i][j] * RHO + temp_pheromone[i][j]# 主循环def mainloop(self):self.root.mainloop()# ----------- 程序的入口处 -----------if __name__ == '__main__':TSP(tkinter.Tk()).mainloop()

初始的城市分布情况如图所示:

迭代30次左右的情况

600次左右的情况

总结

蚁群算法广泛应用在TSP(商旅问题)路径优化问题 调度问题 着色问题 聚类分析 网络路由 数据挖掘 工业PCB 板
其它组合优化。
蚁群算法的优点缺点:
具有较强的鲁棒性、优良的分布式计算机制和正反馈机制、易于与其他方法相结合等优点,缺点是求解时间长,初始信息素匮乏,容易出现停滞现象。

参考文献https://blog.csdn.net/weixin_39383896/article/details/101568241

蚁群算法原理与实现(python)相关推荐

  1. 蚁群算法原理详解和matlab代码

    1原理: 蚂蚁在寻找食物源的时候,能在其走过的路径上释放一种叫信息素的激素,使一定范围内的其他蚂蚁能够察觉到.当一些路径上通过的蚂蚁越来越多时,信息素也就越来越多,蚂蚁们选择这条路径的概率也就越高,结 ...

  2. 道路匹配MapMatching:GPS轨迹点常用聚类算法介绍(K-Means聚类、蚁群算法等)

    道路匹配MapMatching:GPS轨迹点常用聚类算法介绍(K-Means聚类.蚁群算法等) 前言 一.聚类算法是什么? 二.道路匹配中常见聚类算法介绍 1.K-Means算法 2.基于时间和距离的 ...

  3. python蚁群算法路径规划_使用python实现蚁群算法

    此次使用python实现蚁群算法是仿照蚁群优化算法的JAVA实现中的蚁群算法实现方法,使用的也是其中的数据(此处为上传数据),如需更深一步了解蚁群算法原理和具体实现过程,请参考蚁群优化算法的JAVA实 ...

  4. MATLAB机器学习系列-12:蚁群算法优化原理及其matlab实现

    蚁群算法原理 概述 蚁群算法(Ant Colony Algorithm, ACA)由Marco Dorigo于1992年在他的博士论文中首次提出,该算法模拟了自然界中蚂蚁的觅食行为. 蚂蚁在寻找食物源 ...

  5. 离散蚁群算法实例(求解旅行商问题)

    蚁群算法 蚁群算法原理 万字长文带你了解蚁群算法及求解复杂约束问题[源码实现] 上面这篇博文的蚁群算法是实数编码.今天讲解下离散编码的蚁群算法.      算法原理不再解释,直接上算例. 旅行商问题 ...

  6. 数学建模算法模型--蚁群算法

    有关蚁群算法学习资料分享: 链接:https://pan.baidu.com/s/10rY9OYN0ADfhKDXOK0R4fA?pwd=v09z  提取码:v09z 蚁群算法(Ant Colony ...

  7. 群智能算法 第4关:蚁群算法 - 商队旅行最短路径计算

    任务描述 本关任务:使用 python 实现蚁群算法,并寻找商队旅行最短路径. 相关知识 为了完成本关任务,你需要掌握:1.蚁群算法原理,2.蚁群算法流程,3.使用蚁群算法解决商队旅行问题. 蚁群算法 ...

  8. 智能优化算法之蚁群算法(1)

    蚁群算法(ant colony algorithm) : 一种模拟进化算法 蚂蚁在觅食过程中能够在其经过的路径留下一种称为信息素的物质,并在觅食的过程中能感知这种物质的强度,并指导自己的行动方向,他们 ...

  9. 蚁群算法和简要matlab来源

    1 蚁群算法原理 从1991由意大利学者 M. Dorigo,V. Maniezzo 和 A. Colorni 通过模拟蚁群觅食行为提出了一种基于群体的模拟进化算法--蚁群优化.极大关注,蚁群算法的特 ...

  10. 蚁群算法(Ant Colony Optimization)

    蚁群算法(Ant Colony Optimization) 蚁群算法简介 蚁群算法(Ant Clony Optimization, ACO)是一种群智能算法,它是由一群无智能或有轻微智能的个体(Age ...

最新文章

  1. css3多行超出隐藏并打点点
  2. c语言程序设计填空带答案,c语言程序设计填空题及答案复习用精编-20210414010859.docx-原创力文档...
  3. Java实现线程同步的方式
  4. 计算机1级 计算机基础知识,计算机一级计算机基础及MSOffice应用:计算机基础知识...
  5. STM32使用IIC总线通讯协议在OLED屏幕上显示字符串、汉字、单总线获取DHT11模块温湿度并通过IIC显示到屏幕(软件IIC)
  6. Postman安装与使用(网络请求神器)--post、get请求
  7. python求1到n的乘积_Python如何计算列表中所有数字的乘积?(代码示例)
  8. NLP基础|中英文词向量评测理论与实践
  9. OpenCV3学习(3)——视频文件的读取与写入
  10. html align 属性,align-content
  11. 使用pt-query-digest进行日志分析
  12. 洛谷P2568 GCD(莫比乌斯反演)
  13. AngularJS 学习笔记值post传值
  14. 数据结构学习笔记(转载)
  15. Hive,Pig,HBase 傻傻分不清楚
  16. mysql游标 循环_MySQL游标与嵌套循环
  17. MiniTable 可单选/取消单选.
  18. 持续分化的 NFT 市场:新的金字塔正在形成
  19. 【Linux】grep命令与正则表达式(RegExp)
  20. C++年月日时分秒与秒数互相转换

热门文章

  1. 如何在虚拟机安装鸿蒙os,VirtualBox安装教程
  2. Vagrant 与 VirtualBox 的保姆级安装教程
  3. Redhat Enterprise Linux磁带机简单操作
  4. js替换a标签href
  5. SSM实现会议室预约管理系统
  6. 2020年日历_2020年日历全年表
  7. Github TOP100 Android开源,flutter与android混合开发
  8. 中国管道内检测市场现状调研与投资预测分析报告2022-2028年
  9. 项管:配置管理、变更管理、文档管理、知识管理及其他
  10. 【信息系统项目管理师】第十六章 变更管理思维导图