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

禁忌搜索算法(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 坐标
01020
13040
22010
34030
41010
55020

目标是找到一个经过所有城市且总距离最短的路径。

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算法算法的工作原理

  1. 初始化

    • 随机生成一个初始解 s 作为当前解。
    • 设置一个空的禁忌表 T 和最大禁忌表长度 L,定义最大迭代次数 max_iter
  2. 生成邻域解

    • 对当前解 s,生成其邻域解集合 N(s)。通常,邻域解是通过对当前解的微小修改(如交换、移位等)生成的多个新解。
  3. 选择最优邻域解

    • 在邻域解集合 N(s) 中,选择一个不在禁忌表中的最佳解 s',使得其目标函数值最优(通常是最小化问题中的最小值)。
    • 若所有邻域解均在禁忌表中,则可以选择一个禁忌解作为当前解。
  4. 更新禁忌表

    • 将新的解 s' 添加到禁忌表 T 中,以避免在未来的搜索过程中重新访问该解。
    • 若禁忌表长度超过最大限制 L,则删除最早加入的解。
  5. 更新当前解和全局最优解

    • 将当前解 s 更新为新解 s'
    • 如果 s' 的目标函数值优于全局最优解 s*,则更新全局最优解 s*
  6. 迭代和终止

    • 重复步骤 2-5,直到达到最大迭代次数 max_iter 或找到满意解为止。

4.4 TS算法算法的关键要素

  1. 禁忌表(Tabu List)

    • 禁忌表是一个用来存储禁忌解的集合,用于防止搜索过程中的循环和回溯。禁忌表的长度 L 通常设定为一个固定值,当禁忌表超过最大长度时,将最早的解移出禁忌表。
  2. 邻域结构

    • 邻域结构决定了每次搜索所能达到的解空间范围。常见的邻域操作有交换、移位、反转等操作。
  3. 禁忌策略

    • 禁忌策略决定了哪些解被列入禁忌表。在一般情况下,禁忌解是根据一定规则选定的,以确保多样化搜索和有效避免循环。
  4. 解的多样化策略

    • 在搜索过程陷入局部最优时,解的多样化策略用于打破停滞状态,推动搜索进入新的区域。

4.5 TS算法算法的优缺点

4.5.1 优点

  • 跳出局部最优:通过禁忌表机制,TS 算法能够有效避免局部最优解,继续在解空间中进行搜索。
  • 灵活性强:TS 算法可以应用于多种优化问题,通过调整邻域结构和禁忌策略,可以针对不同问题进行适应性调整。
  • 易于实现:相较于一些复杂的优化算法,TS 算法较为简单,易于实现。

4.5.2 缺点

  • 计算开销较大:在大规模问题中,生成邻域解和维护禁忌表可能会带来较高的计算开销。
  • 参数敏感:算法性能对禁忌表长度、邻域结构和禁忌策略较为敏感,需要根据具体问题进行调优。
  • 不保证全局最优解:虽然 TS 算法能跳出局部最优,但不能保证一定找到全局最优解。

4.6 TS算法算法的应用场景

  • 旅行商问题 (TSP):寻找经过所有城市的最短路径。
  • 车辆路径问题 (VRP):优化多辆车在多个配送点的路径。
  • 生产调度与资源分配:如工作车间调度、工厂生产排程、任务分配等。
  • 网络设计与路由优化:优化计算机网络或物流网络中的节点连接和路由路径。
  • 组合优化问题:如背包问题、图着色问题、设备布局问题等。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 图神经网络模型扩展5--3
  • java编程行业特点
  • OpenAI API key not working in my React App
  • 无人机 PX4 飞控 | EKF2简介与使用方法
  • pyinstaller打包python程序
  • 【LeetCode 算法笔记】155. 最小栈
  • JVM JMM 专题篇 ( 12000 字详解 )
  • 第159天:安全开发-Python-协议库爆破FTPSSHRedisSMTPMYSQL等
  • Redis 篇-初步了解 Redis 持久化、Redis 主从集群、Redis 哨兵集群、Redis 分片集群
  • k8s中的认证授权
  • kubeadm方式安装k8s+基础命令的使用
  • CentOS7更新YUM源
  • 时空大数据平台:激活新质生产力的智慧引擎
  • Python 将矩阵转换为行最简形式 (Row Echelon Form, REF)和列最简形式 (Column Echelon Form, CEF)
  • DB-GPT部署和试用
  • [笔记] php常见简单功能及函数
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • JSDuck 与 AngularJS 融合技巧
  • JS变量作用域
  • Map集合、散列表、红黑树介绍
  • python 学习笔记 - Queue Pipes,进程间通讯
  • React 快速上手 - 07 前端路由 react-router
  • SpringBoot 实战 (三) | 配置文件详解
  • Spring声明式事务管理之一:五大属性分析
  • Vue2.0 实现互斥
  • vue中实现单选
  • 成为一名优秀的Developer的书单
  • 复杂数据处理
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 异步
  • 用jQuery怎么做到前后端分离
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • 选择阿里云数据库HBase版十大理由
  • ${ }的特别功能
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (C语言)输入一个序列,判断是否为奇偶交叉数
  • (Forward) Music Player: From UI Proposal to Code
  • (java)关于Thread的挂起和恢复
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (一)WLAN定义和基本架构转
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)人的集合论——移山之道
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .cn根服务器被攻击之后
  • .Net Memory Profiler的使用举例
  • .Net Web窗口页属性
  • .NET 将多个程序集合并成单一程序集的 4+3 种方法
  • .NET关于 跳过SSL中遇到的问题
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化