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

基于禁忌搜索算法(TS)的TSP(Python实现)

        本篇文章是博主在最化优学习、人工智能等领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在最优化算法

       最优化算法(1)---基于禁忌搜索算法(TS)的TSP(Python实现)》

基于禁忌搜索算法(TS)的TSP(Python实现)

目录

基于禁忌搜索算法(TS)的TSP(Python实现)

1.项目介绍       

2.程序代码

3.运行结果


1.项目介绍       

        基于禁忌搜索算法(TS)的TSP(Traveling Salesman Problem,旅行商问题),涉及一种用于解决TSP的优化方法。TSP是一个经典的组合优化问题,目标是寻找一条最短路径,使得旅行商可以访问每个城市恰好一次并返回起点城市。

        TS算法作为一种启发式优化算法,在TSP求解中具有广泛的应用。相较于传统的穷举或贪婪算法,TS算法通过引入禁忌列表和邻域结构来更全面地探索解空间,从而更有可能找到较为优秀的近似最优解。

        禁忌搜索算法从一个初始解开始,在每次迭代中根据邻域结构生成新的解,并根据目标函数对其质量进行评估。若新解优于当前最优解且未出现在禁忌列表中,则接受该解作为当前最优解;否则,寻找下一个最佳候选解。同时,禁忌列表会记录一段时间内禁止选择的解,以避免陷入循环或重复访问相似解的情况。

        在TSP问题上,邻域结构通常包括交换两个城市的位置、翻转子路径等操作,而目标函数则是路径长度。禁忌搜索通过不断迭代搜索和更新禁忌列表,逐步改进当前路径,直至满足结束条件为止。

在基于TS算法求解TSP问题时,禁忌搜索的核心思想包括以下几个方面:

  1. 禁忌列表:记录已经探索过的路径或解,以避免下一步重复探索相同的路径或解。
  2. 邻域结构:定义了TSP解空间中可行解之间的相邻关系,如通过交换、插入等操作生成新的解。
  3. 目标函数:通常是TSP问题中路径长度的计算,用于评估每个解的质量。

TS算法求解TSP的基本步骤包括:

  • 初始化:随机生成初始路径
  • 迭代搜索:根据邻域结构和目标函数,通过禁忌搜索不断调整路径,并更新禁忌列表,记录当前最优路径
  • 终止条件:达到预设的迭代次数或满足特定条件时结束搜索,返回最优路径

        通过利用TS算法求解TSP问题,可以有效地寻找到较为优秀的旅行路线,虽不能保证找到全局最优解,但通常能获得接近最优解的结果。


2.程序代码

""""
题目:基于禁忌搜索算法的TSP
作者:Rainbook
最终修改时间:2023.12.30
"""
import math
import random
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.pylab import mpl
import numpy as npplt.rcParams['font.sans-serif'] = ['Microsoft YaHei']  # 使用微软雅黑字体
plt.rcParams['axes.unicode_minus'] = False  # 处理负号显示异常# 计算路径距离,即评价函数
def calFitness(line, dis_matrix):dis_sum = 0dis = 0for i in range(len(line)):if i < len(line) - 1:dis = dis_matrix.loc[line[i], line[i + 1]]  # 计算距离dis_sum = dis_sum + diselse:dis = dis_matrix.loc[line[i], line[0]]dis_sum = dis_sum + disreturn round(dis_sum, 1)def traversal_search(line, dis_matrix, tabu_list):# 邻域随机遍历搜索traversal = 0  # 搜索次数traversal_list = []  # 存储局部搜索生成的解,也充当局部禁忌表traversal_value = []  # 存储局部解对应路径距离while traversal <= traversalMax:pos1, pos2 = random.randint(0, len(line) - 1), random.randint(0, len(line) - 1)  # 交换点# 复制当前路径,并交换生成新路径new_line = line.copy()new_line[pos1], new_line[pos2] = new_line[pos2], new_line[pos1]new_value = calFitness(new_line, dis_matrix)  # 当前路径距离# 新生成路径不在全局禁忌表和局部禁忌表中,为有效搜索,否则继续搜索if (new_line not in traversal_list) & (new_line not in tabu_list):traversal_list.append(new_line)traversal_value.append(new_value)traversal += 1return min(traversal_value), traversal_list[traversal_value.index(min(traversal_value))]def greedy(CityCoordinates, dis_matrix):'''贪婪策略构造初始解'''# 出来dis_matrixdis_matrix = dis_matrix.astype('float64')for i in range(len(CityCoordinates)): dis_matrix.loc[i, i] = math.pow(10, 10)line = []  # 初始化now_city = random.randint(0, len(CityCoordinates) - 1)  # 随机生成出发城市line.append(now_city)  # 添加当前城市到路径dis_matrix.loc[:, now_city] = math.pow(10, 10)  # 更新距离矩阵,已经过城市不再被取出for i in range(len(CityCoordinates) - 1):next_city = dis_matrix.loc[now_city, :].idxmin()  # 距离最近的城市line.append(next_city)  # 添加进路径dis_matrix.loc[:, next_city] = math.pow(10, 10)  # 更新距离矩阵now_city = next_city  # 更新当前城市return line# 画路径图
def draw_path(line, CityCoordinates):x, y = [], []for i in line:Coordinate = CityCoordinates[i]x.append(Coordinate[0])y.append(Coordinate[1])for j in range(len(line) - 1):plt.quiver(x[j], y[j], x[j + 1] - x[j], y[j + 1] - y[j], color='r', width=0.005, angles='xy', scale=1,scale_units='xy')plt.quiver(x[-1], y[-1], x[0] - x[-1], y[0] - y[-1], color='r', width=0.005, angles='xy', scale=1,scale_units='xy')plt.title('基于禁忌搜索算法的TSP')# plt.figure()# plt.plot(x, y,color='r', alpha=0.8, linewidth=0.8)# plt.xlabel('x')# plt.ylabel('y')plt.show()if __name__ == '__main__':# 随机生成城市信息nCity = 50CityCoordinates = np.random.uniform(0, 2000, [nCity, 2])  # uniform()生成nCity个二维数组,数值范围是0到2000# 参数设置CityNum = nCity  # 城市数量MinCoordinate = 0  # 二维坐标最小值MaxCoordinate = 101  # 二维坐标最大值tabu_limit = 50  # 禁忌长度,该值应小于(CityNum*(CityNum-1)/2)iterMax = 200  # 迭代次数traversalMax = 100  # 每一代局部搜索次数tabu_list = []  # 禁忌表tabu_time = []  # 禁忌次数best_value = math.pow(10, 10)  # 较大的初始值,存储最优解best_line = []  # 存储最优路径# 计算城市之间的距离dis_matrix = pd.DataFrame(data=None, columns=range(len(CityCoordinates)), index=range(len(CityCoordinates)))for i in range(len(CityCoordinates)):xi, yi = CityCoordinates[i][0], CityCoordinates[i][1]for j in range(len(CityCoordinates)):xj, yj = CityCoordinates[j][0], CityCoordinates[j][1]dis_matrix.iloc[i, j] = round(math.sqrt((xi - xj) ** 2 + (yi - yj) ** 2), 2)# 贪婪构造line = greedy(CityCoordinates, dis_matrix)value = calFitness(line, dis_matrix)  # 初始路径距离# 存储当前最优best_value, best_line = value, linebest_value_list = []best_value_list.append(best_value)# 更新禁忌表tabu_list.append(line)tabu_time.append(tabu_limit)itera = 0while itera <= iterMax:new_value, new_line = traversal_search(line, dis_matrix, tabu_list)if new_value < best_value:  # 优于最优解best_value, best_line = new_value, new_line  # 更新最优解best_value_list.append(best_value)print('第%d次:当前优解为' % (itera+1))print(best_line)line, value = new_line, new_value  # 更新当前解# 更新禁忌表tabu_time = [x - 1 for x in tabu_time]if 0 in tabu_time:tabu_list.remove(tabu_list[tabu_time.index(0)])tabu_time.remove(0)tabu_list.append(line)tabu_time.append(tabu_limit)itera += 1# 路径顺序print("-------最优解为:")print(best_line)# 画路径图draw_path(best_line, CityCoordinates)

3.运行结果


        参考资料来源:CSDN、百度搜索、维基百科等

        文章若有不当和不正确之处,还望理解与指出。由于部分文字、图片等来源于互联网,无法核实真实出处,如涉及相关争议,请联系博主删除。如有错误、疑问和侵权,欢迎评论留言联系作者,或者关注VX公众号:Rain21321,联系作者。

相关文章:

基于禁忌搜索算法(TS)的TSP(Python实现)

本篇文章是博主在最化优学习、人工智能等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对相关等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在最优化算…...

Linux shell 网络掩码地址转CIDR

例子&#xff1a; ./1.sh 255.255.255.0 ./1.sh 255.255.255.128 ./1.sh 255.255.0.0 源实现&#xff1a; #!/bin/bashnetmask_to_cidr() {local IFSlocal -a octetslocal i0local cidr0IFS. read -r -a octets <<< "$1"for octet in "${octets[]}…...

C#,煎饼排序问题(Pancake Sorting Problem)算法与源代码

1 煎饼排序问题 给定一个未排序的数组&#xff0c;任务是对给定数组进行排序。您只能在阵列上执行以下操作。 翻转&#xff08;arr&#xff0c;i&#xff09;&#xff1a;将数组从0反转为i 示例&#xff1a; 输入&#xff1a;arr[]{23、10、20、11、12、6、7} 输出&#xff1a…...

13.西瓜书——半监督学习

1.概述 &#xff08;1&#xff09; 纯半监督学习 (Pure Semi-Supervised Learning) 纯半监督学习是一种典型的半监督学习方法&#xff0c;它的主要特点是同时利用有标签数据和无标签数据进行模型训练。目标是通过整合这两种类型的数据来提高模型的泛化性能。在这个过程中&#…...

C++进阶之路---继承(二)

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、继承与友元 友元关系不能继承&#xff0c;也就是说基类友元不能访问子类私有和保护成员。 class Student; class Per…...

C及C++每日练习(3)

选择题&#xff1a; 1.以下程序的输出结果是&#xff08;&#xff09; #include <stdio.h> main() { char a[10] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, *p; int i; i 8; p a i; printf("%s\n", p - 3); } A.6 B. 6789 C. 6 D.789 对于本题&#xff0…...

黑马点评-附近商户实现

GEO数据结构 Redis在3.2版本中加入了对GEO的支持&#xff0c;允许存储地理坐标信息&#xff0c;根据经纬度来检索数据。 GEO本质上是基于sortedSet实现的&#xff0c;在Sorted Set中&#xff0c;每个成员都是与一个分数(score)相关联的&#xff0c;这个分数用于对成员进行排序…...

安装nginx:手动安装和yum安装

本文在centos7.9下分别尝试了yum安装和手动安装&#xff0c;记录一下试验过程。为后来者少踩点坑。 下载 下载地址&#xff1a;链接 。建议下载稳定版本&#xff0c;也就是Stable Version&#xff0c;这里下载的是 nginx-1.24.0 # 我下载在如下文件夹 mkdir/opt/apps cd /op…...

【C++ STL详解】——string类

目录 前言 一、string类对象的常见构造 二、string类对象的访问及遍历 1.下标【】&#xff08;底层operator【】函数&#xff09; ​编辑 2.迭代器 3.范围for 4.at 5.back和front 三、string类对象的容量操作 1.size 和 length 2.capacity 3.empty 4.clear 5.res…...

MatplotlibPython 1 3.7

放大数据&#xff0c;如果想仔细看某一行的数据的时候 可以调不同的颜色&#xff0c;图片的长宽高&#xff0c;以及线的种类 plt.figure 这个命令下的所有东西都在这个figure里面 plt.xlim 改变坐标轴的范围 plt.xlabel 改变坐标轴的总名称 plt.xticks 换单位 plt.yt…...

深入理解 Dubbo:构建分布式服务治理体系

目录 1. 介绍 2. Dubbo 的核心概念 2.1 服务提供者&#xff08;Provider&#xff09;与服务消费者&#xff08;Consumer&#xff09; 2.2 注册中心&#xff08;Registry&#xff09; 2.3 监控中心&#xff08;Monitor&#xff09; 3. Dubbo 的功能特性 3.1 远程调用&…...

唤起原生IOS和安卓Android app的方法

大家好我是咕噜美乐蒂&#xff0c;很高兴又和大家见面了&#xff01; 要唤起原生 iOS 或 Android 应用程序&#xff0c;你可以使用以下方法&#xff1a; 唤起原生 iOS 应用程序 在 iOS 上&#xff0c;你可以使用自定义 URL 方案或 Universal Links 来唤起原生应用程序。以下…...

RabbitMQ的web控制端介绍

2.1 web管理界面介绍 connections&#xff1a;无论生产者还是消费者&#xff0c;都需要与RabbitMQ建立连接后才可以完成消息的生产和消费&#xff0c;在这里可以查看连接情况channels&#xff1a;通道&#xff0c;建立连接后&#xff0c;会形成通道&#xff0c;消息的投递、获取…...

GitHub登不上:修改hosts文件来解决(GitHub520,window)

参考链接&#xff1a;GitHub520: 本项目无需安装任何程序&#xff0c;通过修改本地 hosts 文件&#xff0c;试图解决&#xff1a; GitHub 访问速度慢的问题 GitHub 项目中的图片显示不出的问题 花 5 分钟时间&#xff0c;让你"爱"上 GitHub。 (gitee.com) GitHub网站…...

01-DevOps代码上线-git入门及gitlab远程仓库

一、准备学习环境 10.0.0.71-gitlab 2c2g-20GB 10.0.0.72-jenkins 2c2g-20GB 10.0.0.73-sonarqube 1c1g-20GB 10.0.0.74-nexus 1c1g-20GB 10.0.0.75-dm 1c1g-20GB &#xff08;模拟写代码服务器&#xff09; 在centos系统中&…...

EdgeX Foundry 安全模式安装部署

文章目录 一、安装准备1.官方文档2. 克隆服务器3.安装 Docker4.安装 docker-compose 二、安装部署1.docker-comepse2.启动 EdgeX Foundry3.访问 UI3.1. consul3.2. EdgeX Console EdgeX Foundry # EdgeX Foundryhttps://iothub.org.cn/docs/edgex/ https://iothub.org.cn/docs…...

网络安全-appcms-master

一、环境 gethub上面自己找appcms-master 二、分析一下源码以及闯关思路 首先是有一个函数循环以及函数过滤&#xff0c;我们的post会将我们所传的所有val值去进行一个循环&#xff0c;之后通过htmlspecialchars这个函数进行过滤和转换所以val值不能通过单双引号闭合注入的方…...

ThreadLocal 与 synchronized 区别

我的理解 目的都是为了一个大前提:操作内容的线程安全。 任务不同&#xff1a;synchronized 解决的是多线程下线程操作权限的问题&#xff0c;以及原子性的保证。通过对锁的竞争&#xff0c;达到对资源的访问有序。 ThreadLocal是解决的事多线程下资源的隔离问题&#xff0c;即…...

灵魂指针,教给(二)

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 C语言知识 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 目录 一、数组名的理解 二、使用指针访问数组 三、一维数组传参本质 四、冒泡排序 五、二级指针 六、指针数组 七、指针数组…...

线程安全--浅谈Ad-hoc与加锁的区别

浅谈Ad-hoc 与加锁 两者要解决的都是对对象的语义混乱操作&#xff0c;即有个count进行累加操作。 我的理解/文心一言的反馈如下: 加锁是保证我们对同一个count在多线程下的访问有序&#xff0c;即“读写-修改-写入”具有原子性。 而Ad-hoc机制就是通过程序员自己定义一个私有…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

负载均衡器》》LVS、Nginx、HAproxy 区别

虚拟主机 先4&#xff0c;后7...

渗透实战PortSwigger Labs指南:自定义标签XSS和SVG XSS利用

阻止除自定义标签之外的所有标签 先输入一些标签测试&#xff0c;说是全部标签都被禁了 除了自定义的 自定义<my-tag onmouseoveralert(xss)> <my-tag idx onfocusalert(document.cookie) tabindex1> onfocus 当元素获得焦点时&#xff08;如通过点击或键盘导航&…...