6.蒙特卡洛方法(TSP)

2023-05-16

定义:
旅行商问题,即TSP问题(Traveling Salesman Problem)又译为旅行推销员问题、货郎担问题,是数学领域中著名问题之一。假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。

例题:假设存在八个村庄坐标如下,那么怎样走一条路经过他们,同时路径最短
在这里插入图片描述

MATLAB代码如下:

clear;clc
% 只有8个城市的简单情况
 towns =[0.64 0.41 0.99 0.55 0.77 0.25 0.11 0.89;
         0.74 0.45 0.66 0.21  0.32 0.99 0.54 0.11]' ;  % 城市坐标矩阵,n行2列
n = size(towns,1);  % 城市的数目

figure(1)  % 新建一个编号为1的图形窗口
plot(towns(:,1),towns(:,2),'o');   % 画出城市的分布散点图
for i = 1:n
    text(towns(i,1)+0.02,towns(i,2)+0.02,num2str(i))   % 在图上标上城市的编号(加上0.02表示把文字的标记往右上方偏移各0.02单位)
end
hold on % 接着在这个图形上画图的


d = zeros(n);   % 初始化两个城市的距离矩阵全为0
for i = 2:n    %i从2开始,是因为他与他自己的距离是0
    for j = 1:i  
        towns_i = towns(i,:);   x_i = towns_i(1);     y_i = towns_i(2);  % 城市i的横坐标为x_i,纵坐标为y_i
        towns_j = towns(j,:);   x_j = towns_j(1);     y_j = towns_j(2);  % 城市j的横坐标为x_j,纵坐标为y_j
        d(i,j) = sqrt((x_i-x_j)^2 + (y_i-y_j)^2);   % 计算城市i和j的距离
    end
end
d = d+d';   % 生成对称完整的距离矩阵

min_result = +inf;  % 假设最短的距离为min_result,初始化为无穷大,后面只要找到比它小的就对其更新
min_path = [1:n];   % 初始化最短的路径就是1-2-3-...-n
N = 500000;  % 模拟的次数,尽量比解的个数大几倍十几倍,但也不要太大,运行慢
for i = 1:N  % 开始循环
    result = 0;  % 初始化走过的路程为0
    path = randperm(n);  % 生成一个1-n的随机打乱的序列
    for i = 1:n-1  
        result = d(path(i),path(i+1)) + result;  % 按照这个序列不断的更新走过的路程这个值
    end
    result = d(path(1),path(n)) + result;  % 别忘了加上从最后一个城市返回到最开始那个城市的距离
    if result < min_result  % 判断这次模拟走过的距离是否小于最短的距离,如果小于就更新最短距离和最短的路径
        min_path = path;
        min_result = result;
    end
end
min_path
min_path = [min_path,min_path(1)];   % 在最短路径的最后面加上一个元素,即第一个点(我们要生成一个封闭的图形)
n = n+1;  % 城市的个数加一个(紧随着上一步)
for i = 1:n-1 
     j = i+1;
    towns_i = towns(min_path(i),:);   x_i = towns_i(1);     y_i = towns_i(2); 
    towns_j = towns(min_path(j),:);   x_j = towns_j(1);     y_j = towns_j(2);
    plot([x_i,x_j],[y_i,y_j],'-')    % 每两个点就作出一条线段,直到所有的城市都走完
    pause(0.5)  % 暂停0.5s再画下一条线段
    hold on
end

运行结果:
最短距离为2.8858,走法如下图(闭合的圈,起点任意)
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

6.蒙特卡洛方法(TSP) 的相关文章

  • MATLAB求符号函数的函数值的方法

    在MATLAB中定义函数的方法有许多种 xff0c 比较常用的一种是定义符号变量 x 和 y 举一个简单的例子 xff1a 对函数 y 61 x 2 用上述方法的MATLAB语言如下 xff1a syms x y y 61 x 2 要想画出
  • C++寻找数组最大值和最小值

    寻找数组中的最大最小值 include lt iostream gt using namespace std include lt algorithm gt int main int n cin gt gt n int p 61 new i
  • Excel如何同时查找多个数据

    在使用多个excel表的时候 xff0c 有时需要在一个表中查找另一个表中的某些信息 xff0c 怎样能一步到位 xff0c 将所有要查找的信息一次找出来而不是一个个的Ctrl 43 F xff1f 这是前几天帮辅导员老师统计新生的数据时遇
  • python tkinter 全部组件(widget)及事件类型(event)一览

    对于一个简单的GUI程序设计来说 xff0c 我觉得无非就是三个要素 xff0c widget xff08 部件 xff09 xff0c layout xff08 布局 xff09 xff0c event xff08 事件的响应 xff09
  • DS18B20 1-WIRE ROM搜索算法详解

    转自 xff1a http blog sina com cn s blog 57ad1bd20102uxxw html 1 WIRE 搜索算法详解 xff08 1 xff09 0 前言 美信公司 xff08 http www maximin
  • 关于python tkinter 多线程依然无响应问题

    今天解决了一个GUI程序的多线程问题 因为GUI程序在执行高IO操作的时候容易出现假死和无响应的状态 xff0c 所以需要用到多线程 但我的程序开了线程之后依然是无响应状态 几次尝试 xff0c 终于找到问题所在 1 首先 xff0c 我的
  • Ubuntu内核的查看、更新、卸载、取消及启用自动更新

    1 查看当前内核版本 xff1a uname r 2 升级内核 xff1a sudo apt get update sudo apt cache search linux image 查看可用内核 在选择合适的内核后 xff0c sudo

随机推荐