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

模拟退火算法应用——求解TSP问题

仅作自己学习使用


一、问题

        旅行商问题(TSP) 是要求从一个城市出发,依次访问研究区所有的城市,并且只访问一次不能走回头路,最后回到起点,求一个使得总的周游路径最短的城市访问顺序。
       采用模拟退火算法求解TSP问题,很自然的想到退火的目标函数(优化函数)应该就是总的周游距离。那么在算法中如何体现呢?那就是把城市的坐标放在一个n×2的矩阵中,矩阵中存放城市的顺序就是依次周游城市的路径,所以在求解过程中会不断的产生新的更优解(周游顺序,在算法中体现就是城市坐标的存放顺序),有了这个关键的思路就很好解决了。

二、Matlab代码

clear
clc
T1 = cputime;
C = [% 各个城市坐标39.91, 116.39;   % 北京31.22, 121.48;   % 上海23.13, 113.27;   % 广州22.54, 114.06;   % 深圳30.67, 104.06;   % 成都34.27, 108.93;   % 西安31.98, 118.75;   % 南京39.92, 116.36;   % 天津28.71, 115.83;   % 南昌45.75, 126.63;   % 哈尔滨36.07, 120.38;   % 青岛38.04, 114.48;   % 石家庄29.59, 106.54;   % 重庆26.08, 119.30;   % 福州30.25, 120.16;   % 杭州28.19, 112.97;   % 长沙25.03, 102.73;   % 昆明35.68, 139.76;   % 东京37.56, 126.97;   % 首尔1.35, 103.82;    % 新加坡13.41, 103.86;   % 金边21.03, 105.85;   % 河内3.14, 101.69;    % 吉隆坡39.90, 32.85;    % 安卡拉37.97, 23.73;    % 雅典38.71, -9.14;    % 里斯本41.89, 12.50;    % 罗马52.52, 13.41;    % 柏林55.75, 37.62;    % 莫斯科48.86, 2.35;     % 巴黎
];n = length(C);  % 获取城市的个数
T = 100 * n;    % 初始温度
L = 10;         % 马尔可夫链长度
K = 0.986;      % 降温系数%%  构建城市坐标结构体
city = struct([]);
for i = 1:ncity(i).x = C(i,1);     % 经度city(i).y = C(i,2);     % 纬度
end%% 开始退火
% 统计迭代次数
count = 1;   
% 计算每次迭代后的总距离(第一次就是初始时,按照坐标的顺序计算的距离)
Dist(count) = GetDist(city,n); 
figure(1)
% 当温度无限趋于0度时停止迭代
while T > 0.01 % 每次降温 均进行多次迭代for i = 1:L% 计算原路线周游距离len1 = GetDist(city,n);% 产生随机扰动(随机交换两个城市的坐标)p1 = floor(1 + n * rand()); % rand函数产生一个0,1之间均匀分布的实数,包含0但不包含1p2 = floor(1 + n * rand()); % 因此这个表达式可以产生一个从1到n的随机数while (p1 == p2)p1 = floor(1 + n * rand()); p2 = floor(1 + n * rand());endtemp_city = city;% 交换第P1个城市和第P2个城市的坐标temp = temp_city(p1);temp_city(p1) = temp_city(p2);temp_city(p2) = temp;% 计算新路线的周游距离len2 = GetDist(temp_city,n);% 新、老路线的差值(相当于能量)delta = len2 - len1;if(delta<0)% 新路线的评估函数更小(记住,模拟退火算法相当于是一个求函数极小值的算法)city = temp_city;  % 更新原路线(变量里存放城市的顺序也就是访问城市的顺序)else% Metropolis接受准则(概率选择更差的解)if exp((len1-len2)/T) > rand()% 记住这个概率的公式,指数部分一定是要个负数,概率的值不可能超过1city = temp_city;endendend% 本次迭代结束,统计迭代次数加1count = count + 1; % 将本次迭代的最优解放在len中Dist(count) = GetDist(city,n); %% 本次退火结束,降温T = T * K;% 按照新的城市的顺序,把这些城市画出来for i = 1: n-1plot([city(i).x,city(i+1).x],[city(i).y,city(i+1).y],'bo-');hold on;endplot([city(n).x,city(1).x],[city(n).y,city(1).y],'ro-');title(['优化最短距离:', num2str(Dist(count))]);hold offpause(0.005); % 动态显示出每次的搜索结果
end
T2 = cputime;
figure(2)
plot(Dist,LineWidth=2)
xlabel("迭代次数")
ylabel("目标函数值")
title("适应度进化曲线","搜索时间:"+(T2-T1)+" s")
%% 评估函数
function result = GetDist(city,n)
% 计算总的周游路径长度(评估函数)
% city是各个城市的坐标result = 0;for i = 1:n-1result = result + sqrt((city(i).x - city(i+1).x)^2 + (city(i).y - city(i+1).y)^2);endresult = result + sqrt((city(n).x - city(1).x)^2 + (city(n).y - city(1).y)^2);
end

三、效果

周游图

适应度进化曲线

四、问题

        大家可以试一试更多的城市,当有很多城市的坐标相差不大时,在最后的搜索结果中,会出现一个非常奇怪的问题,就是在周游图中,有些城市消失了,检查存放城市的city结构体,是存放着这些坐标的,这里如果有知道的朋友还请多多批评指教,我将及时改正。

相关文章:

模拟退火算法应用——求解TSP问题

仅作自己学习使用 一、问题 旅行商问题(TSP) 是要求从一个城市出发&#xff0c;依次访问研究区所有的城市&#xff0c;并且只访问一次不能走回头路&#xff0c;最后回到起点&#xff0c;求一个使得总的周游路径最短的城市访问顺序。 采用模拟退火算法求解TSP问题&#x…...

【LeetCode】每日一题 2023_11_28 设计前中后队列(数组/链表/双端队列)

文章目录 刷题前唠嗑题目&#xff1a;设计前中后队列题目描述代码与解题思路偷看大佬题解 结语 刷题前唠嗑 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 这道题的难度&#xff0c;才是我想象中的中等题的难度好吧&#xff0c;昨天那玩意对我来说还是太难了…...

python基于YOLOv8全系列模型【n/s/m/l/x】开发构建不同参数量级的钢铁产业产品智能自动化检测识别系统

在前文的项目开发实践中&#xff0c;我们已经以钢铁产业产品缺陷检测数据场景为基准&#xff0c;陆续开发构建了多款目标检测模型&#xff0c;感兴趣的话可以自行阅读即可。 《YOLOv3老矣尚能战否&#xff1f;基于YOLOv3开发构建建钢铁产业产品智能自动化检测识别系统&#xf…...

力扣142. 环形链表 II

文章目录 力扣142. 环形链表 II示例代码实现总结收获 力扣142. 环形链表 II 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c…...

【设计模式-2.2】创建型——简单工厂和工厂模式

说明&#xff1a;本文介绍设计模式中&#xff0c;创建型设计模式中的工厂模式&#xff1b; 飞机大战 创建型设计模式&#xff0c;关注于对象的创建&#xff0c;本文介绍的简单工厂和工厂模式同样也是。举一个游戏例子&#xff0c;如飞机大战游戏中&#xff0c;屏幕中敌人类型…...

将文件读入C中的字符数组

当您使用 C 编程语言时&#xff0c;您可能会遇到一些需要将文件读入字符数组的问题&#xff0c;例如分析每个字符的频率&#xff0c;或者将所有句子的每个起始词从小写转换为大写&#xff0c;反之亦然。该解决方案非常简单&#xff0c;但对于不太了解文件读取或写入的人来说可能…...

不小心删除了短信,如何在 Android 上恢复已删除的短信

不小心删除了文字消息在 Android 手机上使用可能会是一种令人痛苦的体验。这些消息可能包含有价值的信息、珍贵的回忆或重要的细节。幸运的是&#xff0c;您可以探索多种方法来恢复这些丢失的消息。在本文中&#xff0c;我们将深入研究可用于检索已删除短信的选项&#xff0c;并…...

Java电子招投标采购系统源码-适合于招标代理、政府采购、企业采购、等业务的企业

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及审…...

springBoot的实现原理;SpringBoot是什么;使用SpringBoot的核心功能;springBoot核心注解以及核心配置文件

文章目录 springBootspringBoot的实现原理什么是 Spring Boot&#xff1f;SpringBoot是什么为什么要使用springBootSpring Boot的核心功能Spring Boot 主要有如下优点&#xff1a; SpringBoot启动过程-流程Spring Boot 的核心注解是哪个&#xff1f;什么是 JavaConfig&#xff…...

logback-spring.xml详解

《springboot使用logback日志框架超详细教程》文中&#xff0c;filter中最重要的两个过滤器LevelFilter&#xff08;日志级别精确匹配&#xff09;、ThresholdFilter&#xff08;阈值过滤&#xff09; 的描述非常准确&#xff1a; springboot使用logback日志框架超详细教程_sp…...

【Python】nn.BCEWithLogitsLoss函数详解

nn.BCEWithLogitsLoss() 是 PyTorch 中一个用于二元分类问题的损失函数&#xff0c;它结合了 Sigmoid 层&#xff08;将输出映射到 [0,1] 范围内&#xff09;和 Binary Cross Entropy&#xff08;BCE&#xff09;损失。这可以避免在正向和反向传播过程中可能出现梯度爆炸或梯度…...

【C++】日期类的实现

在上篇博客中我们已经学习了C中的运算符重载&#xff0c;我们说&#xff0c;操作符只能对于内置类型进行操作&#xff0c;对自定义类型我们需要自己定义函数去实现一系列的操作 那么这篇博客我们就专门把日期这个类单独拿出来写一下它都有哪些有意义的可以重载的运算符&#xf…...

带残差连接的ResNet18

目录 1 模型构建 1.1 残差单元 1.2 残差网络的整体结构 2 没有残差连接的ResNet18 2.1 模型训练 2.2 模型评价 3 带残差连接的ResNet18 3.1 模型训练 3.2 模型评价 4 与高层API实现版本的对比实验 总结 残差网络&#xff08;Residual Network&#xff0c;ResNet&#xff09;…...

【深入解析git和gdb:版本控制与调试利器的终极指南】

【本节目标】 1. 掌握简单gdb使用于调试 2. 学习 git 命令行的简单操作, 能够将代码上传到 Github 上 1.Linux调试器-gdb使用 1.1.背景 程序的发布方式有两种&#xff0c;debug模式和release模式release模式不可被调试&#xff0c;debug模式可被调试Linux gcc/g出来的二进制…...

CGAN原理讲解与源码

1.CGAN原理 生成器&#xff0c;输入的是c和z&#xff0c;z是随机噪声&#xff0c;c是条件&#xff0c;对应MNIST数据集&#xff0c;要求规定生成数字是几。 输出是生成的虚假图片。 生成器生成的图片被判别器认为是真实图片&#xff0c;那么标签就是1 其实判别器模型输出的是…...

C#实体类与XML互转以及List和DataTable转XML的使用

引言 在C#开发中&#xff0c;数据的存储和传输是非常常见的需求。使用XML作为数据格式有很多优点&#xff0c;例如可读性强、易于解析等。而实体类、List和DataTable是表示数据模型的常用方式。本文将介绍如何在C#中实现实体类、List和DataTable与XML之间的相互转换&#xff0c…...

uniapp的vue3的模版的setup函数内使用uniapp内置方法

vue2使用方式直接在method同级使用就行,但是在vue3的setup函数内直接使用会报错,本人找了好久,发现vue3需要导入uniapp模块才能使用,具体如下 使用uniapp上拉加载更多方法 <script>import {onReachBottom} from dcloudio/uni-apponReachBottom(() > {console.log(&qu…...

UI自动化的基本知识

一、UI自动化测试介绍 1、什么是自动化测试 概念&#xff1a;由程序代替人工进行系统校验的过程 1.1自动化测试能解决的问题&#xff1f; 回归测试 (冒烟测试) 针对之前老的功能进行测试 通过自动化的代码来实现。 针对上一个版本的问题的回归 兼容性测试 web实例化不同的浏…...

python实现C++简易自动压行

突发奇想&#xff0c;想要将自己的c压行之后交上去。但是苦于手动压行效率太低&#xff0c;在网上搜索压行网站没有找到&#xff0c;突然发现压行不就是检查检查去个换行符吗。于是心血来潮&#xff0c;用python实现了一个简易压行程序。 首先&#xff0c;宏定义等带#的文件不…...

京东数据分析(京东大数据采集):2023年线上珍珠市场销售数据采集

在珠宝首饰市场&#xff0c;从黄金到钻石&#xff0c;如今年轻人的新风潮又转向了珍珠。珍珠热潮并非刚刚兴起&#xff0c;早在前两年&#xff0c;抖音、快手等短视频台的珍珠开蚌直播内容&#xff0c;就掀起了一波珍珠热潮。 此后&#xff0c;随着珍珠饰品被越来越多社交平台的…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

02.运算符

目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&&#xff1a;逻辑与 ||&#xff1a;逻辑或 &#xff01;&#xff1a;逻辑非 短路求值 位运算符 按位与&&#xff1a; 按位或 | 按位取反~ …...