C++动态规划解决TSP(旅行商)问题

这篇具有很好参考价值的文章主要介绍了C++动态规划解决TSP(旅行商)问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目描述:

某旅行商希望从某城市出发经过一系列的城市最后再回到出发的城市。这些城市之间均可直航,他希望只经过这些城市一次且旅行的总线路最短。设有n个城市,城市的编号从1到n。

输入第一行为整数n,表示城市的数量。其后n行,每行有n个整数,用空格隔开,表示城市之间的距离。其中的第1个数表示城市1和城市2之间的距离,第2个数表示城市1和城市3之间的距离,…,第 n-1个数表示城市1和城市n之间的距离,依次类推。

解题思路:

给出一个样例,5个城市

旅行商问题 动态规划 c++,c++,动态规划,算法

二维表格表示城市之间的距离

0 4 8 6 5
4 0 3 2 10
8 3 0 8 7
6 2 8 0 3
5 10 7 3 0

显然我们可以想到有很多种路线,

1 ——>  2 ——> 3 ——> 4 ——> 5 ——>  1;

1 ——>  2 ——> 3 ——> 5 ——> 4 ——>  1;

如果把所有情况都列出来,显然是可以解决这个问题的(回溯法),利用动态规划去解决这个问题则需要去将这个问题分割成子问题,下面给出dp数组的含义以及分析过程:

dp[i][j] :从i 出发经过集合 j里面所有节点并回到起点的最小距离

乍一看可能觉得很蒙圈,下面给出几个dp[][]的值帮助理解

dp[1][0] = ?  1 代表第一个城市,也就是起点,0是点的集合,那么意思就是没有点,那么从1回到1的距离是0,dp[1][0] = 0;

dp[2][0] =? 2代表第二个城市,0的意思也是不需要再经过任何点,从2回到1的距离即dp[2][0]的值dp[2][0]  = 4

以此类推,我们可以得到所有的dp[n][0],这也是dp的初始化的一部分,因为我们要计算的是经过所有城市的花费,那么dp[1][0]、dp[1][1]、dp[1][2]都是无意义的,我们只需要去计算dp[1][除了起点之外的所有城市]。

dp[2][1] = ?从2出发,经过1个城市回到1的值?

这里的1并不代表要经过多少个城市,因为这个问题本质上是组合问题,我们要去准确的知道经过的是哪些城市,而不是数量,因此 j 也就是这里的 1 是一个二进制数,利用二进制来表示要经过的点 1  ==  0001 (5个城市除去起点还剩4个),注意这里并不表示第一个城市,回看我们的dp定义——从i 出发经过集合 j里面所有节点并回到起点,已经包含了回到起点,那么这里表示的其实是第二个城市。回到dp[2][1],从2出发经过  0001(就是第2个城市)那么显然这个是无意义的。它与dp[2][0]的意义相同。

到这应该能知道dp[3][1]代表的意思了,从3出发经过 0001(第2个城市)回到1的最小距离,那么怎么计算呢?

动态规划最重要的便是状态转移当前求的问题要能够从之前的问题求得。

3 ——> 2 ——> 1   可以看不可以看成

3 ——> 2 ——> 1   加粗的部分我们是不是已经计算过了?是的就是dp[2][0],

那么dp[3][1] = dp[2][0] + value[3][2](value[i][j]代表从i到j的距离)

dp[4][3] 的意思呢?

从4出发经过 0011(第2和3城市)回到1的最小距离,

有两种方案:4 ——> 3 ——> 2——> 1                4 ——> 2 ——> 3——> 1

第一种的状态转移:4 ——> 3 ——> 2——> 1   dp[4][3] = dp[3][1] + value[4][3];

第二种的状态转移:4 ——> 2 ——> 3——> 1   dp[4][3] = dp[2][2] + value[4][2];这里为什么是dp[2][2]呢?2 = 0010(也就是第三个城市)

显然将两者取min即使答案,至此基本的思路就解释完了,下面给出完整的dp表格以及代码,具体的细节就给读者自行体会了。

旅行商问题 动态规划 c++,c++,动态规划,算法文章来源地址https://www.toymoban.com/news/detail-774375.html

#include<iostream>
#include<vector>
#include<algorithm>
#include<time.h>
#include<sys/timeb.h>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<vector<int>>value(n+1,vector<int>(n+1,0));
	int dp_Size=(1 << (n - 1));
	int ans = 10000;
	vector<vector<int>>dp(n, vector<int>(dp_Size,10000));
	vector<int>dp_ans(n - 1);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cin >> value[i][j];
		}
	}

	for (int i = 1; i < n; i++) {
		dp[i][0] = value[i + 1][1];
	}
	for (int i = 1; i < dp_Size-1; i++) {
		for (int j = 1; j < n; j++) {
			if ((1 << (j - 1) & i) != 0) {
				continue;
			}
			for (int k = 1; k < n;k++) {
				if (((1 << (k - 1)) & i)) { //按位与
					dp[j][i] = min(dp[j][i], dp[k][i-(1<<(k-1))] + value[j+1][k + 1]);
					dp_ans[j - 1] = dp[j][i];
				}
			}
		}
	}	
	for (int i = 1; i < n; i++) {
		ans = min(ans, value[1][i + 1] + dp_ans[i - 1]);
	}
	/*for (int j = 0; j < n; j++) {
		for (int i = 0; i < dp_Size; i++) {
			cout << dp[j][i]<<"  ";
		}
		cout << endl;
	}*/
    //打印dp数组
	cout << endl;
	/*for (int i = 0; i < n - 1; i++) {
		cout << dp_ans[i]<<"\t";
	}*/
	cout << ans;

	return 0;
}

到了这里,关于C++动态规划解决TSP(旅行商)问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 运筹系列82:使用动态规划求解TSP问题

    定义 c ( s , k ) c(s,k) c ( s , k ) 为当前在 k k k ,待访问点的集合 s s s ,最后返回城市0的最短路径,那么Bellman方程为: c ( s , k ) = min ⁡ i ∈ s { c ( s − { i } , i ) + d i , k } c(s,k)=min_{i in s}{c(s-{i},i)+d_{i,k}} c ( s , k ) = min i ∈ s ​ { c ( s − { i } , i ) + d i , k ​ } 为了使用方便,这里

    2024年02月06日
    浏览(33)
  • 旅行商问题TSP

    目录 蚁群算法 Hopfield网络 遗传算法 免疫算法 求解思路 Hopfield网络适合求结果的 次优解 ,可以保证解向能量函数最小值方向收敛,但不能确保达到全局最小点。 实现能量函数 网格能量的最小值对应于最佳或者次最佳的路径距离。 实现动态方程  repmat - 重复数组副本    

    2024年02月08日
    浏览(31)
  • 分支限界TSP(旅行商问题)

    【问题】 TSP 问题(traveling salesman problem) 是指旅行家要旅行 n 个城市, 要求各个城市经历且仅经历一次然后回到出发城市, 并要求所走的路程最短。 【想法】 首先确定目标函数的界[down, up], 可以采用贪心法确定 TSP 问题的一个上界。 如何求得 TSP 问题的一个合理的下界呢

    2024年02月08日
    浏览(29)
  • 旅行商问题(枚举,回溯,动态规划,贪心,分支界限)

    假设有一个货郎担要拜访n个城市,他必须选择所要走的路程,路程的限制时每个城市只能拜访一次,而且最后要走到原来出发的城市,要求路径长度。 旅行商问题将要走过的城市建立成一个完全图。稠密图,所以用临接矩阵来存。 由于路径的特殊性,可以正走也可以反着走

    2024年02月04日
    浏览(31)
  • [动态规划,二进制状态压缩] 旅行商问题

    题目描述 一个国家有 n 个城市,每两个城市之间都开设有航班,从城市 i 到城市 j 的航班价格为 cost[i, j] ,而且往、返航班的价格相同。 售货商要从一个城市出发,途径每个城市 1 次(且每个城市只能经过 1 次),最终返回出发地,而且他的交通工具只有航班,请求出他旅

    2024年01月24日
    浏览(31)
  • 旅行商问题 Traveling Salesman Problem(TSP)

    一个商人从一点出发,经过所有点后返回原点。 目标:经过所有点的最短路程。 约束: 1,除起点和终点外,所有点当且仅当经过一次; 2,起点与终点重合;所有点构成一个连通图 图论解释:该问题实质是在一个带权完全无向图中,找一个权值最小的哈密尔顿回路 哈密尔

    2024年02月03日
    浏览(28)
  • 旅行商问题(TSP)及Python图论求解

    旅行商问题(Traveling Salesman Problem, TSP)是指给定一个城市的集合以及每两个城市之间的距离,找到一条经过每个城市恰好一次且路径最短的回路。 可以想象成一个旅行商要拜访多个城市,问他如何安排路线,使得行程最短。这个问题可能看起来简单,但是随着城市数量的增

    2024年02月12日
    浏览(25)
  • C++算法 —— 动态规划(2)路径问题

    每一种算法都最好看完第一篇再去找要看的博客,因为这样会帮你梳理好思路,看接下来的博客也就更轻松了。当然,我也会尽量在写每一篇时都可以让不懂这个算法的人也能边看边理解。 动规的思路有五个步骤,且最好画图来理解细节,不要怕麻烦。当你开始画图,仔细阅

    2024年02月06日
    浏览(35)
  • Hopfield神经网络求解旅行商(TSP)问题matlab代码

            1.网络结构         连续Hopfield神经网络(Continuous Hopfield Neural Network,CHNN)的拓扑结构和离散Hopfield神经网络的结构类似,如图11-1所示。连续Hopfield网络和离散Hopfield 网络的不同点在于其传递函数不是阶跃函数,而是连续函数。         与离散型Hopfield神经网络不

    2024年02月14日
    浏览(28)
  • 强化学习求解TSP:Qlearning求解旅行商问题(Traveling salesman problem, TSP)提供Python代码

    Q-learning是一种强化学习算法,用于解决基于奖励的决策问题。它是一种无模型的学习方法,通过与环境的交互来学习最优策略。Q-learning的核心思想是通过学习一个Q值函数来指导决策,该函数表示在给定状态下采取某个动作所获得的累积奖励。 Q-learning的训练过程如下: 1. 初

    2024年02月03日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包