1、蚂蚁在路径上释放信息素。

2、碰到还没走过的路口,就随机挑选一条路走。同时,释放与路径长度有关的信息素。

3、信息素浓度与路径长度成反比。后来的蚂蚁再次碰到该路口时,就选择信息素浓度较高路径。

4、最优路径上的信息素浓度越来越大。

5、最终蚁群找到最优寻食路径。

人工蚁群与真实蚁群对比:

基于TSP问题的基本蚁群算法:

TSP求解中,假设蚁群算法中的每只蚂蚁是具有以下特征的简单智能体:

每次周游,每只蚂蚁在其经过的支路(i,j)上都留下信息素。

‚蚂蚁选择城市的概率与城市之间的距离和当前连接支路上所包含的信息素余量有关。

ƒ为了强制蚂蚁进行合法的周游,直到一次周游完成后,才允许蚂蚁游走已访问过的城市(这可由禁忌表来控制)。

基本蚁群的两个过程:

(1)状态转移

(2)信息素更新

(1)状态转移

为了避免残留信息素过多而淹没启发信息,在每只蚂蚁走完一步或者完成对所有n个城市的遍历(也即一个循环结束)后,要对残留信息进行更新处理。

由此,t+n时刻在路径(i,j)上的信息量可按如下规则进行调整:

(2)信息素更新模型

蚁周模型(Ant-Cycle模型)

蚁量模型(Ant-Quantity模型)

蚁密模型(Ant-Density模型)

区别:

1.蚁周模型利用的是全局信息,即蚂蚁完成一个循环后更新所有路径上的信息素;

2.蚁量和蚁密模型利用的是局部信息,即蚂蚁完成一步后更新路径上的信息素。

蚁群算法基本流程:

蚁群算法中主要参数的选择:

蚁群算法中主要参数的理想选择如下:

国内外,对于离散域蚁群算法的改进研究成果很多,例如自适应蚁群算法、基于信息素扩散的蚁群算法等,这里仅介绍离散域优化问题的自适应蚁群算法。

自适应蚁群算法:对蚁群算法的状态转移概率、信息素挥发因子、信息量等因素采用自适应调节策略为一种基本改进思路的蚁群算法。

自适应蚁群算法中两个最经典的方法:蚁群系统(AntColony System, ACS)和最大-最小蚁群系统(MAX-MINAnt System, MMAS)。

蚁群系统对基本蚁群算法改进:

①蚂蚁的状态转移规则不同;

②全局更新规则不同;

③新增了对各条路径信息量调整的局部更新规则

下面是Python实现求50个城市之间最短距离的代码

# -*- coding: utf-8 -*-

import random

import copy

import time

import sys

import math

import tkinter #//GUI模块

import threading

from functools import reduce

# 参数

'''

ALPHA:信息启发因子,值越大,则蚂蚁选择之前走过的路径可能性就越大

,值越小,则蚁群搜索范围就会减少,容易陷入局部最优

BETA:Beta值越大,蚁群越就容易选择局部较短路径,这时算法收敛速度会

加快,但是随机性不高,容易得到局部的相对最优

'''

(ALPHA, BETA, RHO, Q) = (1.0,2.0,0.5,100.0)

# 城市数,蚁群

(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.0 for col in range(city_num)] for raw in range(city_num)]

pheromone_graph = [ [1.0 for col in range(city_num)] for raw in range(city_num)]

#----------- 蚂蚁 -----------

class Ant(object):

# 初始化

def __init__(self,ID):

self.ID = ID # ID

self.__clean_data() # 随机初始化出生点

# 初始数据

def __clean_data(self):

self.path = [] # 当前蚂蚁的路径

self.total_distance = 0.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_index

self.path.append(city_index)

self.open_table_city[city_index] = False

self.move_count = 1

# 选择下一个城市

def __choice_next_city(self):

next_city = -1

select_citys_prob = [0.0 for i in range(city_num)] #存储去下个城市的概率

total_prob = 0.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.0/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.0:

# 产生一个随机概率,0.0-total_prob

temp_prob = random.uniform(0.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.0:

next_city = i

break

# 未从概率产生,顺序选择一个未访问城市

# if next_city == -1:

# for i in range(city_num):

# if self.open_table_city[i]:

# next_city = i

# break

if (next_city == -1):

next_city = random.randint(0, city_num - 1)

while ((self.open_table_city[next_city]) == False): # if==False,说明已经遍历过了

next_city = random.randint(0, city_num - 1)

# 返回下一个城市序号

return next_city

# 计算路径总距离

def __cal_total_distance(self):

temp_distance = 0.0

for 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] = False

self.total_distance += distance_graph[self.current_city][next_city]

self.current_city = next_city

self.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(object):

def __init__(self, root, width = 800, height = 600, n = city_num):

# 创建画布

self.root = root

self.width = width

self.height = height

# 城市数目初始化为city_num

self.n = n

# tkinter.Canvas

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 = 5

self.__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 = False

self.__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.__r

node = 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.0

self.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 = False

self.__lock.release()

self.root.destroy()

print (u"\n程序已退出...")

sys.exit()

# 停止搜索

def stop(self, evt):

self.__lock.acquire()

self.__running = False

self.__lock.release()

# 开始搜索

def search_path(self, evt = None):

# 开启线程

self.__lock.acquire()

self.__running = True

self.__lock.release()

while self.__running:

# 遍历每一只蚂蚁

for ant in self.ants:

# 搜索一条路径

ant.search_path()

# 与当前最优蚂蚁比较

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_distance

temp_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__':

print (u"""

--------------------------------------------------------

程序:蚁群算法解决TPS问题程序

作者:许彬

日期:2015-12-10

语言:Python 2.7

--------------------------------------------------------

""")

TSP(tkinter.Tk()).mainloop()

python蚁群算法可视化_蚁群算法原理及其实现(python)相关推荐

  1. 机器学习经典算法实践_服务机器学习算法的系统设计-不同环境下管道的最佳实践

    机器学习经典算法实践 "Eureka"! While working on a persistently difficult-to-solve problem, you disco ...

  2. python路径规划算法可视化_基于粒子群算法的牙齿正畸路径规划方法python实现

    这篇是基于粒子群算法的牙齿正畸路径规划研究的python实现,参考的是徐晓强等人的<基于改进粒子群算法的牙齿正畸路径规划方法>,与这篇文章的区别在于: 1.徐等的文章设计了一种改进的粒子群 ...

  3. 付费入群怎么做_微信群怎么设置付费才可以进入

    如果我们有资源,有特立独行的表情包,或者有渠道,我们就可以通过付费进群的功能设置需要资源的用户可以扫码付费之后加入可以获取有趣的有价值的资源包或者表情包,需要实现付费进群功能也非常的简单,我们只需要准 ...

  4. python复杂网络点图可视化_数据分析:R与Python怎么选?

    作者介绍 知春里@伟仔 不知名数据科学家. 持续写<数据分析>和<数据产品>的系列文章,欢迎关注. 01 选R还是Python? "球鞋是买阿迪还是买耐克?" ...

  5. python的gui界面 可视化_使用可视化设计窗体的GUI程序

    示例Demo2_1用PyQt5的一些类创建了一个简单的GUI应用程序,窗体及窗体上的标签对象的创建和属性设置都完全由代码完成.显然这种纯代码方式构造UI的方式是比较麻烦的,特别是在窗体上组件比较多.层 ...

  6. python文献知识图谱可视化_知识图谱可视化工具(知识图谱可视化python)

    知识图谱可视化工具免费杭州市西湖区教育装备保障服务中心 除了知识图,图还能做什么?编者注:作者的高级解决方案顾问包汉林.本文将集中在三个方面,侧重于图数据库和图分析的价值,并列举图分析应用程序的一些方 ...

  7. python nlp文本摘要实现_用TextRank算法实现自动文本摘要

    [51CTO.com快译]1. 引言 文本摘要是自然语言处理(NLP)领域中的应用之一,它必将对我们的生活产生巨大影响.随着数字媒体和出 版业的不断发展,谁还有时间浏览整篇文章/文档/书籍来决定它们是 ...

  8. mysql集群与分布式_集群与分布式的区别

    什么是集群 集群(cluster)就是一组计算机,它们作为一个整体向用户提供一组网络资源,这些单个的计算机系统就是集群的节点(node).集群提供了以下关键的特性.可扩展性.集群的性能不限于单一的服务 ...

  9. python 异常点检测 cook距离_异常检测算法汇总

    本文来自:https://github.com/Albertsr 第一部分:无监督异常检测 1. 算法 1.1 孤立森林(Isolation Forest) 算法论文: Isolation Fores ...

  10. 第5章_使用者(User)_群组(Group)_非群组外的其他人(Other)文件权限改变

    1. Linux用户身份与群组相关信息 系统上账号信息 个人密码记录在/etc/shadow文件中 Linux中的组名记录在/etc/group 通过ls -al 查看文件权限,可以分别看到 文件所有 ...

最新文章

  1. php artisan常用方法
  2. 多个数字数组_1分钟彻底理解JavaScript的数组与函数
  3. C++ STL : 模拟实现STL中的关联式容器unordered_map/unordered_set
  4. Vue全家桶实战01_【从入门到放弃系列】
  5. 准备重新回归信息安全产业
  6. firefox2.0的拖放式搜索怎么不行了?是设置问题吗?
  7. There is no row in position 0
  8. JavaScript基础知识必知!
  9. php用于字符串函数是,php中用于查找字符串的常用函数
  10. gitee创建ssh公钥
  11. jquery计算两个日期天数差
  12. 虚拟机中安装vmware tools 到 Debian 时出现 找不到kernel headers的提示
  13. UNIX操作系统中,文件的索引结构放在( )
  14. 矩阵运算--特征矩阵
  15. 【DirectX3D - 5】渲染多路视频(单一窗口)
  16. mysql8 错误日志_MySQL 8 服务器日志
  17. Raft和PBFT算法对比
  18. ffmpeg转换进度计算公式
  19. 怎么用计算机向手机上传照片,华为手机怎么传照片到电脑上去?华为手机往电脑传照片方法...
  20. csps2019格雷码

热门文章

  1. Vue中,v-show与v-if的区别
  2. 二进制十进制间小数怎么转换
  3. 软件测试--缺陷报告常见问题03
  4. Android Studio — Could not determine java version from ‘11.0.8‘. The project uses Gradle version wh
  5. 如何在Eclipse配置Tomcat
  6. 7-5 删除字符串中的子串 (20 分)
  7. javascript简介和基本语法
  8. 什么是jquery $ jQuery对象和DOM对象 和一些选择器
  9. 调用ICodeCompiler来计算字符串表达式
  10. E60的存储空间不足? NO