蚁群优化算法ACO

蚁群优化算法模拟了自然界中蚂蚁的觅食行为,信息素浓度的大小表征路径的远近,信息素浓度越高,表示对应的路径距离越短。同时,路径上的信息素浓度会随着时间的推进而逐渐衰减。

1.过程

(1)初始化参数

蚁群规模、信息素因子α、启发函数因子β、信息素挥发因子ρ、信息素释放总量q、最大迭代次数等。

(2)构建解空间

起初把蚂蚁随机放到不同城市,对于每一个蚂蚁,采用轮盘赌找出下一个要访问的城市,直到访问完所有城市。

(3)更新信息素

计算各个蚂蚁经过的路径长度,找出本次迭代中的最短路径,并更新城市路径的信息素浓度。更新信息素浓度分为三种策略:蚁周、蚁量、蚁密。

蚁周是完成一次路径循环后,蚂蚁才释放信息素。

蚁量是一只蚂蚁从一个城市到达另一个城市后,直接释放信息素。

蚁密是一只蚂蚁从一个城市到达另一个城市后,释放的信息素需要除以城市间的路径距离。

(4)判断是否终止

迭代次数到达最大迭代次数后,终止。否则,回到(2)。

2.流程图

3.代码

from utils import draw_picture, get_next_pos, init_pos, save_best_result
import tqdmimport matplotlib.pyplot as plt
import matplotlib
matplotlib.use('TkAgg')class ACO(object):def __init__(self, ant_count: int, generations: int, alpha: float, beta: float, rho: float, q: int,strategy: int, distance, points):""":param ant_count::param generations::param alpha: relative importance of pheromone:param beta: relative importance of heuristic information:param rho: pheromone residual coefficient:param q: pheromone intensity:param strategy: pheromone update strategy. 0 - ant-cycle, 1 - ant-quality, 2 - ant-density:param distance: distance between each points"""self.Q = qself.rho = rhoself.beta = betaself.alpha = alphaself.ant_count = ant_countself.generations = generationsself.update_strategy = strategyself.points = pointsself.distance = distance# 路径数目self.rank = len(distance)#self.eta = [[0 if i == j else 1 / distance[i][j] for j in range(self.rank)] for i inrange(self.rank)]# 每条路径上的信息素浓度self.pheromone_content = [[1 for _ in range(self.rank)] for _ in range(self.rank)]# 初始化def initialization(self):self.memory_vector = []     # 记录每个蚂蚁的总路径for _ in range(self.ant_count):     # 不关心i,可以用_代替iself.memory_vector.append([init_pos(self.rank)])    # 随机初始化每个蚂蚁位置# 用轮盘赌计算蚂蚁要去的下一个城市def roulette(self, id, pos):possibility = []for i in range(self.rank):if i in self.memory_vector[id]:# 如果蚂蚁访问过这个城市,则不去possibility.append(0)else:possibility.append(self.pheromone_content[pos][i]**self.alpha*(self.eta[pos][i]**self.beta))next_pos = get_next_pos(possibility)return next_pos# 增加信息素浓度:三种策略,这里还有点问题def update_pheromone_delta(self, ant_path):if self.update_strategy == 0:for i in range(self.ant_count):self.pheromone_content[ant_path[i][0]][ant_path[i][1]] += self.Qself.pheromone_content[ant_path[i][1]][ant_path[i][0]] += self.Qif len(self.memory_vector[0]) == self.rank:self.pheromone_content[self.memory_vector[i][-1]][self.memory_vector[i][0]] += self.Qself.pheromone_content[self.memory_vector[i][0]][self.memory_vector[i][-1]] += self.Qelif self.update_strategy == 1:for i in range(self.ant_count):self.pheromone_content[ant_path[i][0]][ant_path[i][1]] += (self.Q/self.distance[ant_path[i][0]][ant_path[i][1]])self.pheromone_content[ant_path[i][1]][ant_path[i][0]] += (self.Q/self.distance[ant_path[i][0]][ant_path[i][1]])if len(self.memory_vector[0]) == self.rank:self.pheromone_content[self.memory_vector[i][-1]][self.memory_vector[i][0]]+=self.Q/self.distance[self.memory_vector[i][0]][self.memory_vector[i][-1]]self.pheromone_content[self.memory_vector[i][0]][self.memory_vector[i][-1]]+=self.Q/self.distance[self.memory_vector[i][0]][self.memory_vector[i][-1]]elif self.update_strategy == 2:# 完成一次循环后if len(self.memory_vector[0]) == self.rank:# 计算每个蚂蚁本次的总路程total_cost = []for i in range(self.ant_count):cost = 0for j in range(1, self.rank):cost += self.distance[self.memory_vector[i][j-1]][self.memory_vector[i][j]]cost += self.distance[self.memory_vector[i][0]][self.memory_vector[i][-1]]total_cost.append(cost)# 更新信息素浓度for i in range(self.ant_count):delta = self.Q/total_cost[i]for j in range(1, self.rank):# 双向路径self.pheromone_content[self.memory_vector[i][j-1]][self.memory_vector[i][j]] += deltaself.pheromone_content[self.memory_vector[i][j]][self.memory_vector[i][j-1]] += delta# 蚂蚁最初的那条路self.pheromone_content[self.memory_vector[i][0]][self.memory_vector[i][-1]] += deltaself.pheromone_content[self.memory_vector[i][-1]][self.memory_vector[i][0]] += deltaelse:# 没有完成一次循环passelse:raise KeyError# 减少信息素浓度def update_pheromone(self):for i in range(self.rank):for j in range(self.rank):self.pheromone_content[i][j] = self.pheromone_content[i][j] * (1 - self.rho)# 更新蚂蚁本次迭代找到的路径def update_memory_vector(self, ant_path):for i in range(self.ant_count):self.memory_vector[i].append(ant_path[i][1])# 执行算法def run(self):self.cost = 0self.path = []plt.ion()   # 启用交互模式(动态图)# tqdm进度条for iteration in tqdm.tqdm(range(self.generations), desc='Processing'):# print(f'-----start iteration {iteration+1} of ACO-----')self.initialization()for steps in range(self.rank - 1):# 在一次新的迭代中,蚂蚁选择一条路径从pos到next_posant_path = []for i in range(self.ant_count):     # 对于每一只蚂蚁pos = self.memory_vector[i][-1]next_pos = self.roulette(i, pos)ant_path.append([pos, next_pos])self.update_memory_vector(ant_path)     # 更新蚂蚁本次迭代的路径self.update_pheromone_delta(ant_path)   # 增加路径上的信息素浓度self.update_pheromone()     # 减少信息素浓度plt.cla()plt.title("ant colony algorithm")self.cost, self.path = draw_picture(self.points, self.distance, self.memory_vector, iteration)plt.pause(0.01)     # 暂停运行一段时间,能将内存中的图像显示出来# 保存数据def save(self, seed):save_best_result(self.path, self.points, seed)plt.ioff()  # 关闭交互模式plt.show()  # 显示图片,会阻塞后面代码运行,适用于静态图
# 开发时间:2023/12/13 19:50
import random
import math
import numpy as npimport matplotlib.pyplot as plt
import matplotlib
matplotlib.use('TkAgg')def random_init(points_num ,min_x ,max_x, min_y, max_y):points = []while len(points) != points_num:x = random.randint(min_x, max_x)y = random.randint(min_y, max_y)if [x, y] in points:continuepoints.append([x, y])file = open("temp.txt", "w")for i in range(len(points)):file.write(f'{points[i][0]}{points[i][1]}\n')file.close()print("Data running time was saved in file [temp.txt]")return pointsdef dis(point1, point2):return math.sqrt((point1[0]-point2[0]) ** 2 + (point1[1]-point2[1]) ** 2)def calculate_distance(points):distance = []for i in range(len(points)):list = []for j in range(len(points)):list.append(dis(points[i], points[j]))distance.append(list)return distancedef get_next_pos(possibility):n = sum(possibility)for i in range(len(possibility)):possibility[i] /= nn = sum(possibility)r = random.uniform(0, n)pos = 0while True:if possibility[pos] == 0:pos += 1elif r-possibility[pos] < 0:return poselse:r -= possibility[pos]pos += 1def init_pos(rank):pos = random.randint(0, rank-1)return posdef load_example(text_name):file = open(text_name, 'r')content = file.readlines()points = []for data in content:x, y = data.split(" ")points.append([int(x), int(y)])distance = calculate_distance(points)return points, distancedef draw_picture(points, distance, path, iteration):rank = len(points)ant_number = len(path)x = []y = []for i in range(rank):x.append(points[i][0])y.append(points[i][1])plt.scatter(x, y)min_cost = np.inffor i in range(ant_number):temp_cost = 0for j in range(1, rank):temp_cost += distance[path[i][j-1]][path[i][j]]temp_cost += distance[path[i][0]][path[i][-1]]if temp_cost < min_cost:min_cost = temp_costbest_path = path[i]for i in range(ant_number):for j in range(rank):x[j] = points[path[i][j]][0]y[j] = points[path[i][j]][1]plt.plot(x, y)plt.text(0, 0, f'iteration:{iteration} min_cost = {round(min_cost, 2)}', family='fantasy', fontsize=12,style='italic',color='mediumvioletred')return round(min_cost, 2), best_pathdef save_best_result(path, points, seed):for i in range(1, len(path)):x1 = points[path[i - 1]][0]y1 = points[path[i - 1]][1]x2 = points[path[i]][0]y2 = points[path[i]][1]plt.arrow(x1, y1, x2 - x1, y2 - y1, width=0.05, color='r', length_includes_head=True)plt.arrow(x2, y2, points[path[0]][0] - x2, points[path[0]][1] - y2, width=0.05, color='r',length_includes_head=True)plt.gcf().set_size_inches(20, 12)  # get current figureplt.savefig("result.png")print("画图呀")plt.close()print('\n')print("-" * 50)print(f"[Best Path](random seed [{seed}])")print(show_path(path))print("Last result picture was saved in [result.png]")print(f"If you want to get this result again please add '-s {seed}'")print("-" * 50)print('\n')def show_path(path):route = str(path[0])for i in range(1, len(path)):route = route + "->"+str(path[i])route = route + "->"+str(path[0])return route
import argparse
from ACO import ACO
import random
from utils import random_init,calculate_distance,load_exampleimport matplotlib
matplotlib.use('TkAgg')def default_argument_parser():# ArgumentParser 编写命令行接口# 创建对象(解析器)parser = argparse.ArgumentParser(description="ant colony algorithm")# 添加参数parser.add_argument("--test", nargs="?")  # 参数可设置0或1个parser.add_argument('--ant', default=5, type=int)   # 蚂蚁数parser.add_argument('--points', default=20, type=int)   # 城市数parser.add_argument('--generation', default=50,type=int)  # 迭代次数parser.add_argument('--alpha', default=2.0,type=float)     # 信息素因子parser.add_argument('--beta', default=3.0,type=float)     # 启发函数因子parser.add_argument('--rho', default=0.5,type=float)       # 信息素挥发因子parser.add_argument('--q', default=100,type=float)      # 信息素浓度parser.add_argument('--strategy', default=2,type=int)   # 信息素更新策略parser.add_argument('--min_x', default=0,type=int)      # 范围parser.add_argument('--max_x', default=100,type=int)parser.add_argument('--min_y', default=0,type=int)parser.add_argument('--max_y', default=100,type=int)parser.add_argument('-s', '--seed', type=int)'''信息素三种更新策略0:  蚁量:加浓度1:  蚁密:加浓度/城市间的路径距离2:  蚁周:蚂蚁全走完再更新信息素浓度'''return parserdef main():# 解析参数args = default_argument_parser().parse_args()if(args.seed == None):seed = random.randint(1, 10000)random.seed(seed)   # 随机数种子print("no random seed found")args.seed = seedelse:print(f"set random seed {args.seed}")random.seed(args.seed)if args.test != None:points, distance = load_example(args.test)else:points = random_init(args.points, args.min_x, args.max_x, args.min_y, args.max_y)distance = calculate_distance(points)aco = ACO(ant_count=args.ant,generations=args.generation,alpha=args.alpha,beta=args.beta,rho=args.rho,q=args.q,strategy=args.strategy,points=points,distance=distance,)aco.run()       # 执行算法aco.save(args.seed)     # 保存数据# 当.py文件被直接运行时,下面代码会执行;当.py文件以模块形式被导入则不会执行
if __name__ == '__main__':main()

4.优缺点

优点:采用正反馈机制进行更新,使得结果不断收敛;可以并行计算。

缺点:收敛速度慢;不适用于解空间是连续的优化问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/221768.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx+Tomcat实现负载均衡和动静分离

目录 前瞻 动静分离和负载均衡原理 实现方法 实验&#xff08;七层代理&#xff09; 部署Nginx负载均衡服务器(192.168.75.50:80) 部署第一台Tomcat应用服务器&#xff08;192.168.75.60:8080&#xff09; 多实例部署第二台Tomcat应用服务器&#xff08;192.168.75.70:80…

8080端口被占用怎么解决,并结束释放8080端口

8080端口是被用于WWW代理服务的&#xff0c;可以实现网页浏览&#xff0c;经常在访问某个网站或使用代理服务器的时候&#xff0c;Win10 8080端口被占用解决方法吧。 1、按【 Win r】 2、运行窗口&#xff0c;输入【cmd】命令&#xff0c;按【确定或回车】&#xff0c;打开命…

基于SpringBoot 校园招聘系统设计与实现(源码+文档+可视化HTML+数据库)

摘 要 基于SpringBoot 校园招聘系统是一种基于Java技术的校园招聘和可视化展示的系统。该系统通过采集和整合各类招聘网站、社交媒体等渠道的数据&#xff0c;对招聘岗位进行深入分析&#xff0c;并将分析结果以直观、易懂的可视化形式呈现。系统能够自动从多个数据源获取招聘…

电子学会C/C++编程等级考试2023年03月(五级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:拼点游戏 C和S两位同学一起玩拼点游戏。有一堆白色卡牌和一堆蓝色卡牌,每张卡牌上写了一个整数点数。C随机抽取n张白色卡牌,S随机抽取n张蓝色卡牌,他们进行n回合拼点,每次两人各出一张卡牌,点数大者获得三颗巧克力,小者获…

Flutter:web项目跨域问题解决

前后端解决系列 文章目录 一、Flutter web客户端解决本地环境调试跨域问题二、Flutter web客户端解决线上环境跨域问题 一、Flutter web客户端解决本地环境调试跨域问题 就一句命令【--web-browser-flag "--disable-web-security"】&#xff0c;用来屏蔽浏览器域名请…

大模型时代-让AI自己开发自己

一、前言 AI能自己开发自己或者开发和一个很像自己的东西吗&#xff1f;显然是可以的&#xff01;因为AI模型的算法&#xff0c;基本就是学习和递归 二、大模型的算法实现例子 本例子就是通过AI模型来写 大模型的实现通常涉及到深度学习框架和大量的计算资源。具体的算法代…

Java入门学习笔记二

一、抽象类 当编写一个类时&#xff0c;我们往往会为该类定义一些方法&#xff0c;这些方法是用来描述该类的行为方式&#xff0c;那么这些方法都有具体的方法体。 分析事物时&#xff0c;发现了共性内容&#xff0c;就出现向上抽取。会有这样一种特殊情况&#xff0c;就是功…

Python实现高效摸鱼,批量识别银行卡号并自动写入Excel表格

前言 每当有新员工入职&#xff0c;人事小姐姐都要收集大量的工资卡信息&#xff0c;并且生成Excel文档&#xff0c;看到小姐姐这么辛苦&#xff0c;我就忍不住要去帮她了… 于是我用1行代码就实现了自动识别银行卡信息并且自动生成Excel文件&#xff0c;小姐姐当场就亮眼汪汪…

智能冶钢厂环境监控与设备控制系统(边缘物联网网关)

目录 1、项目背景 2、项目功能介绍 3、模块框架 3.1 架构框图 3.2 架构介绍 4、系统组成与工作原理 4.1 数据采集 4.2 指令控制 4.3 其他模块 4.3.1 网页、qt视频流 4.3.2 qt搜索进程 5、成果呈现 6、问题解决 7、项目总结 1、项目背景 这个项目的背景是钢铁行业的…

tesseract-ocr安装使用

描述&#xff1a; 在centos上安装 tesseract 并在springboot项目中使用 步骤一&#xff1a;安装 确认使用的版本tesseract和test4j版本需要匹配&#xff0c;这里选择最新版 tesseract5.3.3 &#xff0c;test4j 5.9.0 版本匹配可查看 Releases nguyenq/tess4j GitHub 或…

使用 iperf 和 iftop 测试网络带宽

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…

CSS中神奇的filter属性

CSS是Web开发中不可或缺的一部分&#xff0c;它可以帮助开发者在页面上添加各种各样的样式和效果。其中一个比较神奇的CSS属性就是filter&#xff0c;它可以让我们实现各种有趣的图形处理效果。 一、filter属性的基础 filter属性是CSS中用于对元素进行图形效果处理的属性之一…

C语言—每日选择题—Day47

第一题 1. 以下逗号表达式的值为&#xff08;&#xff09; (x 4 * 5, x * 5), x 25 A&#xff1a;25 B&#xff1a;20 C&#xff1a;100 D&#xff1a;45 答案及解析 D 本题考查的就是逗号表达式&#xff0c;逗号表达式是依次计算每个表达式&#xff0c;但是只输出最后一个表…

【算法题】开源项目热度榜单(js)

解法 const lines ["4","8 6 2 8 6","camila 66 70 46 158 80","victoria 94 76 86 189 211","athony 29 17 83 21 48","emily 53 97 1 19 218", ]; const lines2 ["5","5 6 6 1 2","…

ArkTS入门

代码结构分析 struct Index{ } 「自定义组件&#xff1a;可复用的UI单元」 xxx 「装饰器&#xff1a;用来装饰类结构、方法、变量」 Entry 标记当前组件是入口组件&#xff08;该组件可被独立访问&#xff0c;通俗来讲&#xff1a;它自己就是一个页面&#xff09;Component 用…

tuxera2023破解版免费下载 NTFS for Mac读写工具(附序列号)

Tuxera ntfs 2023 破解安装包是一个mac读写ntfs磁盘工具允许您访问&#xff0c;它允许您访问NFTS 驱动器上的文件。 该应用程序提供访问访问Mac 设备中NFTS 格式文件的驱动力&#xff0c;因此您有权基于格式文件进行无困难的访问Windows 数据。 在发生电力灾难或断电时使用防损…

Signal EM的流程与分析

RedhawkTM 提供了一种在设计中分析Power EM和SignalEM的单一平台方法。Power EM通常作为Static IR和Dynamic IR分析的组成部分进行。Signal EM分析是单独进行分析的,检查设计中所有信号线和过孔的平均(单向或双向)、RMS和峰值电流密度【1】。 1 SignalEM 流程介绍 如图7…

ArrayList集合的两个实例应用,有趣的洗牌算法与杨辉三角

本节课的内容&#xff0c;就让我们来学习一下ArrayList集合的应用&#xff0c;ArrayList的本质就是一个顺序表&#xff0c;那下面一起来学习吧 目录 一、杨辉三角 1.题目详情及链接 2.剖析题目 3.思路及代码 二、洗牌算法 1.创造牌对象 2.创造一副牌 3.洗牌操作 4.发…

人工智能(pytorch)搭建模型22-基于pytorch搭建SimpleBaseline(人体关键点检测)模型,并详细介绍该网络模型与代码实现

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型22-基于pytorch搭建SimpleBaseline(人体关键点检测)模型&#xff0c;并详细介绍该网络模型与代码实现。本文将介绍关于SimpleBaseline模型的原理&#xff0c;以及利用pytorch框架搭建模型…

lwIP 细节之三:errf 回调函数是何时调用的

使用 lwIP 协议栈进行 TCP 裸机编程&#xff0c;其本质就是编写协议栈指定的各种回调函数。将你的应用逻辑封装成函数&#xff0c;注册到协议栈&#xff0c;在适当的时候&#xff0c;由协议栈自动调用&#xff0c;所以称为回调。 注&#xff1a;除非特别说明&#xff0c;以下内…