禁忌搜索算法(TS算法)求解实例---旅行商问题 (TSP)

news2024/11/14 15:11:10

目录

  • 一、采用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 = 0
    for 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_distance

    for iteration in range(max_iter):
        # 生成所有邻域解
        neighbors = get_neighborhood(current_solution)
        neighbors_distances = [(neighbor, total_distance(neighbor)) for neighbor in neighbors]
        
        # 在禁忌表之外选择最优邻域解
        next_solution = None
        next_distance = float('inf')
        for neighbor, distance in neighbors_distances:
            if neighbor not in tabu_list and distance < next_distance:
                next_solution = neighbor
                next_distance = distance

        # 更新当前解
        current_solution = next_solution
        current_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_distance

        print(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):优化多辆车在多个配送点的路径。
  • 生产调度与资源分配:如工作车间调度、工厂生产排程、任务分配等。
  • 网络设计与路由优化:优化计算机网络或物流网络中的节点连接和路由路径。
  • 组合优化问题:如背包问题、图着色问题、设备布局问题等。

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

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

相关文章

论文阅读: SigLit | SigLip |Sigmoid Loss for Language Image Pre-Training

论文地址&#xff1a;https://arxiv.org/pdf/2303.15343 项目地址&#xff1a;https://github.com/google-research/big_vision 发表时间&#xff1a;2023年3月27日 我们提出了一种用于语言图像预训练&#xff08;SigLIP&#xff09;的简单成对 Sigmoid 损失。与使用 softmax …

Redis 篇-初步了解 Redis 持久化、Redis 主从集群、Redis 哨兵集群、Redis 分片集群

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 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…

new/delete和malloc/free到底有什么区别

new和malloc 文章目录 new和malloc前言一、属性上的区别二、使用上的区别三、内存位置的区别四、返回类型的区别五、分配失败的区别六、扩张内存的区别七、系统调度过程的区别总结 前言 new和malloc的知识点&#xff0c;作为一个嵌入式工程师是必须要了解清楚的。new和malloc的…

驱动器磁盘未格式化危机:专业数据恢复实战指南

认识危机&#xff1a;驱动器中的磁盘未被格式化 在日常的数字生活中&#xff0c;我们时常依赖于各种存储设备来保存重要的文件、照片、视频等数据。然而&#xff0c;当某一天你尝试访问某个驱动器或外接硬盘时&#xff0c;突然弹出的“驱动器中的磁盘未被格式化。您想现在格式…

【CSS in Depth 2 精译_032】5.4 Grid 网格布局的显示网格与隐式网格(上)

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09; 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位&#xff08;已完结&#xff09; 2.1 相对…

利用语义搜索和混合查询策略提升RAG系统的准确性

人工智能咨询培训老师叶梓 转载标明出处 在构建基于大模型&#xff08;LLM&#xff09;的生成式问答系统&#xff08;Generative Q&A&#xff09;时&#xff0c;检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;方法被广泛采用。RAG通过结合检索…

Gin渲染

HTML渲染 【示例1】 首先定义一个存放模板文件的 templates文件夹&#xff0c;然后在其内部按照业务分别定义一个 posts 文件夹和一个 users 文件夹。 posts/index.tmpl {{define "posts/index.tmpl"}} <!DOCTYPE html> <html lang"en">&…

【网络通信基础与实践第二讲】包括互联网概述、互联网发展的三个阶段、互联网的组成、计算机网络的体系结构

一、互联网概述 计算机网络是由若干节点&#xff08;node&#xff09;和连接这些节点的链路&#xff08;link&#xff09;组成。 网络之间还可以通过路由器互联起来&#xff0c;这就构成了一个覆盖范围更大的计算机网络。这样的网络称为互联网。 网络把许多计算机连接在一起…

『功能项目』制作提示主角升级面板【56】

我们打开上一篇55事件中心处理怪物死亡的项目&#xff0c; 本章做的事情是制作提示主角升级的界面&#xff0c;当主角升级时就会被显示出来点击确认即可消失 首先在unity编辑场景制作 在确认按钮对象上添加事件 点击Button将Panel添加至事件框选 在事件函数中选择gameobject.S…

【图像拼接】基于SIFT/SURF特征算法的图像拼接,matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于SIFT/SURF特征算法的图像拼接&#xff0c;用matlab实现。 一、案例背景和算法介…

[C#学习笔记]Newtonsoft.Json

视频地址&#xff1a;分享一些Newtonsoft.Json的实用功能与技巧_哔哩哔哩_bilibili 强烈推荐学习C#和WPF的朋友关注此UP&#xff0c;知识点巨多&#xff0c;讲解透彻&#xff01; 一、JsonSerializerSettings 1.1 自动缩进-Formatting 使用Formatting.None进行序列化 var …

流媒体之RTMP协议(其四)

欢迎诸位来阅读在下的博文~ 在这里&#xff0c;在下会不定期发表一些浅薄的知识和经验&#xff0c;望诸位能与在下多多交流&#xff0c;共同努力&#xff01; 江山如画&#xff0c;客心如若&#xff0c;欢迎到访&#xff0c;一展风采 文章目录 前期博客参考书籍一、PTMP简介二…

MyBatis的配置文件详解

01-MyBatis的配置文件详解 创建的接口和xml文件的名字最好写一样的要不然会出问题,然后和接口名相同的xml文件在resources下创建个和接口相同文件夹把xml文件放进去,而且resources下的创建的文件夹需要一级一级的创键,比如:cn创建完,创建tulingxue,然后再创建mapper文件夹才行…

python绘制月亮

import matplotlib import matplotlib.pyplot as plt import moviepy.editor as mpymatplotlib.rcParams[font.family] SimHei# 坐标列表 positions [(0, 0), (1 / 4, 1 / 4), (1 / 3, 1 / 4), (1 / 2, 1 / 4), (2 / 3, 1 / 4),(3 / 4, 1 / 4), (1, 1 / 4), (5 / 4, 1 / 4), …

C++中的容器——vector

1. vector的介绍 vector&#xff1a;vector的底层实际上就是一个数组&#xff08;也称为顺序表&#xff09;&#xff0c;数据是连续存储在数组中的&#xff0c;因此vector是可以使用下标来进行访问的&#xff0c;但是它的大小并不是像数组一样是固定的&#xff0c;而是可以动态…

漳州自闭症寄宿学校,孩子的快乐学习乐园

在温暖而包容的南方都市——广州&#xff0c;藏着一所特别的学校&#xff0c;它以爱为名&#xff0c;为自闭症儿童编织了一个充满希望的未来&#xff0c;这就是星贝育园自闭症儿童寄宿制学校。这里&#xff0c;不仅是知识的殿堂&#xff0c;更是孩子们心灵得以自由飞翔、快乐学…

削峰+限流:秒杀场景下的高并发写请求解决方案

我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货! 哈喽,大家好!我是小米,一个29岁、活泼积极、热衷分享技术的码农。今天和大家聊一聊应对高并发的写请求这个主题,尤其是在大促、秒杀这种场景下,系统…

【Docker Nexus3】maven 私库

1.部署环境 window 11 x64Docker Desktop 4.34.1 (166053) Docker Engine v27.2.0 1.1.Docker 镜像源 1.1.1.Docker Engine 配置 {"builder": {"features": {"buildkit": true},"gc": {"defaultKeepStorage": "32…

微服务_入门2

文章目录 一、Feign二、Gateway服务网关 一、Feign 来看我们以前利用RestTemplate发起远程调用的代码&#xff1a; 存在下面的问题&#xff1a; 代码可读性差&#xff0c;编程体验不统一&#xff08;url需要自己在代码中拼写出来&#xff09;参数复杂URL难以维护&#xff0…

Weapons Armor PBR Pack 1 - Fantasy RPG 武器护甲游戏模型

武器和护甲包#1有30个武器和护甲,每个对象都有默认外观,大多数都有网格变形和Substance Painter源文件,用于自定义纹理。 无限PBR&我的哲学 Infinity PBR是十几位艺术家的作品,他们都在做自己最擅长的事情。我想为独立游戏开发者制作最通用、最优质的资产,按照我希望的…