【发布时间】:2011-01-14 23:53:03
【问题描述】:
首先,这是我们去年在一个项目中必须解决的四个问题之一,我找不到合适的算法,所以我们采用了蛮力解决方案。
问题:这些数字在一个未排序的列表中,并且只支持一种类型的操作。操作定义如下:
给定位置 i 和位置 j,该操作将位置 i 处的数字移动到位置 j,而不改变其他数字的相对顺序。如果 i > j,则位置 j 和 i - 1 之间的数字的位置增加 1,否则如果 i
我们需要设计一种算法,给定一个数字列表,确定最优(就成本而言)移动序列以重新排列序列。
尝试: 我们的部分调查围绕 NP 完备性,我们将其作为决策问题,并尝试找到对 Garey 和 Johnson 的书中列出的任何问题的合适转换:计算机和难处理性,但没有结果。在 Donald E. Knuth 的书《计算机编程艺术》中也没有直接提及(从我们的角度来看)这种变化。 3 排序和搜索。我们还分析了对链表进行排序的算法,但没有一种算法能很好地找到最佳的运动顺序。
请注意,这个想法不是要找到一种对序列进行排序的算法,而是要告诉我组织序列的成本方面的最佳运动序列,您可以复制并对其进行排序以分析最终位置如果你愿意的话,实际上我们可以假设列表包含从 1 到 n 的数字,所以我们知道要放置每个数字的位置,我们只关心最小化步骤的总成本。
我们测试了几种贪心方法,但都失败了,分而治之的排序算法无法使用,因为它们在列表中没有成本的部分进行交换,而且我们的动态编程方法必须考虑很多情况。
蛮力递归算法采用从 i 到 j 的所有可能的运动组合,然后再次采用其余元素的所有可能时刻,最后它返回对列表进行排序的总成本较低的序列,如你可以想象这个算法的成本是残酷的,并且对于超过 8 个元素来说是不切实际的。
我们的观察:
n 次移动不一定比 n+1 次移动便宜(与 O(1) 的数组交换不同)。
将一个元素从位置 i 移动到 j 基本上有两种方法:一种是直接移动它,另一种是围绕 i 移动其他元素,使其到达位置 j。
最多您进行 n-1 次移动(未触及的元素单独到达其位置)。
如果这是最佳的移动顺序,那么您没有移动同一个元素两次。
【问题讨论】:
-
您介意举一个“操作”的小例子吗?我不完全理解它的描述方式。
-
@nightcracker: 对我来说它看起来像一个简单的
insert(remove(i), j),因此该元素的位置将从i 变为j,成本为abs(i-j) -
如果您发布一个示例或迄今为止最佳解决方案的(伪)代码会有所帮助。
-
输入:4,1,2,3 输出:pos 0 到 3 成本:3
-
输入:1,3,4,2 输出:pos 3 to 1 成本:5
标签: algorithm sorting optimization