当前位置: 首页 > news >正文

python 实现蚁群算法(simpy带绘图)

这里使用了蚁群算法求解了旅行商问题,同时结合了simpy来绘图

选择下一个食物的函数为:

probability[i] = pheromone[self.now][self.not_to_foods[i]] ** pheromone_w + (1 / distance[self.now][self.not_to_foods[i]]) ** distance_w

该条路概率权重=该点信息素^信息素权重*(1/路径长)^路径权重/总和,这里后面会用random.choices就不用除了

信息素更新为:

new_pheromone[self.route[i]][self.route[i + 1]] += pheromone_Q / self.sum_len
pheromone = np.add((1 - volatilize) * pheromone, new_pheromone)

总信息素会挥发volatilize比例,然后所有蚂蚁路径每一段加上固定释放的信息量/路径总长度

话不多说,都在代码注释里了

import random
import simpy
import matplotlib.pyplot as plt
import numpy as np# 在这里我们尝试用蚁群算法求解旅行商问题,简而言之,就是寻找一条链接所有点的最短路径最后要回到初始点
# 我想绘制一下每只蚂蚁的行走过程,所以使用上次的simpy包来模拟一下,
# 这个simpy包主要是为了更好的可视化模拟训练过程,你也可以给每只蚂蚁单独线程代替,
# 或者干脆不用管过程,只用一轮一轮的上蚂蚁,在信息素部分做点处理,光看结果也可以。总之大多要比simpy快class Ant(object):  # 蚂蚁类# 说一下训练过程,有很多只蚂蚁,从随机位置出发,# 每次遵从信息素的指引,选择下一个城市,直到没有可选城市,回到初始位置然后根据路径总长度在路径上散播信息素def __init__(self):  # 蚂蚁构造函数# 一只蚂蚁,只需要保存走过的食物就可以,# 这里我们为了以后整信息素时不用遍历,顺便保存一下走过的长度self.route = []  # 到达食物路径,一个例子是:[2,1,3,2]self.not_to_foods = []  # 未到达的食物点self.sum_len = 0  # 走过路径总长度self.now = 0  # 当前所在位置self.next_food = 0  # 下一个所在位置self.Initial_Position(random.randint(0,foods_n-1))  # 设定初始位置# 绘图参数self.now_position = [0, 0]  # 起始到终点的向量self.proportion = env.now  # 走的时间,画图就是找到起始食物点,然后加上(起始和终点的向量乘以(当前时间-出发时间)/路长)就是蚂蚁位置,def Initial_Position(self, n):  # 选择初始位置'self.now = n  # 当前所在的食物self.next_food = n  # 下一个要到的食物self.route = []self.not_to_foods = [i for i in range(foods_n)]  # 未到达的食物点self.sum_len = 0self.route.append(n)  # 添加到路径self.not_to_foods.remove(n)  # 初始点不会在未到的食物点def Set_Now(self, next_food):  # 到下一个点self.next_food = next_food  # 下一个要到的食物self.route.append(next_food)  # 添加到路径self.sum_len += distance[self.now][next_food]  # 总路径增加if next_food in self.not_to_foods:self.not_to_foods.remove(next_food)  # 移出未到的食物点self.now_position = foods[next_food] - foods[self.now]  # 走的方向self.proportion = env.now  # 出发时间def Next_Food(self):  # 根据信息素和路径寻找下一个食物len_not_to_foods = len(self.not_to_foods)  # 没选择的食物个数probability = np.zeros(len_not_to_foods)  # 选择食物的概率for i in range(len_not_to_foods):# 选一个路径的概率是该点信息素^信息素权重*(1/路径长)^路径权重/总和,这里后面会用random.choices就不用除了probability[i] = pheromone[self.now][self.not_to_foods[i]] ** pheromone_w + (1 / distance[self.now][self.not_to_foods[i]]) ** distance_wnext_food = random.choices(self.not_to_foods, probability)  # 根据权重选择下一个点return next_fooddef Change_Pheromone(self):  # 更新信息素矩阵,先添加到一个临时变量中,信息素矩每隔一段时间后自己会挥发并将这个变量添加进去。for i in range(foods_n):new_pheromone[self.route[i]][self.route[i + 1]] += pheromone_Q / self.sum_lennew_pheromone[self.route[i + 1]][self.route[i]] = new_pheromone[self.route[i]][self.route[i + 1]]def run(self):  # 蚂蚁出动global min_distance, min_routewhile True:while self.not_to_foods:  # 未空还能找食物next_food = self.Next_Food()[0]self.Set_Now(next_food)  # 根据信息素和路径去下一个食物位置yield env.timeout(distance[self.now][next_food])  # 等待到达终点self.now = next_food  # 到达位置# 没有食物可以去了next_food = self.route[0]self.Set_Now(next_food)  # 去初始点yield env.timeout(distance[self.now][next_food])  # 等待到达终点self.now = next_food  # 到达位置self.Change_Pheromone()  # 到了初始点之后,更新信息素if min_distance > self.sum_len:min_distance = self.sum_lenmin_route = self.routeself.Initial_Position(random.randint(0,foods_n-1))  # 重新初始化,再来一轮def Change_Pheromone(env):global pheromone, new_pheromonewhile True:# 每隔一段时间,挥发,更新信息素,# 我想要平均走完一波蚂蚁更新一波,那么,我大概需要等待平均总路长的时间(因为假设蚂蚁1m/s)这里就用(foods_n+1)/2,两点间平均距离大概是0.5yield env.timeout((foods_n + 1) / 2)pheromone = np.add((1 - volatilize) * pheromone, new_pheromone)new_pheromone = np.zeros((foods_n, foods_n))# 初始化函数,初始化蚁群,食物,信息素矩阵,
def Initialization(ants_n, foods_n, dimension):''':param ants_n:  蚁群大小:param foods_n: 食物数目:param dimension: 维度:return: 初始化蚁群,食物,信息素矩阵,距离矩阵'''ants = [Ant() for _ in range(ants_n)]  # 蚁群np.random.seed(0)  # 随机数种子,让生成的位置一致,你可以删去foods = np.random.rand(foods_n, dimension)  # 所有食物位置,支持高维,不过绘图只有二维(python三维图太卡了),只测试二维pheromone = np.zeros((foods_n, foods_n))+2  # 信息素矩阵初始为路径长度平均数的倒数之类的distance = np.zeros((foods_n, foods_n))  # 距离矩阵for i in range(foods_n):  # 计算欧氏距离for j in range(foods_n):if i > j:  # 以前算过了,抄过来distance[i][j] = distance[j][i]continueif i == j:  # 一样的位置就是0,不算了continuedistance[i][j] = np.sqrt(np.sum((foods[i] - foods[j]) ** 2))return ants, foods, pheromone, distancedef plt_Refresh():  # 绘图while True:plt.clf()  # 清屏plt.xlim(0, 1)plt.ylim(-0.1, 1)# 绘图plt.text(0.05, -0.05, "now_time = " + str(env.now))for i in range(foods_n):  # 所有的食物点for j in range(i):plt.plot([foods[i][0],foods[j][0]],[foods[i][1],foods[j][1]],linewidth=pheromone[i][j]/100)plt.scatter(foods[i][0], foods[i][1], 100)plt.text(foods[i][0], foods[i][1], i)for i in range(ants_n):  # 所有的蚂蚁点# 到起始食物点,然后加上(起始和终点的向量乘以(当前时间-出发时间)/路长)就是蚂蚁位置,if ants[i].now == ants[i].next_food:position = foods[ants[i].now]else:position = foods[ants[i].now] + ants[i].now_position * (env.now - ants[i].proportion) / \distance[ants[i].now][ants[i].next_food]plt.scatter(position[0], position[1])plt.text(position[0], position[1], i)# 刷新图形plt.draw()plt.pause(time_particles)yield env.timeout(time_particles)def Firing(env):  # env启动env.process(Change_Pheromone(env))  # 启动信息素矩阵env.process(plt_Refresh())  # 启动绘图for i in range(ants_n):  # 启动所有蚂蚁env.process(ants[i].run())ants_n = 15  # 蚂蚁数目,一般1.5*foods_n
foods_n = 10  # 食物数目
dimension = 2  # 维度,建议2,因为绘图只搞了2
min_distance = float("inf")  # 最小距离
min_route = []  # 最小路径
# 一些超参数
pheromone_w = 1  # 信息素权重
distance_w = 6  # 距离权重
volatilize = 0.5  # 信息素挥发比例
pheromone_Q = 10  # 总信息素
run_time = 100  # 模拟时间
time_particles = 0.05  # 绘图间隔
new_pheromone = np.zeros((foods_n, foods_n))
# 绘图
plt.figure()
plt.pause(10)    # 方便我录屏,等10s再出画面你们要删去
env = simpy.Environment()  # 设置环境并启动模拟
ants, foods, pheromone, distance = Initialization(ants_n, foods_n, dimension)  # 初始化,通常,蚁群数目是食物数目1.5倍
print(foods)
Firing(env)  # 开火,启动(添加要模拟的函数)
env.run(until=run_time)  # 运行模拟print(min_route,min_distance)
plt.show()  # 遍历完成后不消失

自己用建议删去 plt.pause(10)这一行,同时,可以调大time_particles,

这是结果:

视频审核还没通过,通过了就放出来

相关文章:

python 实现蚁群算法(simpy带绘图)

这里使用了蚁群算法求解了旅行商问题,同时结合了simpy来绘图 选择下一个食物的函数为: probability[i] pheromone[self.now][self.not_to_foods[i]] ** pheromone_w (1 / distance[self.now][self.not_to_foods[i]]) ** distance_w 该条路概率权重该点…...

OpenAI 董事会宫斗始作俑者?一窥伊尔亚·苏茨克维内心世界

OpenAI 董事会闹剧应该是暂告一个段落了,Sam Altman和Greg Brockman等一众高管均已加入微软,还有员工写联名信逼宫董事会的戏码,关注度已经降下来了。 但是,这场宫斗闹剧的中心人物Ilya Sutskever大家关注度不算太高。他本人是纯粹的技术男,极少抛头露面透露其内心世界。…...

Android App 启动状态有几种?

startup state Android 启动状态(startup state)1.1、冷启动(Cold Start)1.2、温启动(Warm Start)1.3、热启动(Hot Start)1.4、后台启动(Background Start) 优…...

Spring Cloud Alibaba Sentinel 简单使用

Sentinel Sentinel 主要功能Sentinel 作用常见的流量控制算法计数器算法漏桶算法 令牌桶算法Sentinel 流量控制Sentinel 熔断Sentinel 基本使用添加依赖定义资源定义限流规则定义熔断规则如何判断熔断还是限流自定义 Sentinel 异常局部自定义异常全局自定义异常系统自定义异常…...

nvm切换node后,没有npm

当我们想要在不同的 Node.js 版本之间切换的时候,通常会使用 nvm(Node Version Manager) 来完成。但是,当我们在使用 nvm 切换 Node.js 版本的时候,可能会遇到没有 npm 的情况。这种情况通常发生在我们在新环境或者重新…...

Redis-高性能原理剖析

redis安装 下载地址:http://redis.io/download 安装步骤: # 安装gcc yum install gcc# 把下载好的redis-5.0.3.tar.gz放在/usr/local文件夹下,并解压 wget http://download.redis.io/releases/redis-5.0.3.tar.gz tar -zxvf redis-5.0.3.tar…...

ORA-00600 【3948】,ORA-00600 【3949】

前言 这个报错没有从ORA600那个tool中查到。 回顾 环境 环境是windows 11203 rac环境,非归档数据库 有部分数据文件建到了本地文件系统。目标是将部分数据文件通过switch to copy的形式移动到diskgroup里 流程 srvctl关闭双节点, 启动单节点到moun…...

flink 查看写入starrocks的数据量 总行数

针对该connector: https://github.com/StarRocks/docs.zh-cn/blob/main/loading/Flink-connector-starrocks.md...

全链路压测的步骤及重要性

全链路压测是一种系统性的性能测试方法,旨在模拟真实用户场景下的完整操作流程,全面评估软件系统在不同压力下的性能表现。这种测试方法对于保证应用程序的高可用性、稳定性和可扩展性至关重要。 1. 全链路压测概述 全链路压测是在模拟实际用户使用场景的…...

使用Python实现几种底层技术的数据结构

使用Python实现几种底层技术的数据结构 数据结构(data structure)是带有结构特性的数据元素的集合,它研究的是数据的逻辑结构和数据的物理结构以及它们之间的相互关系,并对这种结构定义相适应的运算,设计出相应的算法,并确保经过这…...

前端面试题【72道】

文章目录 1. 说说你对盒子模型的理解2. css选择器有哪些?优先级?哪些属性可以继承?3. 元素水平垂直居中的方法有哪些?如果元素不定宽高呢?4. 怎么理解回流跟重绘?什么场景下会触发?5. 什么是响应…...

OpenGL 绘制文本(QPainter)

文章目录 一、简介二、实现代码三、实现效果一、简介 OpenGL中并没有绘制文本的相关函数,因此这里仍然用的是Qt中的QPainter工具来绘制文本,但是其相关的定位这里仍然会用OpenGL中的坐标转换。这里对其也进行封装一下,方便后续使用。 二、实现代码 TextDrawable.h #ifndef T…...

windows电脑连接Android和iPhone真机调试

windows电脑连接Android和iPhone真机调试 目前用的是Hbuilder X编辑器,在正常情况下,Android手机需要在 "设置 ----> 更多设置 ----->关于手机 ------> 版本号(手指点击5-7下即可打开开发者模式)"(我的是vivo的…...

windows上 adb devices有设备 wsl上没有

终于解决了!!!! TAT,尝试了很多种办法。 比如WSL中的adb和Windows中的adb版本必须一致,一致也没用,比如使用 ln 建立链接也没用。 这个解决办法的前提是windows中的abd是好用的。 ●在windows…...

释放搜索潜力:基于Docker快速搭建ES语义检索系统(快速版),让信息尽在掌握

搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排)、系统架构、常见问题、算法项目实战总结、技术细节以及项目实战(含码源) 专栏详细介绍:搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排)、系统架构、常见问题、算法项目实战总结、技术…...

JS--localStorage设置过期时间的方案(有示例)

原文网址:JS--localStorage设置过期时间的方案(有示例)_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍如何使用localStorage设置数据的过期时间。 问题描述 localStorage是不支持设置过期时间的,cookie虽然支持设置过期时间但它存的数据量很小。所…...

JNPF开发平台凭什么火?

一、关于低代码 JNPF平台在提供无代码(可视化建模)和低代码(高度可扩展的集成工具以支持跨功能团队协同工作)开发工具上是独一无二的。支持简单、快速地构建及不断改进Web端应用程序,可为整个应用程序的生命周期提供全…...

关于“计算机中由于找不到msvcr120.dll,无法继续执行代码5种解决方法

今天,我想和大家分享一下关于“由于找不到msvcr120.dll,无法继续执行代码5种解决方法”的话题。在我们日常的使用中,有时候会遇到这样的问题:在运行某个程序时,突然提示“无法继续执行代码,因为找不到msvcr120.dll”。…...

LR学习笔记——基本面板

文章目录 面板介绍色彩调整区域明暗调整区域纹理及质感色彩饱和 面板介绍 面板如上图所示 基本可分为几个板块:色彩、明暗、纹理及质感、色彩饱和 色彩调整区域 色温:由蓝色和黄色控制色调:由绿色和洋红控制 互补色:蓝色对黄色&…...

Cloud 微服务

架构 一 单体架构 1 概念 将项⽬所有模块(功能)打成jar或者war,然后部署⼀个进程。 互联网早期,一般的网站应用流量较小,只需一个应用,将所有功能代码都部署在一起就可以,这样可以减少开发、…...

GPAK5混合信号可编程器件:重塑嵌入式设计的硬件协处理器

1. 项目概述:当FPGA遇上“超级胶水”,GPAK5如何重塑嵌入式设计在嵌入式系统开发这个行当里干了十几年,我经手过无数“胶水逻辑”电路。所谓“胶水逻辑”,就是那些不起眼但不可或缺的小芯片——几个与非门、一个施密特触发器、一个…...

如何彻底修复机械键盘连击问题:Keyboard Chatter Blocker实用指南

如何彻底修复机械键盘连击问题:Keyboard Chatter Blocker实用指南 【免费下载链接】KeyboardChatterBlocker A handy quick tool for blocking mechanical keyboard chatter. 项目地址: https://gitcode.com/gh_mirrors/ke/KeyboardChatterBlocker 机械键盘连…...

别再混淆了!5分钟搞懂Linux里的TTY、PTS和PTY到底啥关系(附常用命令清单)

别再混淆了!5分钟搞懂Linux里的TTY、PTS和PTY到底啥关系(附常用命令清单) 第一次在Linux终端里敲who命令时,看到输出结果里的pts/0和tty1是不是一头雾水?更别提/dev/ptmx这种神秘路径了。别担心,今天我们就…...

kode:harness:统一团队AI编码方向的工程框架

1. 项目概述:kode:harness,一个为团队AI编码对齐方向而生的工程框架如果你在一个团队里,发现每个开发者用AI助手写代码时,项目就像被几匹脱缰的野马往不同方向拉扯,那么kode:harness就是那套统一的缰绳和导航系统。这不…...

AI编程助手选型指南:从GitHub Awesome清单到高效开发实践

1. 项目概述与价值定位最近在GitHub上闲逛,又发现了一个宝藏仓库——CodandoTV维护的“awesome-ai-coding-assistants”。作为一名在代码堆里摸爬滚打了十多年的老开发,我第一眼看到这个标题就来了兴趣。这不仅仅是一个简单的工具列表,它更像…...

告别第三方工具!用WSL2+usbipd-win在Win11上原生读写Linux格式U盘(保姆级避坑指南)

在Windows 11上原生访问Linux格式存储设备的终极方案 每次插入那块存满代码的Btrfs格式移动硬盘时,Windows资源管理器弹出的"需要格式化"提示总让人血压升高。作为开发者,我们经常需要在不同系统间切换,而文件系统兼容性问题就像一…...

在Node.js后端服务中接入Taotoken并实现异步聊天补全调用

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 在Node.js后端服务中接入Taotoken并实现异步聊天补全调用 对于需要在Node.js后端服务中集成大模型能力的开发者而言,直…...

软件工程师在TVA产业化浪潮中的角色定位与机遇(16)

重磅预告:本专栏将独家连载新书《AI视觉技术:从入门到进阶》精华内容。本书是《AI视觉技术:从进阶到专家》的权威前导篇,特邀美国 TypeOne 公司首席科学家、斯坦福大学博士 Bohan 担任技术顾问。Bohan先生师从美国三院院士、“AI教…...

Godot Pixel Renderer:3D模型实时渲染像素动画的完整指南

1. 项目概述:当3D建模遇上像素艺术如果你和我一样,是个对复古像素艺术情有独钟的游戏开发者,同时又不想被逐帧手绘动画的繁重工作量劝退,那么今天要聊的这个工具,可能会成为你工作流里的“神器”。我最近在捣鼓一个带有…...

提示工程指南:从零掌握与大语言模型高效对话的核心技术

1. 项目概述与核心价值如果你最近在折腾大语言模型,不管是想用它来写代码、分析文档,还是搞点自动化的小工具,大概率都听过一个词——“提示工程”。听起来挺玄乎,好像是什么高深莫测的新学科。其实说白了,它就是你跟A…...