对一组有修改成本的数字进行排序

5

首先,去年我们在一个项目中需要解决四个问题之一,但我找不到合适的算法,所以我们采用了暴力解决方案。

问题:这些数字在一个未排序的列表中,只支持一种操作。该操作定义如下:

给定位置i和位置j,操作将在位置i处的数字移动到位置j,而不改变其他数字的相对顺序。如果i>j,则介于位置j和i-1之间的数字的位置增加1;否则,如果i<j,则介于位置i+1和j之间的数字的位置减少1。此操作需要i步来查找要移动的数字,并需要j步来定位要移动到的位置。然后,将数字从位置i移动到位置j所需的步骤数为i+j。

我们需要设计一个算法,给定一组数字,确定重新排列序列的最佳(成本最低)移动序列。

尝试:我们的研究涉及NP完全性,将其作为决策问题,并尝试找到适当的转换来解决Garey和Johnson的书中列出的任何问题,但没有结果。 Donald E. Knuth的书:计算机程序设计艺术卷3排序和搜索中也没有直接参考(从我们的角度来看)这种变化。我们还分析了用于排序链表的算法,但它们中没有一个能够提供找到最佳移动序列的好方法。

请注意,我们的想法不是要找到对序列进行排序的算法,而是告诉我在成本方面最优的移动序列,以组织该序列。如果您愿意,可以复制并将其排序以分析元素的最终位置。实际上,我们可以假设列表包含从1到n的数字,因此我们知道要放置每个数字的位置,我们只关心最小化步骤的总成本。

我们尝试了几种贪心算法,但它们都失败了,分治排序算法不能使用,因为它们会无成本地交换列表的部分,而我们的动态编程方法必须考虑许多情况。

暴力递归算法采用所有可能的i到j的移动组合,然后再考虑其余元素的所有可能移动,最后返回按总成本排序的序列。正如您所想象的那样,这个算法的成本是巨大的,对于超过8个元素就不可行了。

我们的观察:

  • n个元素的移动不一定比n+1个元素的移动更便宜(与数组中的交换不同,数组中的交换是O(1))。

  • 基本上有两种方法将一个元素从位置i移动到位置j:一种是直接移动它,另一种是以某种方式移动i周围的其他元素,使其达到位置j。

  • 最多只需进行n-1次移动(未触及的元素单独到达其位置)。

  • 如果这是最优的移动序列,则您没有重复移动同一元素。


您介意给出一个“操作”的小例子吗?我不完全理解描述的方式。 - orlp
@nightcracker:在我看来,这似乎是一个简单的insert(remove(i),j),因此该元素的位置将从i更改到j,其代价为abs(i-j) - ruslik
如果您能发布一个示例或者目前最佳解决方案的(伪)代码,那将会很有帮助。 - Apalala
输入:4,1,2,3 输出:位置0到3,成本为3。 - David Darias
输入:1、3、4、2 输出:位置 3 到 1 成本:5 - David Darias
我没有发布我们制作的完整摘要,因为它有6页,而且是用西班牙语写的。如果您有任何疑问,请问我,我会尽快回答。 - David Darias
1个回答

2
这个问题看起来很适合使用近似算法,但那只能给我们一个足够好的答案。由于您想要最佳答案,我会改进蛮力方法的步骤。

我会使用回溯方法,保持找到的最佳解决方案,并剪枝超过最佳解决方案成本的任何分支。我还会添加一个置换表,以避免重新搜索由先前分支使用不同的移动排列达到的状态。

我还会添加一些启发式方法,在探索其他移动之前探索更有可能达到良好结果的移动。例如,首选具有较小成本的移动。我需要进行实验,才能告诉哪些启发式方法可能最有效。

我还会尝试在原始数组中找到最长递增子序列。这将给我们一个不需要移动的数字序列,应该能够大幅减少我们需要探索的分支数。这也极大地加速了对几乎排序好的列表的搜索。
我希望这些改进能够处理比8更大的列表,但是当处理随机数很多的大型列表时,我更喜欢使用近似算法。
根据大众需求(1人),这是我用遗传算法(我最熟悉的元启发式算法)解决这个问题的方法。
首先,我会计算数字的最长递增子序列(见上文)。不属于该集合的每个项都必须被移动。现在我们只需要知道以什么顺序进行移动。
作为遗传算法输入的基因组只是一个数组,其中每个元素代表要移动的一个项。数组中出现的项的顺序表示它们需要移动的顺序。适应度函数将是原始问题中描述的成本计算。
现在我们已经拥有了将问题插入标准遗传算法所需的所有要素。其余的就是微调。大量的微调。

有时候,近似算法也是一个不错的选择。如果你认为有什么方法可以奏效,那就加上去吧 ;) - Oscar Mederos
@Oscar,我添加了一种遗传算法解决方案。我只是使用了我所知道的,所以可能还有其他收敛更快的方法适用于这个问题(请参见元启发式维基百科文章中的所有30亿种算法)。 - Ze Blob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接