给定排序数组A
,例如{4,9,10,11,19}
。从i->j
移出的费用为abs(A[j]-A[i])
。从给定元素开始,例如10
。找出最少的成本路径,而无需两次访问相同的元素。因此,在此示例中,解决方案将是10->9->4->11->19
,即1 + 5 + 7 + 8 = 21
。
我试图用最近邻法来解决这个问题。
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启发式算法吗?
答案 0 :(得分:3)
对于您的情况,最低成本是21,请参阅
10->9->4->11->19 ==> 1 + 5 + 7 + 8 = 21.
我认为,对于一般情况,如果你从第i个位置开始,最低成本是路径,最小值
A[i]->A[i-1]-> ...->A[1] -> A[i+1] -> A[i+2] -> ...->A[n] and
A[i]->A[i+1]-> ... ->A[n] ->A[i-1] ->A[i-2] -> ...->A[1]
答案 1 :(得分:1)
处理较小或最大的元素,取决于哪个更接近(在值中,而不是索引)到起始元素,然后简单地处理剩余的元素到右边或左边(取决于我们是否处理了最小的元素或最大的元素)。
所以,从4,9,10,11,19
开始10
:
从10
到最小元素4
的距离为6,从10
到最大元素19
的距离为9,因此转到{{1} }。
然后按排序顺序处理剩余的元素 - 4
。
这为我们提供9, 11, 19
,费用为10 -> 4 -> 9 -> 11 -> 19
。
这可以在6 + 5 + 2 + 8 = 21
。
注意:强>
值得注意的是,只要我们首先向最近的一侧移动,然后向另一侧移动(无论我们处理哪个元素,只要我们不多次改变方向),我们就会得到最佳结果。
这就是O(n)
也提供10 -> 9 -> 4 -> 11 -> 19
的原因。