动态编程:遍历城市

时间:2012-11-17 21:38:54

标签: algorithm dynamic-programming

我遇到了这个问题:

有两个人。有n个城市的有序序列,并且给出了每对城市之间的距离。您必须将城市划分为两个子序列(不一定是连续的),以便人员A访问第一个子序列中的所有城市(按顺序),人员B访问第二个子序列中的所有城市(按顺序),并且这样的总和A和B行进的总距离最小化。假设人A和人B最初在各个子序列中的第一个城市开始。

我寻找答案,答案是:
设c [i,j]是第一个人在城市i停靠,第二个人在城市j停留的最小行程距离。假设我< j

c [0,j] = k从1到j-1的总和(d [k,k + 1])
c [i,j] = min(c [k,j] + d [k,i])如果i!= 0其中0

解决方案也可以在问题10 here

中看到

现在,我的问题是:
这个解决方案没有i = 1的定义(因为那时k没有价值) 2.现在,假设我们找到了c [2,3]。它将是c [1,3] + d [1,2]。现在c [1,3]意味着人    B访问0,2和3,人A保持在1或B人访问2和3和A.    访问0和1.此外,c [2,3]表示A只访问了2 / 0,1,2 / 0,2 / 1,2。所以,

 c[1,3] = min(d[0,1]+ d[2,3], d[0,2]+ d[2,3])
 c[2,3] = min(d[0,1]+ d[1,2], d[0,2]+ d[1,3], d[1,2]+d[0,3], d[0,1]+d[1,3])

可以看出解决方案并不重叠。

换句话说,在c [1,3]中B已经涵盖了2。因此,如果我们在c [2,3]中包含c [1,3],则意味着A和B都会访问2,这不是必需的,因为它只会增加成本。

如果我错了,请纠正我。

2 个答案:

答案 0 :(得分:2)

Q ::城市序列的双人遍历:您将获得n个城市的有序序列,以及每对城市之间的距离。设计一种算法,将城市划分为两个子序列(不一定是连续的),使得人A在第一个子序列中按顺序访问所有城市(按顺序),人B在第二个子序列中按顺序访问所有城市(按顺序),以及A和B行进的总距离最小化。假设人A和人B最初在各个子序列中的第一个城市开始。

以下是我对解决方案::

的理解

让我们说城市的数字从1到n。我们在C(i,j)上递归,如果人A在城市i结束并且人B在城市j结束,则行进的最小距离。假设不失一般性i<学家

设C(0,n)表示人A不访问任何城市,而人B从[1,n]访问所有城市。

因此,C(0,j)= d(1,2)+ d(2,3)+ .... + d(j-1,j)(B从城市1开始,按顺序进行城市j)。

C(i,j),其中i不是0 =以下两种情况中的最小值:

案例1:A人在城市i开始和停止。在这种情况下,C(i,j)=人B行进的距离,按顺序从1到j前往所有城市,跳过城市i = d(1,2)+ d(2,3)+ ... + d(i-1,i + 1)+ d(i + 1,i + 2)+ ... + d(j-1,j)

案例2:人A在我之前在某个城市开始,因此在去往城市i之前有一个城市k(他在遍历中的第二个城市)。在这种情况下,C(i,j)=最小{C(k,j)+ d(k,i)}其中k可以从1变化到i-1。

问题的解决方案是最小{C(i,n)},其中i从0变化到n-1。

我们可以按行主要顺序填充DP矩阵,因为C(i,j)的每个计算需要距离d或C(k,j),其中k <1。一世。

算法的运行时间为O(n ^ 3),因为我们进行计算的O(n ^ 2)个条目,每个计算需要O(n)时间。

编辑::我认为讲义中给出的解决方案缺少case1。

答案 1 :(得分:1)

你说得对,提议的解决方案有些混乱和不正确。

考虑问题的方法一如既往地是归纳的:如果我需要解决大小为n的问题,我怎样才能将它减少到更小的问题(0,...,n-1)。如果您想为大小n解决此问题,您会注意到其中一个玩家需要将节点n带入其路径。

C [i,j]函数是一个辅助函数,表示你所描述的&#34;最小成本,A停在i,B停在j&#34;。

要到达状态C [i,j],玩家B必须从j-1来到j,除非当然j-1 = i。在j-1 = i的情况下,则j必须来自某些k <1。一世。因此,函数C [i,j]可以描述如下:

C[i,j] = {
   C[i,j-1] + d[j-1,j]                   (if i < j-1)
   min C[k,i] + d[k,j] for 0 <= k < i    (if i = j-1)
}

使用此设置,您的基本情况只是C [0,1] = d [0,1]。

你的最终答案是min C [k,n] 0 <= k