排序数组中的最低成本累积路径

时间:2013-11-08 11:31:07

标签: arrays algorithm

这个问题是前面提到的问题的延伸:
Least cost path in a sorted array

给定排序数组A,例如{4,9,10,11,19}。从i->j搬迁的费用为 abs(A[j] - A[i]) + cost_incurred_till_i。从给定元素开始,例如10。找到最低成本路径而不访问相同的元素两次。

对于给定的数组:

10->9->4->11->19 cost: 1+(1+5)+(1+5+7)+(1+5+7+8) = 41
10->4->9->11->19 cost: 5+(5+5)+(5+5+2)+(5+5+2+8) = 47
10->9->11->4->19 cost: 1+(1+2)+(1+2+7)+(1+2+7+15) = 39 
10->11->9->4->19 cost: 1+(1+2)+(1+2+5)+(1+2+5+15) = 35 --one of optimal paths
10->11->19->9->4 cost: 1+(1+8)+(1+8+10)+(1+8+10+5) = 53
10->11->19->4->9 cost: 1+(1+8)+(1+8+15)+(1+8+15+5) = 63
...

我试图用最近邻法来解决这个问题。

 i = start
 While (array is not empty)
    ldiff = A[i] - A[i-1]
    rdiff = A[i+1] - A[i]
    (ldiff < rdiff) ? sum += ldiff : sum += rdiff
    remove A[i]

在这种情况下,最近邻居适用于我们没有相等加权路径的情况。我意识到这是TSP问题。什么是解决这个问题的最佳方法?我应该使用像Christofides或其他算法的TSP启发式算法吗?

2 个答案:

答案 0 :(得分:0)

你很近,你可以稍微修改最近的邻居。当两个邻居相等时,检查该邻居的过去元素,然后进入与相反的方向(更靠近)(以避免回溯太多)。如果这些元素距离相同,那就继续向前看,直到它们没有。如果你在看到差异之前达到了界限,那就去吧。

你的例子很好看:

我们唯一的分支点是决定是否在9的第一步中访问1110。通过两个方向浏览它们会显示4194更接近10,因此请远离11


显然,对于没有很多顺序均匀间隔元素的数组,这会更快。如果它们的 none 均匀分布,那么它将与您的相同,以n步进行。

最糟糕的情况是,您必须在每一步都看到一直两端,这将访问每个元素。由于我们为每个n元素运行一次,因此它出现在 O(n ^ 2)。一个例子是一个带有所有均匀间隔元素的数组,从死点开始搜索。

答案 1 :(得分:0)

有一个O(n 2 )动态编程解决方案。我不知道它是否是最佳的。

下一个选择始终是未访问节点中的直接邻居,因此访问节点形成连续范围。逻辑子问题是在给定受访节点范围的情况下找到部分解决方案。子问题的最佳解决方案仅取决于访问范围和最后访问的节点(必须是其中一个端点)。

可以使用标识访问范围的两个索引对子问题进行编码,该顺序指示最后访问的节点。子问题(a,b)的解决方案是部分解决方案,假设从 min(a,b) max(a,b)的节点已经被访问过, a 是最后访问过的节点。它可以递归地定义为

更好
  • insert(a, solve(a - dir, b))
  • insert(a, solve(b + dir, a))

如果 b &gt; = a ,则 dir 为1,否则为-1。

有两个基本案例。子问题(0,n-1)具有解决方案{A[0]},子问题(n-1,0)具有解决方案{A[n-1]}。这些对应于最终选择,它是第一个节点或最后一个节点。

完整的问题对应于子问题(s,s),其中 s 是起始元素的索引。