基于蚁群算法的TSP问题建模求解(Python)

基于蚁群算法的TSP问题建模求解

  • 一、蚁群优化算法(Ant Colony Optimization,ACO)
    • 1.1 蚁群算法的起源——“双桥实验”
    • 1.2 蚁群优化算法思想
    • 1.3 蚁群算法应用于求解组合优化问题
  • 二、基于蚁群算法的TSP问题建模求解
    • 2.1 旅行商问题(Travelling salesman problem,TSP)
    • 2.2 蚁群算法求解TSP问题思想、步骤、流程图
    • 2.3 实例分析
    • 2.4 完整代码
    • 2.5 运行结果

一、蚁群优化算法(Ant Colony Optimization,ACO)

蚁群系统(Ant System或Ant Colony System(是由意大利学者Dorigo、Maniezzo等人于20世纪90年代(1992年)首先提出来的。他们在研究蚂蚁觅食的过程中,发现单个蚂蚁的行为比较简单,但是蚁群整体却可以体现一些智能的行为。例如蚁群可以在不同的环境下,寻找最短到达食物源的路径。这是因为蚁群内的蚂蚁可以通过某种信息机制实现信息的传递。后又经进一步研究发现,蚂蚁会在其经过的路径上释放一种可以称之为“信息素”的物质,蚁群内的蚂蚁对“信息素”具有感知能力,它们会沿着“信息素”浓度较高路径行走,而每只路过的蚂蚁都会在路上留下“信息素”,这就形成一种类似正反馈的机制,这样经过一段时间后,整个蚁群就会沿着最短路径到达食物源了。

1.1 蚁群算法的起源——“双桥实验”

双桥实验在研究蚂蚁觅食行为过程中,人们发现,尽管单只蚂蚁的能力十分有限,但整个蚁群却在觅食过程中可以发现从蚁巢到食物源的最短路径。在觅食过程中,蚂蚁通过“媒介质”来协调它们之间的行动。所谓“媒介质”指的是一种以环境的变化为媒介的间接通信方式。蚂蚁在寻找食物时,以其产生的被称为信息素的化学物质作为媒介而间接的传递信息。当蚂蚁从蚁穴走到食物源,从而形成了含有信息素的路径。

蚂蚁从A点出发,随机选择路线ABD或ACD。经过9个时间单位时:走ABD的蚂蚁到达终点,走ACD的蚂蚁刚好走到C点。

经过18个时间单位时:走ABD的蚂蚁到达终点后得到食物又返回了起点A,而走ACD的蚂蚁刚好走到D点。

最后的极限是所有的蚂蚁只选择ABD路线。(正反馈过程)

1.2 蚁群优化算法思想

蚁群优化算法思想:蚁群的自组织行为通过遗留在来往路径的信息素Pheromone)挥发的化学性物质来进行通信和协调。

  • 蚁群算法是对自然界蚂蚁的寻径方式进行模似而得出的一种仿生优化算法:蚂蚁在运动过程中,能够在它所经过的路径上留下信息素(pheromone)的物质进行信息传递,而且蚂蚁在运动过程中能够感知这种物质,并以此指导自己的运动方向。
  • 由大量蚂蚁组成的蚁群集体行为便表现出一种信息正反馈现象:某一路径上走过的蚂蚁越多,则后来者选择该路径的概率就越大。

1.3 蚁群算法应用于求解组合优化问题

将蚁群算法应用于解决优化问题的基本思路为:用蚂蚁的行走路径表示待优化问题的可行解,整个蚂蚁群体的所有路径构成待优化问题的解空间。路径较短的蚂蚁释放的信息素量较多,随着时间的推进,较短的路径上累积的信息素浓度逐渐增高,选择该路径的蚂蚁个数也愈来愈多。最终,整个蚂蚁会在正反馈的作用下集中到最佳的路径上,此时对应的便是待优化问题的最优解。

二、基于蚁群算法的TSP问题建模求解

2.1 旅行商问题(Travelling salesman problem,TSP)

刘兴禄 -《运筹优化常用模型、算法及案例实战:Python+Java实现》总结了TSP问题共有3种数学模型,本文采用DFJ模型,见基于禁忌搜索的TSP问题建模求解(Java)。

2.2 蚁群算法求解TSP问题思想、步骤、流程图

蚂蚁通过信息素指导寻优过程,每次迭代更新信息素,不断寻优。
蚂蚁在运动过程中,能够在它所经过的路径上留下信息素(pheromone)的物质进行信息传递,对应于求解TSP中
每只蚂蚁根据路径上的信息素和启发式信息(两城市间距离)独立地选择下一座城市,在时刻t,蚂蚁k从城市i转移到城市j的概率为:
p i j k ( t ) = { [ τ i j ( t ) ] α [ η i j ( t ) ] β ∑ s ∈ J k ( i ) [ τ i s ( t ) ] α [ η i s ( t ) ] β , j ∈ J k ( i ) 0 , j ∉ J k ( i ) \begin{align} p_{i j}^{k}(t)=\left\{\begin{array}{ll} \frac{\left[\tau_{i j}(t)\right]^{\alpha}\left[\eta_{i j}(t)\right]^{\beta}}{\sum_{s \in J_{k}(i)}\left[\tau_{i s}(t)\right]^{\alpha}\left[\eta_{i s}(t)\right]^{\beta}}, & j \in J_{k}(i) \\ 0, & j \notin J_{k}(i) \end{array}\right.\end{align} pijk(t)={sJk(i)[τis(t)]α[ηis(t)]β[τij(t)]α[ηij(t)]β,0,jJk(i)j/Jk(i)
其中:

  • α \alpha α β \beta β分别表示信息素和启发式银子的相对重要程度。
  • τ i j \tau_{ij} τij表示城市i到j的信息素。
  • η i j = 1 / d i j \eta_{ij}=1/d_{ij} ηij=1/dij d i j d_{ij} dij为城市间距离矩阵。
  • J k ( i ) = { 1 , 2 , ⋯ , n } − t a b u k J_k(i)=\{1,2,\cdots,n\}- {tabu_k} Jk(i)={1,2,,n}tabuk t a b u k {tabu_k} tabuk是蚂蚁k已经访问过城市。

蚂蚁在运动过程中能够感知信息素,并以此指导自己的运动方向
当所有蚂蚁完成一次周游后,各路径上的信息素将进行更新:
τ i j ( t + n ) = ( 1 − ρ ) τ i j + Δ τ i j \begin{align} \tau_{ij}(t+n)=(1-\rho)\tau_{ij}+\Delta\tau_{ij}\end{align} τij(t+n)=(1ρ)τij+Δτij

Δ τ i j = ∑ k = 1 m Δ τ i j k \begin{align}\Delta\tau_{ij}=\sum_{k=1}^{m} \Delta\tau_{ij}^{k}\end{align} Δτij=k=1mΔτijk
Δ τ i j k = { Q L k , if 蚂蚁 k 在本次周游中经过边  i j 0 , otherwise  \begin{align} \Delta \tau_{i j}^{k}=\left\{\begin{array}{ll} \frac{Q}{L_{k}}, & \text { if 蚂蚁}k\text{ 在本次周游中经过边 } ij \\ 0, & \text { otherwise } \end{array}\right. \end{align} Δτijk={LkQ,0, if 蚂蚁k 在本次周游中经过边 ij otherwise 
其中:

  • ρ \rho ρ 0 < ρ < 1 0<\rho<1 0<ρ<1)表示路径上信息素的蒸发系数;
  • Q为正常数;
  • L k L_k Lk表示第k只蚂蚁在本次周游中所走过路径的长度。

蚁群算法求解TSP问题步骤如下:

  1. 初始化。问题相关参数(城市数量、城市间距离矩阵)、算法参数(蚂蚁数量、 α \alpha α β \beta β ρ \rho ρ Q Q Q m a x g e n maxgen maxgen)。
  2. 为每只蚂蚁构建路径。随机初始化蚂蚁路径的起点城市,根据式(1)计算每个城市的选择概率,通过轮盘赌选择下一个城市,直至路径蚂蚁路径形成一条TSP回路。
  3. 根据式(2)更新信息素矩阵。
  4. 检查终止条件
  5. 输出最优值

蚁群算法求解TSP问题算法流程图:

2.3 实例分析

在这里插入图片描述
在这里插入图片描述

2.4 完整代码

采用TSP问题标准测试函数att48,城市数量48进行测试,

# -*- coding: utf-8 -*-
import itertools
import random
import copy
import numpy as np
from scipy.spatial import distance
from typing import List, Dict, Tuple
from matplotlib import pyplot as plt
from numpy import ndarraynp.set_printoptions(threshold=np.inf, linewidth=np.inf)# 参数
'''
ALPHA:信息启发因子,值越大,则蚂蚁选择之前走过的路径可能性就越大,值越小,则蚁群搜索范围就会减少,容易陷入局部最优
BETA:Beta值越大,蚁群越就容易选择局部较短路径,这时算法收敛速度会加快,但是随机性不高,容易得到局部的相对最优
'''# 城市距离和信息素
class AntColonyOpt:def __init__(self, problem):self.problem = problemself.num_city = problem.num_cityself.city_coord = problem.city_coordself.city_list = problem.city_listself.distance = Noneself.pheromone = Noneself.num_ant = 48self.alpha = 1.self.beta = 2.self.rho = .5  # 信息素的蒸发率self.Q = 100.self.tau = np.ones(shape=(self.num_city, self.num_city))  # 信息素self.eta = Noneself.ant_list = []self.best_ant = Noneself.gen = 0  # 初始化迭代次数self.max_gen = 1e3self.initialize()# 初始化def initialize(self):# 初始化城市之间的距离city_coord = np.asarray(list(self.city_coord.values()))self.distance = distance.cdist(city_coord, city_coord, 'euclidean')self.eta = 1 / self.distance# 初始城市之间的信息素self.pheromone = np.ones(shape=(self.num_city, self.num_city), dtype=np.float64)# self.pheromone = [[1.0 for col in range(num_city)] for raw in range(num_city)]for i in range(self.num_ant):ant = {"id": i,"path": [i],"path_length": 1 << 31,"tabu": {i},"allow": [True if city != i else False for city in self.city_list],"move_count": 0}self.ant_list.append(ant)self.best_ant = {"id": -1,"path": [0],"path_length": 1 << 31,"tabu": set(),"allow": [True] * self.num_city,"move_count": 0}  # 初始最优解def build_path(self, ant):while ant["move_count"] < self.num_city - 1:# 移动到下一个城市next_city = self.select(ant)self.move(ant, next_city)def select(self, ant):# 计算选择概率: i 当前城市, j 遍历allow中j城市ant_path = ant["path"]i = ant_path[-1]  # 当前城市numerator = np.array([(self.tau[i][j] ** self.alpha) * (self.eta[i][j] ** self.beta) if ant["allow"][j] is True else 0 for j in self.city_list])denominator = np.sum(numerator)p_select = numerator / denominatorp_cum = np.cumsum(p_select)# 轮盘赌选择select = Noner = np.random.uniform(0, 1)for city in self.city_list:if ant["allow"][city] is True:if r < p_cum[city]:select = citybreakreturn select# 移动操作def move(self, ant, next_city):ant["path"].append(next_city)ant["allow"][next_city] = Falseant["tabu"].add(next_city)ant["move_count"] += 1def clear(self):self.ant_list = []random_city = np.random.randint(low=0, high=self.num_city)for i in range(self.num_ant):ant = {"id": random_city,"path": [random_city],"path_length": 1 << 31,"tabu": {random_city},"allow": [True if city != random_city else False for city in self.city_list],"move_count": 0}self.ant_list.append(ant)# 运行蚁群优化算法def run(self):trace = []while self.gen <= self.max_gen:# 遍历每一只蚂蚁for ant in self.ant_list:# 搜索一条路径self.build_path(ant)ant["path_length"] = self.calc_path_length(ant["path"])# 与当前最优蚂蚁比较, 更新最优解if ant["path_length"] < self.best_ant["path_length"]:self.best_ant = copy.deepcopy(ant)# print(ant)# 更新信息素self.update_pheromone()print(u"迭代次数:", self.gen, u"最佳路径总距离:", int(self.best_ant["path_length"]))self.gen += 1trace.append((self.best_ant['path'], self.best_ant['path_length']))self.clear()self.draw([(self.best_ant["path"], self.best_ant["path_length"])])# 计算路径总距离def calc_path_length(self, path):total_distance = 0.for i, j in itertools.pairwise(path):total_distance += self.distance[i][j]i = path[-1]j = path[0]total_distance += self.distance[i][j]return total_distancedef draw(self, trace: List[Tuple[List, float]]) -> None:"""最优路径可视化:param trace:每次迭代过程中最优路径及路径长度,trace是一个list,len(trace)=max_gen:return:"""iteration = np.arange(len(trace))obj_value = [trace[i][1] for i in range(len(trace))]plt.plot(iteration, obj_value)plt.show()final_solution, final_obj_value = trace[-1]x = []y = []for city in final_solution:city_x, city_y = self.city_coord[city]x.append(city_x)y.append(city_y)city_x, city_y = self.city_coord[final_solution[0]]x.append(city_x)y.append(city_y)plt.plot(x, y, 'o-', alpha=1, linewidth=2)plt.savefig("ACO-TSP.png", bbox_inches="tight")def update_pheromone(self):"""更新信息素:return:"""delta_tau = np.zeros(shape=(self.num_city, self.num_city))for ant in self.ant_list:for i in range(1, self.num_city):start, end = ant["path"][i - 1], ant["path"][i]# 在路径上的每两个相邻城市间留下信息素,与路径总距离反比delta_tau[start][end] += self.Q / ant["path_length"]delta_tau[end][start] = delta_tau[start][end]for i in range(self.num_city):for j in range(self.num_city):self.tau[i][j] = (1 - self.rho) * self.tau[i][j] + delta_tau[i][j]class TSP(object):num_city: int = None  # 城市数量city_coord: Dict[int, Tuple[int, int]] = None  # 城市标号及对应坐标,示例 1:(23,312)distance: ndarray = None  # 城市间距离矩阵pheromone: List = Nonedef __init__(self, city_coord):self.num_city = len(city_coord)self.city_coord = city_coordself.city_list = city_coord.keys()self.distance = np.empty(shape=(self.num_city, self.num_city), dtype=np.float64)if __name__ == '__main__':city_coord_att48 = {0: (6734, 1453),1: (2233, 10),2: (5530, 1424),3: (401, 841),4: (3082, 1644),5: (7608, 4458),6: (7573, 3716),7: (7265, 1268),8: (6898, 1885),9: (1112, 2049),10: (5468, 2606),11: (5989, 2873),12: (4706, 2674),13: (4612, 2035),14: (6347, 2683),15: (6107, 669),16: (7611, 5184),17: (7462, 3590),18: (7732, 4723),19: (5900, 3561),20: (4483, 3369),21: (6101, 1110),22: (5199, 2182),23: (1633, 2809),24: (4307, 2322),25: (675, 1006),26: (7555, 4819),27: (7541, 3981),28: (3177, 756),29: (7352, 4506),30: (7545, 2801),31: (3245, 3305),32: (6426, 3173),33: (4608, 1198),34: (23, 2216),35: (7248, 3779),36: (7762, 4595),37: (7392, 2244),38: (3484, 2829),39: (6271, 2135),40: (4985, 140),41: (1916, 1569),42: (7280, 4899),43: (7509, 3239),44: (10, 2676),45: (6807, 2993),46: (5185, 3258),47: (3023, 1942),}problem = TSP(city_coord_att48)aco = AntColonyOpt(problem)aco.run()

2.5 运行结果

采用TSP问题标准测试函数att48,城市数量48,最优解为33523)本文迭代次数:1000最佳路径总距离:35408,其他文章基于禁忌搜索的TSP问题建模求解(Java)结果为34974.67245297696。本文求解结果如下图:

参考:

  • 蚁群算法(Ant Colony Optimization)
  • 一文搞懂什么是蚁群优化算法(Ant Colony Optimization, ACO)【附应用举例】
  • 蚁群算法原理及其实现(python)

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

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

相关文章

格式工厂怎么转换视频方向

格式工厂因为其免费、操作简单、功能齐全的多重优势&#xff0c;深受大家的喜欢。格式工厂具有可以转换视频、音频、去水印、转换GIF、图片转换、PDF合并、PDF转换等功能&#xff0c;然而在对视频进行剪辑的时候&#xff0c;往往会发现找不到格式工厂的转换视频方向的功能&…

Kibana错误【Kibana server is not ready yet】

docker部署kibana成功后&#xff0c;访问http://localhost:5601 ,页面返回“Kibana server is not ready yet” 运行 docker logs kibana 后提示 该错误提示为kibana的版本和es的版本不一致&#xff0c;将两个组件的版本更新一致即可 还有另外一种错误 在kibana的kibana.yml配…

AI老照片上色-DeOldify

&#x1f3e1; 个人主页&#xff1a;IT贫道-CSDN博客 &#x1f6a9; 私聊博主&#xff1a;私聊博主加WX好友&#xff0c;获取更多资料哦~ &#x1f514; 博主个人B栈地址&#xff1a;豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录 1. 老照片上色原理 2…

windows10+ubuntu20.04双系统中,ubuntu系统显示home空间不足的扩容方法

实际上网上有两种扩容方法&#xff0c;除了本文的方法外&#xff0c;另一种是在使用启动U盘打开试用ubuntu&#xff0c;应该涉及到nvidia显卡驱动问题故未采用。另一种即本文。 最开始安装双系统时内存分配没有分配好&#xff0c;给ubuntu系统分配的空间较小,导致了后来的的问…

Multimodal Segmentation of Medical Images with Heavily Missing Data

F是mapping function 吐槽 图3太简单了吧。作者未提供代码

iOS14 Widget 小组件调研

桌面小组件是iOS14推出的一种新的桌面内容展现形式。 根据苹果的统计数据&#xff0c;“一般用户每天进入主屏幕的次数超过90次”&#xff0c;如果有一个我们应用的小组件在桌面&#xff0c;每天都有超过90次曝光在用户眼前的机会&#xff0c;这绝对是一个顶级的流量入口。 “…

Oracle之 第1篇 Oracle 11g 简介

目录 Oracle之 第1篇 Oracle 11g 简介 1.1 Oracle概述 1.2 Oracle 11g 系统的体系结构★ 1.1 Oracle物理结构 1.1物理结构--数据文件 1.1.2 物理结构---日志文件 1.1.3 物理结构---控制文件 1.2.4 配置文件 Oracle之 第1篇 Oracle 11g 简介 1.1 Oracle概述 常用…

无线与局域网技术期末划题自制答案

简答题 1.描述5G的三大应用场景&#xff1f; 5G的三大应用场景包括增强型移动宽带&#xff08;eMBB&#xff09;、超可靠低延迟通信&#xff08;URLLC&#xff09;和大规模机器类型通信&#xff08;mMTC&#xff09;。增强型移动宽带&#xff08;eMBB&#xff09;主要用于支持…

android自定义时间选择

自定义时间选择器&#xff0c;可以更改到年月日&#xff0c;时分秒 一、自定义DatePicker public class CustomDatePicker {/*** 定义结果回调接口*/public interface ResultHandler {void handle(String time);}public enum SCROLL_TYPE {HOUR(1),MINUTE(2);SCROLL_TYPE(int …

【Web】CTFSHOW命令执行刷题记录1

目录 web29 web30 web31 web32 web33 web34 web35 web36 web37-39 web40 web41 &#xff08;y4✌脚本&#xff09; web42 -44 web45 web46 -49 web50 web51 web52 web53 web54 期末复习不了一点&#xff0c;不如做点旧题醒一醒手感。每一题都尽量用不同payl…

@FunctionalSpringBootTest 和@SpringBootTest注解的区别

FunctionalSpringBootTest 和 SpringBootTest 是Spring框架中用于测试的两个不同注解。下面是它们之间的主要区别&#xff1a; 用途和范围&#xff1a; SpringBootTest&#xff1a;这个注解用于需要测试Spring应用程序上下文的场合。它会加载完整的应用程序上下文&#xff0c;适…

插件和工具汇总

插件和工具汇总 【一】MyBatis Log插件【二】热部署【三】一些快捷键 【一】MyBatis Log插件 能够自动拼接参数生成执行的SQL语句&#xff0c;可以更清晰看到执行本次接口调用的所有sql执行条数。在我们执行myabtis的时候&#xff0c;有的时候报错知道哪里错了&#xff0c;但是…

亚马逊,速卖通,美客多卖家怎么才能安全及有效的积累产品的评论

测评补单对于亚马逊、速卖通等平台卖家来说&#xff0c;是一种重要的运营手段之一&#xff0c;通过测评补单快速增加产品的销量、评论数量&#xff0c;提升排名&#xff0c;从而打造爆款产品。 测评养号的好处包括&#xff1a; 1. 提升店铺信誉&#xff0c;制造爆款&#xff…

【大模型】大型模型飞跃升级—文档图像识别领域迎来技术巨变

写在前面 2023年12月31日&#xff0c;第十九届中国图象图形学学会青年科学家会议在广州举行&#xff0c;由中国图象图形学学会主办。 该会议的目标是促进青年科学家之间的交流与合作&#xff0c;以提升我国在图像图形领域的科研水平和创新能力。 由中国图象图形学学会和上海合合…

我在考 pmp,想知道如何去学习 pmbok?

PMP新版大纲加入了ACP敏捷管理的内容&#xff0c;而且还不少&#xff0c;敏捷混合题型占到了 50%&#xff0c;很多人都觉得考试难度提升了&#xff0c;我最开始备考的时候也被折磨过一段时间&#xff0c;但是后面还是找到了方法&#xff0c;3A通过了考试&#xff0c;也算有点经…

【EAI 005】EmbodiedGPT:通过具身思维链进行视觉语言预训练的具身智能大模型

论文描述&#xff1a;EmbodiedGPT: Vision-Language Pre-Training via Embodied Chain of Thought 论文作者&#xff1a;Yao Mu, Qinglong Zhang, Mengkang Hu, Wenhai Wang, Mingyu Ding, Jun Jin, Bin Wang, Jifeng Dai, Yu Qiao, Ping Luo 作者单位&#xff1a;The Universi…

MyBatis:自定义 typeHandler 处理枚举类型

MyBatis 枚举类型typeHandler 枚举类型 枚举类型&#xff0c;在 Java 中属于基本数据类型&#xff0c;而不是构造数据类型&#xff0c;用于声明一组命名的常数。枚举可以根据 Integer 、Long 、Short 或 Byte 中的任意一种数据类型来创建一种新型变量。这种变量可以设置为已经…

npm安装vue,添加淘宝镜像

如果是第一次使用命令栏可能会遇到权限问题。 解决vscode无法运行npm和node.js命令的问题-CSDN博客 安装 在vscode上面的导航栏选择terminal打开新的命令栏 另外可能会遇到网络或者其他的问题&#xff0c;可以添加淘宝镜像 npm install -g cnpm --registryhttps://registry.…

Appium,多应用程序平台的 UI 自动化

Appium是一个开源的移动应用程序自动化测试工具&#xff0c;可以用于跨平台的UI自动化&#xff0c;包括iOS、Android、Web和Windows应用程序。它基于WebDriver协议&#xff0c;支持多种编程语言&#xff0c;如Java、Python、Ruby,Javascript、C#等。 Appium的设计理念是“一次…

websocket: 了解并利用nodejs实现webSocket前后端通信

目录 第一章 前言 1.1 起源 1.2 短轮询与长轮询 1.2.1 短轮询 1.2.2 长轮询 1.2.3 长连接&#xff08;SSE&#xff09; 1.2.4 websocket 第二章 利用Node以及ws创建webSocket服务器 2.1 创建ws服务器&#xff08;后端部分&#xff09; 2.1.1 了解一下 2.1.2 代创建W…