【动态规划法】求解TSP问题

article/2025/9/29 19:59:48

问题详情

求解下图所示的TSP问题,计算出所经过的城市编号以及最短路径值,城市代价矩阵如图所示:
在这里插入图片描述

求解思路

假设从顶点i出发,令d(i, V’ )表示从顶点i出发经过V’ 中各个顶点一次且仅一次,最后回到出发点(i)的最短路径长度,开始时, V’ =V-{i},于是,TSP问题的动态规划函数为:
d(i, V’ )=min{cik+d(k, V’ -{k})} (k∈V’)
d(k,{})=cki (k≠i) (从k出发到达i的距离)

计算过程

从0城市出发经城市1、2、3然后回到0城市的最短路径长度是:
d(0,{1, 2, 3})=min{c01+d(1, { 2, 3}), c02+d(2, {1, 3}), c03+d(3, {1, 2})}
这是最后一个阶段的决策,而:
d(1, {2, 3})=min{c12+d(2, {3}), c13+ d(3, {2})}
d(2, {1, 3})=min{c21+d(1, {3}), c23+ d(3, {1})}
d(3, {1, 2})=min{c31+d(1, {2}), c32+ d(2, {1})}
这一阶段的决策又依赖于下面的计算结果:
d(1, {2})= c12+d(2, {}) d(2, {3})=c23+d(3, {})
d(3, {2})= c32+d(2, {}) d(1, {3})= c13+d(3, {})
d(2, {1})=c21+d(1, {}) d(3, {1})=c31+d(1, {})
而下式可以直接获得(括号中是该决策引起的状态转移):
d(1, {})=c10=5(1→0) d(2, {})=c20=6(2→0) d(3, {})=c30=3(3→0)

再向前倒推,有:
d(1, {2})= c12+d(2, {})=2+6=8(1→2) d(1, {3})= c13+d(3, {})=3+3=6(1→3)
d(2, {3})= c23+d(3, {})=2+3=5(2→3) d(2, {1})= c21+d(1, {})=4+5=9(2→1)
d(3, {1})= c31+d(1, {})=7+5=12(3→1) d(3, {2})= c32+d(2, {})=5+6=11(3→2)
再向前倒退,有:
d(1, {2, 3})= min{c12+d(2, {3}), c13+ d(3, {2})}=min{2+5, 3+11}=7(1→2)
d(2, {1, 3})=min{c21+d(1, {3}), c23+ d(3, {1})}=min{4+6, 2+12}=10(2→1)
d(3, {1, 2})=min{c31+d(1, {2}), c32+ d(2, {1})}=min{7+8, 5+9}=14(3→2)
最后有:
d(0, {1, 2, 3})=min{c01+ d(1, { 2, 3}), c02+ d(2, {1, 3}), c03+ d(3, {1, 2})}
=min{3+7, 6+10, 7+14}=10(0→1)
所以,从顶点0出发的TSP问题的最短路径长度为10,路径是0→1→2→3→0。

动态规划法求解TSP问题的填表过程
假设n个顶点用0~n-1的数字编号,首先生成1~n-1个元素的子集存放在数组V[2n-1]中,设数组d[n][2n-1]存放迭代结果,其中d[i][j]表示从顶点i经过子集V[j]中的顶点一次且仅一次,最后回到出发点0的最短路径长度。(从顶点0出发)
城市代价矩阵
在这里插入图片描述

代码实现

#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
#define MAX_IN 10class Tsp
{
private:int city_number;		//城市个数int **distance;			//城市距离矩阵int **process;			//求最短路径的过程矩阵
public:Tsp(int city_number);		//构造函数void correct();			//矫正输入的城市代价矩阵void printCity();		//打印城市的距离矩阵void getShoretstDistance();	//动态规划法求最短路径void printProcess();		//打印过程矩阵};//构造函数
Tsp::Tsp(int city_num)
{int i = 0, j = 0;city_number = city_num;//初始化城市距离矩阵distance = new int*[city_number];cout << "请输入" << city_number << "个城市之间的距离" << endl;for (i = 0; i<city_number; i++){distance[i] = new int[city_number];for (j = 0; j<city_number; j++)cin >> distance[i][j];}//生成过程矩阵process = new int*[city_number];for (i = 0; i<city_number; i++){process[i] = new int[1 << (city_number - 1)];}}//纠正用户输入的城市代价矩阵
void Tsp::correct()
{int i;for (i = 0; i<city_number; i++){distance[i][i] = 0;}
}//打印城市距离
void Tsp::printCity()
{int i, j;//打印代价矩阵cout << "您输入的城市距离如下" << endl;for (i = 0; i<city_number; i++){for (j = 0; j<city_number; j++)cout << setw(3) << distance[i][j];cout << endl;}
}//动态规划法求最短路径
void Tsp::getShoretstDistance()
{int i, j, k;//初始化第一列for (i = 0; i<city_number; i++){process[i][0] = distance[i][0];}//初始化剩余列for (j = 1; j<(1 << (city_number - 1)); j++){for (i = 0; i<city_number; i++){process[i][j] = 0x7ffff;//设0x7ffff为无穷大//对于数字x,要看它的第i位是不是1,通过判断布尔表达式 (((x >> (i - 1) ) & 1) == 1的真值来实现if (((j >> (i - 1)) & 1) == 1){continue;}for (k = 1; k<city_number; k++){//不能达到k城市if (((j >> (k - 1)) & 1) == 0){continue;}if (process[i][j]>distance[i][k] + process[k][j ^ (1 << (k - 1))]){process[i][j] = distance[i][k] + process[k][j ^ (1 << (k - 1))];//cout<<i<<"行"<<j<<"列为:"<<process[i][j]<<endl;}}}}cout << "最短路径为" << process[0][(1 << (city_number - 1)) - 1] << endl;}//打印过程矩阵
void Tsp::printProcess()
{int i, j;for (j = 0; j<1 << (city_number - 1); j++){cout << setw(3) << j;}cout << endl;for (i = 0; i<city_number; i++){for (j = 0; j<1 << (city_number - 1); j++){if (process[i][j] == 0x7ffff)process[i][j] = -1;cout << setw(3) << process[i][j];}cout << endl;}
}//主函数
int main(void)
{int city_number;while (cin >> city_number){Tsp tsp(city_number);		//初始化城市代价矩阵tsp.correct();					//纠正用户输入的代价矩阵tsp.printCity();				//打印城市tsp.getShoretstDistance();		//求出最短路径tsp.printProcess();			//打印计算矩阵}return 0;
}

运行截图

在这里插入图片描述

分析与思考

这个实验主要借鉴了很多学姐的思想,比如说对某一阶段进行判断,可以采用一维并使用最低为相遇的算法进行判断,我相信在后面这个地方回流有很多疑问,因为现在天色已经很晚了,这篇博文就直接发了,如果读者有什么不理解的地方,欢迎进行评论,我们一起针对问题进行交流。


http://chatgpt.dhexx.cn/article/6qtpqfh2.shtml

相关文章

动态规划法求解0/1背包问题

一、求解0/1背包问题 1、问题描述 有n个重量分别为{w1&#xff0c;w2&#xff0c;…&#xff0c;wn}的物品&#xff0c;它们的价值分别为{v1&#xff0c;v2&#xff0c;…&#xff0c;vn}&#xff0c;给定一个容量为C的背包。 设计从这些物品中选取一部分物品放入该背包的方案&…

动态规划法——多段图的最短路径

目录 动态规划法的基本思想 多段图的基本想法 代码块&#xff08;Java&#xff09; 运行结果 动态规划法的基本思想: 将大问题划分成若干个小问题进行解决&#xff0c;从而一步步获取最优解动归从上到下分析问题&#xff0c;从下到上解决问题动归与分治法相似&#xff0c;其…

强化学习——动态规划法

文章目录 前言一、动态规划法简单认识1.基本概念2.适用情况3.求解步骤4.典型案例二、值函数1.累计折扣奖励2.状态值函数3.动作值函数4.状态值函数与动作值函数的关系5.贝尔曼方程&#xff08;动态规划法核心&#xff09; 三、策略评估1.基于状态值函数评估策略2.基于动作值函数…

南邮|算法分析与设计实验二 动态规划法

目录 实验目的 实验内容 实验步骤 一、最长公共子序列 二、矩阵连乘 实验目的 加深对动态规划法的算法原理及实现过程的理解&#xff0c;学习用动态规划法解决实际应用中的最长公共子序列问题和矩阵连乘问题&#xff0c;体会动态规划法和备忘录方法的异同。 实验内容 …

动态规划--算法

1、动态规划&#xff1a;将求解问题分解成若干个子问题&#xff0c;求解子问题&#xff0c;这些子问题不是独立的 求解后的子问题都会记录到表中&#xff0c;每个子问题仅求解一次&#xff0c; 下次遇到这些子问题直接取解 自底向上的方式计算最优解 2、最优子结构&#xff…

TSP问题,动态规划法

TSP问题是指旅行家要旅行n个城市&#xff0c;要求各个城市经历且仅经历一次然后回到出发城市&#xff0c;并要求所走的路程最短。各个城市间的距离可以用代价矩阵来表示。 假设从顶点i出发&#xff0c;令d(i, V)表示从顶点i出发经过V中各个顶点一次且仅一次&#xff0c;最后…

动态规划法的基本知识

一、动态规划方法相关概念 1、20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时&#xff0c;提出了著名的最优性原理(principle of optimality),同时&#xff0c;把多阶段过程转化为一系列单阶段问题&#xff0c;利用各阶…

动态规划法及其优化

在很多问题中&#xff0c;动态规划算法是我们的最优选择&#xff0c;比起递归算法&#xff0c;动态规划算法的时间复杂度和空间复杂度都更加优越&#xff0c;可以处理的数据规模更大。但是&#xff0c;动态优化算法的时间复杂度为O&#xff08;N*V&#xff09;&#xff0c;也就…

算法设计与分析之动态规划法

文章目录 前言一、动态规划法概述二、动态规划法设计思想三、动态规划法的基本要素四、动态规划算法的设计步骤五、动态规划法与分治法六、动态规划法与贪心法七、动态规划法示例总结 前言 大家好&#xff0c;我是一只勤勤恳恳的程序猿。本篇文章小猿将跟您分享算法设计与分析中…

算法-动态规划法

动态规划是在20世纪50年代由美国数学家贝尔曼为研究最优控制问题而提出的&#xff0c;当该方法在应用数学中的价值被大家认同以后&#xff0c;在计算机学界&#xff0c;动态规划法成为一种通用的算法设计技术用来求解多阶段决策最优化问题。 所以&#xff0c;同学们&#xff0…

动态规划算法

一 动态规划算法 动态规划(Dynamic Programming)算法的核心思想是&#xff1a;将大问题划分为小问题进行解决&#xff0c;从而一步步获取最优解的处理算法。 动态规划算法与分治算法类似。其基本思想也是将待求解问题分解成若干个子问题&#xff0c;先求解子问题&#xff0c;…

经典中的经典算法:动态规划(详细解释,从入门到实践,逐步讲解)

动态规划的重要性就不多说,直接进入正题 首先,我们看一下官方定义:定义: 动态规划算法是通过拆分问题&#xff0c;定义问题状态和状态之间的关系&#xff0c;使得问题能够以递推&#xff08;或者说分治&#xff09;的方式去解决。 动态规划算法的基本思想与分治法类似&#xf…

目标检测中的多尺度特征结合方式

目录 简述 解构物体检测各个阶段 FPN的演进 1&#xff09;无融合 2&#xff09;自上而下单向融合 a&#xff09;Faster/Master/Cascade RCNN中的FPN b&#xff09;RetinaNet中的FPN c&#xff09;Yolov3中的FPN 3&#xff09;简单双向融合 4&#xff09;复杂的双向融…

总结-CNN中的目标多尺度处理

Fly-AI竞赛服务平台 flyai.com 在开始学习之前推荐大家可以多在 FlyAI竞赛服务平台多参加训练和竞赛&#xff0c;以此来提升自己的能力。FlyAI是为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台。每周免费提供项目开源算法样例&#xff0c;支持算法能力变现以及快…

【MFEN:轻量级多尺度特征提取:SR网络】

MFEN: Lightweight multi-scale feature extraction super-resolution network in embedded system &#xff08;MFEN&#xff1a;嵌入式轻量级多尺度特征提取超分辨率网络&#xff09; 深度卷积神经网络&#xff08;CNN&#xff09;在超分辨率&#xff08;SR&#xff09;方面…

深度学习笔记---多尺度网络结构归类总结

目录 1.什么是图像金字塔 1.1 高斯金字塔 ( Gaussian pyramid): 1.2 拉普拉斯金字塔&#xff08;Laplacian pyramid&#xff09; 1.3 DOG金字塔 2. 多尺度网络&#xff08;MTCNN&#xff09; 2.1 多尺度输入网络 2.2 多尺度特征融合网络 2.2.1 并行多分支网络 2.2.2 串行…

【边缘注意:深度多尺度特征】

Learning a Deep Multi-Scale Feature Ensemble and an Edge-Attention Guidance for Image Fusion &#xff08;学习深度多尺度特征集成和图像融合的边缘注意指南&#xff09; 在本文中&#xff0c;我们提出了一种用于红外和可见光图像融合的深度网络&#xff0c;该网络将具…

多尺度特征的提取

1、图像金字塔 将图片进行不同尺度的缩放&#xff0c;得到图像金字塔&#xff0c;然后对每层图片提取不同尺度的特征&#xff0c;得到特征图。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低&#xff0c;且来源于同一张原始图的图像集合。其通过梯次向下采样获得&…

MSRN(多尺度超分辨率重建)

目前的研究倾向于使用更深层次的卷积神经网络来提高性能。然而,盲目增加网络深度不能有效改善网络。更糟糕的是,随着网络深度的增加,训练过程中出现了更多的问题,需要更多的训练技巧。在本文中,我们提出了一种新颖的多尺度残差网络 (MSRN) 来充分利用图像特征,该网络优于…

【multi_scale】多尺度训练——目标检测训练trick

文章目录 1 多尺度训练的介绍2 代码解析3 感谢链接 1 多尺度训练的介绍 多尺度训练对全卷积网络有效&#xff0c;在训练时&#xff0c;每隔一定的 iterations&#xff0c;在一定尺寸范围内&#xff0c;随机选取一种 img_size 进行训练。通过对不同尺度的图像进行训练&#xff…