给定一组表示飞行路径的坐标,练习是找到最大距离(给定n个要通过的点数)。为了说明问题,我们在2D网格上显示了一条飞行路径,如下所示:
以下是算法应该对参数n(整数)执行的操作。
问题是找到一种算法,可以扫描所有点并尝试组合所有距离并返回最终路径的长度。
我们已经有了一个可以获得两点距离的方法:
/**
* @return the distance between the two coordinates
*/
public double distance(Coordinate destination) {}
/**
* @return the farthest coordinate from start
*/
public Coordinate coordMax() {}
/**
* @return max distance using n points
* I would maybe try to go for a recursive solution
* and already have the 2 corner cases down.
*/
public double statMaxDistance(int n) {
if (n == 0)
return coordTable[0].distance(coordTable[coordTable.length - 1]);
if (n == 1)
return coordTable[0].distance(coordMax());
// TODO recursive step
return statMaxDistance();
}
问题是:
有没有办法完成这项任务,而不是遍历整个路径的每个点,一个接一个地尝试所有可能的组合,计算所有可能的距离,最终以最远的路径结束?
遵循这样一种方法似乎很有感觉,只有1或2个点会沿着整个路径移动,但是在计算给定3个参考点的最大距离时,这样的算法会非常贪婪。
答案 0 :(得分:0)
这可以使用动态程序解决。假设D[i][j]
是从起始点到最后一个点为i
的{{1}} - 中间点的最大距离。您的解决方案将是j
。
那么如何解决这个问题?第一列D[n][endPoint]
很容易计算。这只是相应点到起点的距离。其他列有点棘手。您需要检查上一列中最后一个点严格位于当前点之前的所有条目。因此,要计算条目D[0][...]
,您必须计算:
D[i][j]
这意味着:迭代所有可能的D[i][j] = max_{k < j} (D[i - 1][k] + distance(k, j))
,使k
小于k
(即点j
位于当前点k
之前) 。将得到的距离计算为距j
(这是k
部分)的距离与D[i - 1][k]
到k
之间的距离之和。将这些值的最大值放入j
。如果您需要在最后重建路径(即您不仅仅对最大距离感兴趣),您可能还想跟踪D[i][j]
。请注意,可能存在没有有效解决方案的单元格(例如k
- 您无法将D[1][0]
指向第二个(索引0
)中间点。
对每个列中的每个中间点执行此操作,直到1
。最后一步是为D[n - 1][...]
再次执行此过程,严格来说不需要位于D[n][endPoint]
数组中(因为您只对单个值感兴趣,而不是整个列)
计算完此值后,这就是您的解决方案。如果要查找实际路径,则必须使用每个单元格存储的D
值进行回溯。