TSP(不要怕)动态规划(我这里很友好)

代码比较简洁,没有类,也没有用到动态申请内存,对小白蛮友好的。看到了许许多多的题解,感觉对小白不友好,所以本菜站了出来 如果有啥子问题,希望能提出来改正。毕竟这是本小白第一篇题解

思路

对于图G=(V,E),假设从顶点i出发,V’= V - i,则d(i,V’)表示从顶点i出发经过V’中各个顶点一次仅一次,最后回到顶点i的最短路径长度,初始子问题就是d(k,{})表示点k到顶点i的距离。

现在考虑原问题的一部分,d(k,V’-{k})表示从顶点k出发经过V’-{k}中各个点一次仅一次,最后回到出发点i的最短路径长度,则:

d(k,{}) = cki;

d(i,V’) = min(cik + d(k,V’- {k}))(k ∈V’)

(3)从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)

然后逆推就可得出最短路径。

上代码

#include
using namespace std;
int l[20][20],d[20][1000];//l位代价矩阵,d为状态矩阵 
int main()
{
	int n,i,j,k;//n个城市
	cin >> n;
	for(i = 0;i < n; ++i)//构造代价矩阵 
	{
		for(j = 0;j < n; ++j)
		{
			cin >> l[i][j];
			if(i == j) l[i][j] = 0xffff;
			//自己到自己的距离肯定是无穷大啊
			//所以最难到达的地方是自己啊	
		}	
	}
	for(i = 1;i < n; ++i)
		d[i][0] = l[i][0];
	for(j = 1;j < 1 << (n - 1); ++j)
	//用二进制来压缩状态 
	{
		for(i = 0;i < n; ++i)
		{
			d[i][j]  = 0xffff;
			//初始距离为很大 
			for(k = 1;k != n; ++k)
			//判断k城市是否在集合中 
				if(j >> (k - 1) & 1)//k如果在集合中
				//位运算和与运算了解一下
					d[i][j] = min(d[i][j],d[k][j ^ 1 << (k - 1)] + l[i][k]); 
					//以k为中间节点寻找最后面最短的路径 
		}
	}
	cout << "打表:" << endl; 
	for(i = 0;i < n; ++i)
	{
		for(j = 0;j < 1 << (n - 1); ++j)
			cout << d[i][j] << " ";
		cout << endl;
	}
	cout << "最短路径为:" << d[0][1 << (n - 1) - 1] << endl;			
} 
/*这是测试数据,0在这里这是为了使输入方便一点
4
0 3 6 7
5 0 2 3
6 4 0 2
3 7 5 0
*/

TSP(不要怕)动态规划(我这里很友好)_第1张图片
这是运行截图,注意不是按元素组合来输出的,而是按0到2的k次方-1的顺序输出的。
蟹蟹大家阅读!!!爱你们哟!!!

你可能感兴趣的:(算法,tsp,动态规划,c++)