旅行商问题的动态规划解决

 

旅行商问题是一个著名的NP问题,不能找到多项式解。不过可以用动态规划的方法把时间复杂度从O(N!)降低到O

 

(2^N)。对于解决小规模的旅行商还是可以实现的。

http://icpc.ahu.edu.cn/OJ/Problem.aspx?id=420

发现枚举过程中还是有很多重复计算的,所以可以存贮一下状态,避免了重复计算。

 

 

开辟N+1维数组,dp[N][2][2]..[2]

dp[cur][p1][p2]..[pn]表示,当前人在cur位置,并且p1--pn走过的为1,未走过的为0。

可见空间复杂度为N*2^N。

 

状态转移方程为dp[cur][p1]..[1]..[pn]=min{dp[i][p1]..[0]..[n]+Dis[cur][i]};其中i为1--N地点中已经走过的

 

地点。因为当前状态只能从已经走过的那些地方走过来,所以只要选一个最短的,就表示走完以上地点,并且停在

 

当前点需要的最短路程就是这么多。

 

 

由于回路必然包含每一个点,所以从任何点出发,得到的最短路径都是一定的。所以我的程序假设就从第一个点出

 

发。边界条件就是,dp[0][1]。dp[0][1]=0,表示在第0个地点(我是用0--N-1表示N个地点的),1的二级制是

 

00000001,表示只有第一个可以走过。

要注意:既然假设从第一个地点出发,所以在递归自顶向下搜索的时候,只有最后一次才能回出发点!

即dp[cur][p1]..[1]..[pn]中,在p1--pn中只有2个为1的时候,也就是只有出发点和第二个地点的时候,才能从第

 

二个地点回到出发点。

 

最终的结果只要取min{dp[i][1]..[1]..[1]+Dis[0][i]}就好了,表示回到出发点0。构成完整回路。

 

当然如果N比较大,开那么多维的数组比较麻烦,而且可能编译不能通过。所以我们用一个数的不同位分别表示一个

 

城市是否走过。于是将N维压缩到一维。

 

dp[N][2]..[2]变成了 dp[N][2^N]

 

 

 

 

本文链接:https://my.lmcjl.com/post/6592.html

展开阅读全文

4 评论

留下您的评论.