禁忌搜索算法(TS算法)求解实例---旅行商问题 (TSP)
目录
- 一、采用TS求解 TSP
- 二、 旅行商问题
- 2.1 实际例子:求解 6 个城市的 TSP
- 2.2 ==**求解该问题的代码**==
- 2.3 代码运行过程截屏
- 2.4 代码运行结果截屏(后续和其他算法进行对比)
- 三、 ==如何修改代码?==
- 3.1 减少城市坐标,如下:
- 3.2 增加城市坐标,如下:
- 四、 禁忌搜索算法 (Tabu Search, TS) 原理
- 4.1 TS算法定义
- 4.2 TS算法算法的基本思想
- 4.3 TS算法算法的工作原理
- 4.4 TS算法算法的关键要素
- 4.5 TS算法算法的优缺点
- 4.5.1 优点
- 4.5.2 缺点
- 4.6 TS算法算法的应用场景
一、采用TS求解 TSP
求解代码在文中,后续会出其他算法求解TSP问题,你们参加数学建模竞赛只需要会改代码即可。
用来对比此专栏的
遗传算法(GA算法)求解实例—旅行商问题 (TSP)
粒子群算法(PSO算法)求解实例—旅行商问题 (TSP)
模拟退火算法(SA算法)求解实例—旅行商问题 (TSP)
蚁群算法(ACO算法)求解实例—旅行商问题 (TSP)
注意每次运行算法得到的结果可能不太一样。
我知道大家对原理性的东西不感兴趣,我把原理性的东西放在后面,大家如果需要写数模论文可以拿去,但是记得需要改一改,要不然查重过不去。
二、 旅行商问题
2.1 实际例子:求解 6 个城市的 TSP
假设有 6 个城市,其坐标如下:
| 城市 | X 坐标 | Y 坐标 |
|---|---|---|
| 0 | 10 | 20 |
| 1 | 30 | 40 |
| 2 | 20 | 10 |
| 3 | 40 | 30 |
| 4 | 10 | 10 |
| 5 | 50 | 20 |
目标是找到一个经过所有城市且总距离最短的路径。
2.2 求解该问题的代码
import numpy as np
import random# 定义城市坐标
cities = np.array([[10, 20],[30, 40],[20, 10],[40, 30],[10, 10],[50, 20]
])# 计算两城市之间的欧几里得距离
def calculate_distance(city1, city2):return np.sqrt(np.sum((city1 - city2) ** 2))# 计算总旅行距离
def total_distance(path):distance = 0for i in range(len(path) - 1):distance += calculate_distance(cities[path[i]], cities[path[i + 1]])distance += calculate_distance(cities[path[-1]], cities[path[0]]) # 回到起点return distance# 生成初始解
def generate_initial_solution(num_cities):return list(np.random.permutation(num_cities))# 生成邻域解(通过交换路径中的两个城市)
def get_neighborhood(solution):neighbors = []for i in range(len(solution)):for j in range(i + 1, len(solution)):neighbor = solution.copy()neighbor[i], neighbor[j] = neighbor[j], neighbor[i]neighbors.append(neighbor)return neighbors# 禁忌搜索算法主函数
def tabu_search(cities, tabu_size=10, max_iter=500):num_cities = len(cities)# 初始化禁忌表tabu_list = []# 生成初始解current_solution = generate_initial_solution(num_cities)current_distance = total_distance(current_solution)# 初始化最佳解best_solution = current_solution.copy()best_distance = current_distancefor iteration in range(max_iter):# 生成所有邻域解neighbors = get_neighborhood(current_solution)neighbors_distances = [(neighbor, total_distance(neighbor)) for neighbor in neighbors]# 在禁忌表之外选择最优邻域解next_solution = Nonenext_distance = float('inf')for neighbor, distance in neighbors_distances:if neighbor not in tabu_list and distance < next_distance:next_solution = neighbornext_distance = distance# 更新当前解current_solution = next_solutioncurrent_distance = next_distance# 更新禁忌表tabu_list.append(current_solution)if len(tabu_list) > tabu_size:tabu_list.pop(0)# 更新全局最佳解if current_distance < best_distance:best_solution = current_solution.copy()best_distance = current_distanceprint(f"Iteration {iteration + 1}: Best distance = {best_distance:.2f}")return best_solution, best_distance# 运行禁忌搜索算法
best_path, best_distance = tabu_search(cities)
print("Best path:", best_path)
print("Best distance:", best_distance)
2.3 代码运行过程截屏

2.4 代码运行结果截屏(后续和其他算法进行对比)

三、 如何修改代码?
这一部分是重中之重,大家参加数学建模肯定是想跑出自己的结果,所以大家只需要把自己遇到的数学问题,抽象成TSP问题,然后修改代码的城市坐标,然后运行即可。
# 定义城市坐标
cities = np.array([[10, 20],[30, 40],[20, 10],[40, 30],[10, 10],[50, 20]
])
3.1 减少城市坐标,如下:
# 定义城市坐标
cities = np.array([[10, 20],[30, 40],[20, 10],[40, 30]
])
3.2 增加城市坐标,如下:
# 定义城市坐标
cities = np.array([[10, 20],[30, 40],[20, 10],[40, 30],[30, 40],[20, 10],[10, 10],[50, 20]
])
四、 禁忌搜索算法 (Tabu Search, TS) 原理
4.1 TS算法定义
禁忌搜索算法 (Tabu Search, TS) 是一种基于局部搜索的启发式优化算法,由 Fred Glover 在 1986 年提出。禁忌搜索算法通过维护一个“禁忌表”来记录最近访问过的解或搜索路径,从而避免算法在搜索过程中陷入循环或局部最优解。通过合理的禁忌策略和多样化策略,TS 算法能够跳出局部最优解,找到全局最优解或近似最优解。
4.2 TS算法算法的基本思想
禁忌搜索算法的核心思想是对局部搜索进行改进。传统的局部搜索算法可能会因为陷入局部最优解或搜索循环而难以找到全局最优解。禁忌搜索算法通过在每次迭代中选择当前邻域中的最优解作为下一步搜索方向,并使用一个称为“禁忌表”的数据结构来记录已访问过的解或路径,从而避免回到先前访问过的解。禁忌表的内容会动态更新,以使得搜索能够进行更广泛的探索。
4.3 TS算法算法的工作原理
-
初始化:
- 随机生成一个初始解
s作为当前解。 - 设置一个空的禁忌表
T和最大禁忌表长度L,定义最大迭代次数max_iter。
- 随机生成一个初始解
-
生成邻域解:
- 对当前解
s,生成其邻域解集合N(s)。通常,邻域解是通过对当前解的微小修改(如交换、移位等)生成的多个新解。
- 对当前解
-
选择最优邻域解:
- 在邻域解集合
N(s)中,选择一个不在禁忌表中的最佳解s',使得其目标函数值最优(通常是最小化问题中的最小值)。 - 若所有邻域解均在禁忌表中,则可以选择一个禁忌解作为当前解。
- 在邻域解集合
-
更新禁忌表:
- 将新的解
s'添加到禁忌表T中,以避免在未来的搜索过程中重新访问该解。 - 若禁忌表长度超过最大限制
L,则删除最早加入的解。
- 将新的解
-
更新当前解和全局最优解:
- 将当前解
s更新为新解s'。 - 如果
s'的目标函数值优于全局最优解s*,则更新全局最优解s*。
- 将当前解
-
迭代和终止:
- 重复步骤 2-5,直到达到最大迭代次数
max_iter或找到满意解为止。
- 重复步骤 2-5,直到达到最大迭代次数
4.4 TS算法算法的关键要素
-
禁忌表(Tabu List):
- 禁忌表是一个用来存储禁忌解的集合,用于防止搜索过程中的循环和回溯。禁忌表的长度
L通常设定为一个固定值,当禁忌表超过最大长度时,将最早的解移出禁忌表。
- 禁忌表是一个用来存储禁忌解的集合,用于防止搜索过程中的循环和回溯。禁忌表的长度
-
邻域结构:
- 邻域结构决定了每次搜索所能达到的解空间范围。常见的邻域操作有交换、移位、反转等操作。
-
禁忌策略:
- 禁忌策略决定了哪些解被列入禁忌表。在一般情况下,禁忌解是根据一定规则选定的,以确保多样化搜索和有效避免循环。
-
解的多样化策略:
- 在搜索过程陷入局部最优时,解的多样化策略用于打破停滞状态,推动搜索进入新的区域。
4.5 TS算法算法的优缺点
4.5.1 优点
- 跳出局部最优:通过禁忌表机制,TS 算法能够有效避免局部最优解,继续在解空间中进行搜索。
- 灵活性强:TS 算法可以应用于多种优化问题,通过调整邻域结构和禁忌策略,可以针对不同问题进行适应性调整。
- 易于实现:相较于一些复杂的优化算法,TS 算法较为简单,易于实现。
4.5.2 缺点
- 计算开销较大:在大规模问题中,生成邻域解和维护禁忌表可能会带来较高的计算开销。
- 参数敏感:算法性能对禁忌表长度、邻域结构和禁忌策略较为敏感,需要根据具体问题进行调优。
- 不保证全局最优解:虽然 TS 算法能跳出局部最优,但不能保证一定找到全局最优解。
4.6 TS算法算法的应用场景
- 旅行商问题 (TSP):寻找经过所有城市的最短路径。
- 车辆路径问题 (VRP):优化多辆车在多个配送点的路径。
- 生产调度与资源分配:如工作车间调度、工厂生产排程、任务分配等。
- 网络设计与路由优化:优化计算机网络或物流网络中的节点连接和路由路径。
- 组合优化问题:如背包问题、图着色问题、设备布局问题等。
相关文章:
禁忌搜索算法(TS算法)求解实例---旅行商问题 (TSP)
目录 一、采用TS求解 TSP二、 旅行商问题2.1 实际例子:求解 6 个城市的 TSP2.2 **求解该问题的代码**2.3 代码运行过程截屏2.4 代码运行结果截屏(后续和其他算法进行对比) 三、 如何修改代码?3.1 减少城市坐标,如下&am…...
Rust 所有权 简介
文章目录 发现宝藏1. 所有权基本概念2. 所有权规则3. 变量作用域4. 栈与堆4.1 栈(Stack)4.2 堆(Heap) 5. String类型5.1 String 类型5.2 String 的内存分配5.3 所有权与内存管理5.4 String 与切片 6. 变量与数据交互方式6.1 移动&…...
linux-网络管理-防火墙配置
Linux 网络管理:防火墙配置 1. 防火墙概述 防火墙是保护计算机系统和网络免受未经授权访问和网络攻击的安全机制。Linux 系统中,防火墙通过控制进入和离开网络的数据包,实现网络流量的过滤和管理。 Linux 上的防火墙配置工具有多种&#x…...
【springboot】实现文件上传和下载
目录 1. 新建一个springboot项目2. 配置文件application.propertiesapplication.yml 3. 控制类实现文件上传和下载4. 测试 1. 新建一个springboot项目 新建一个springboot项目,选择web,默认即可. 主要pom配置文件如下: <parent><gr…...
【RabbitMQ】RabbitMQ如何保证数据的可靠性,RabbitMQ如何保证数据不丢失,数据存储
【RabbitMQ】RabbitMQ如何保证数据的可靠性,RabbitMQ如何保证数据不丢失,数据存储 RabbitMQ通过一系列机制来确保数据(即消息)在传输和处理过程中不丢失。这些机制主要包括以下几个方面: 1. 消息持久化 持久化消息&a…...
Redis 篇-初步了解 Redis 持久化、Redis 主从集群、Redis 哨兵集群、Redis 分片集群
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 分布式缓存概述 2.0 Redis 持久化 2.1 RDB 持久化 2.1.1 RDB 的 fork 原理 2.2 AOF 持久化 2.3 RDB 与 AOF 之间的区别 3.0 Redis 主从集群 3.1 搭建主从集群 3.2…...
算法基础-二分查找
左闭右闭 [ left,right ] [1,1]可以 while( left < right ) if( a[mid] > target ) right mid - 1 else if( a[mid] < target ) left mid 1 左闭右开 [ left,right ) …...
LeetCode:1184. 公交站间的距离 一次遍历数组,复杂度O(n)
1184. 公交站间的距离 today 1184 公交站间的距离 题目描述 环形公交路线上有 n 个站,按次序从 0 到 n - 1 进行编号。我们已知每一对相邻公交站之间的距离,distance[i] 表示编号为 i 的车站和编号为 (i 1) % n 的车站之间的距离。 环线上的公交车都…...
牛客周赛 Round 60(A,B,C,D,E,F)
比赛链接 官方题解 这场基本都是数学题,官方题解讲的还不错,F能听懂的话其实不难。E是一个球盒模型的组合问题,F是化简递推式,成环时的解决方法很不错。 A 困难数学题 思路: 一个数异或两次结果为 0 0 0ÿ…...
vueCropper裁剪图片(不模糊)以及记录使用方法
需求:上传限定比例的图片。前端框架是vue3 element plus。 问题:使用vueCropper后比例固定。但是上传后的图片很模糊 vueCropper官网 解决办法 vueCropper中有一个full和high两个参数,记得开启 const options: any reactive({img: , // 原…...
【HTML】HTML页面和常见标签
文章目录 什么是前端HTML 页面编写如何快速生成代码框架常见标签注释标签标题标签段落标签换行标签格式化标签 什么是前端 Web 前端,用来直接给以用户呈现的一个一个的网页。一个软件通常是由 后端前端 完成的 后端:通过 Java/C等语言,完成相…...
鸿蒙 ArkUI组件二
ArkUI组件(续) 文本组件 在HarmonyOS中,Text/Span组件是文本控件中的一个关键部分。Text控件可以用来显示文本内容,而Span只能作为Text组件的子组件显示文本内容。 Text/Span组件的用法非常简单和直观。我们可以通过Text组件来显…...
PHP 实现 redis 分布式锁
分布式锁 如果是强一致性保证,在获取锁或者失败后引入数据库存储扫表、mq 等方式进行补偿 如果可以容忍少量异常就不需要考虑了 像这里的代码,没吃建立一个链接铺货,性能损耗时间延迟也是很大的,也可在一块代码中进行服务&…...
vue3 自定义el-tree树形结构样式
这里样式设置主要用到了 windcss 实现效果 模拟数据 这里也可以用模拟的数据,下面用的是后端请求的真实数据 [{"id": 5,"rule_id": 0,"status": 1,"create_time": "2019-08-11 13:36:09","update_time": "…...
【网络安全】分享4个高危业务逻辑漏洞
未经许可,不得转载。 文章目录 正文逻辑漏洞1逻辑漏洞2逻辑漏洞3逻辑漏洞4其它正文 该目标程序是一家提供浏览器服务的公司,其核心功能是网页抓取和多账户登录操作,类似于浏览器中的隐身模式,但更加强大和高效。通过该平台,用户可以轻松管理并同时运行数百个隐身浏览器实…...
【装机教程】Visual Studio Community 2019离线安装
Visual Studio 2019离线安装 由于现在 官网只支持在线安装最新版的Visual Studio 2022,因此 Visual Studio Community 2019需要离线安装。 下载离线安装镜像,并解压。点击vs_setup.exe运行。 选择安装位置,四处位置需要确定。 选择语言包&…...
NumPy 线性代数
NumPy 线性代数 NumPy 是 Python 中用于科学计算的核心库之一,它提供了一个强大的数学函数库,特别是在处理大型多维数组和矩阵时表现出色。线性代数是 NumPy 的一个重要组成部分,它包含了大量的函数和运算符,用于执行矩阵和向量的…...
家装材料之水泥,最容易被忽视的基础材料!
由于水泥在装修中扮演辅料的角色,很多业主往往会忽视它们的质量。事实上,装修无小事,不能抱有抓大放小的态度。 更何况水泥是装修工程的基础材料,在家居装修中,地面、墙面的找平以及瓷砖、大理石的铺贴&#…...
openstack之keystone介绍
功能 keystone在OpenStack中负责: 管理:用户、租户和权限; 认证:组件相互访问的身份认证; 鉴权:提供 RBAC(Role Based Access Control) 权限体系; 服务注册与发现&#…...
【图像拼接】基于SIFT/SURF特征算法的图像拼接,matlab实现
博主简介:matlab图像代码项目合作(扣扣:3249726188) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于SIFT/SURF特征算法的图像拼接,用matlab实现。 一、案例背景和算法介…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
