Algorithm 动态规划:城市的遍历

Algorithm 动态规划:城市的遍历,algorithm,dynamic-programming,Algorithm,Dynamic Programming,我遇到了一个问题: 有两个人。存在n个城市的有序序列,并给出了每对城市之间的距离。您必须将城市划分为两个子序列(不一定连续),以便人员A访问第一个子序列中的所有城市(顺序),人员B访问第二个子序列中的所有城市(顺序),并且使A和B行驶的总距离之和最小化。假设人员A和人员B最初从各自子序列中的第一个城市开始 我寻找它的答案,答案是: 设c[i,j]为第一人在城市i停车,第二人在城市j停车的最小行驶距离。假设i

我遇到了一个问题:

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

我寻找它的答案,答案是:
设c[i,j]为第一人在城市i停车,第二人在城市j停车的最小行驶距离。假设i 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也给出了解决方案

现在,我的问题是:
1.此解决方案没有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]表示仅访问了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])
可以看出,解决方案没有重叠

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


如果我错了,请纠正我。

你是对的,建议的解决方案有些混乱和不正确

思考这个问题的方法总是归纳的:如果我需要解决大小为n的问题,我如何将它简化为更小的问题(0,…,n-1)。如果要解决大小为n的问题,请注意其中一个玩家需要将节点n带到其路径中

C[i,j]函数是一个辅助函数,如您所述,表示“a在i处停止,B在j处停止的最小成本”

为了到达C[i,j]状态,玩家B必须从j-1到达j,当然除非j-1=i。如果j-1=i,那么j必须来自k
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[i,j]={
C[i,j-1]+d[j-1,j](如果imin C[k,i]+d[k,j]表示0Q::城市序列的两人遍历:给定一个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,他在前往城市i(他穿越的第二个城市)之前旅行。在这种情况下,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 算法的运行时间将是O(n^3),因为有O(n^2)个条目需要我们进行计算,每次计算都需要O(n)个时间


<>编辑::我认为讲义中给出的解决方案是缺少Case1。

这不是同一个旅行者访问所有城市,从旅行者B的终点开始,通过“第一”到“A”的端点?@ JDV JANDEVAAN,如果你认为路径是在“VIVE”上分裂的话,你也许可以看到它。边缘,意味着该边缘被移除另一个角度:让“状态”为哪个人在哪个城市,给你一个二次节点数。你从一个节点移动到下一个节点,让a或B移动到下一个未访问的城市,即每个节点最多两条边缘,因此是二次边数。最短路径(由DP计算,即DAG最短路径)以二次(非三次)时间给出解。@dejan…你是对的,但我认为你的基本情况不正确…C[0,1]=0,因为A将为0,B将为1(给出了城市应划分为两个子序列,一个子序列不需要遍历另一个子序列的城市,因此B不需要从0开始)@Dejan我认为有问题。假设最优解是A从1到m个城市,B从m+1到n个城市,那么你的解找到了吗。当你到达第二种情况时(I=j-1)问题是你强迫B从i以下的某个地方来,而不是必须的——j可能是B旅行的起点。我认为你可以通过在开始处添加一个幽灵/僵尸城市0来解决这个问题,它与任何其他城市的距离为零,并定义基本情况C(0,1)=d(0,1)=0。如果你认为我是对的,请告诉我。