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_lenpheromone = 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,然后部署⼀个进程。 互联网早期,一般的网站应用流量较小,只需一个应用,将所有功能代码都部署在一起就可以,这样可以减少开发、…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
