对具有修改成本的数字列表进行排序

Posted

技术标签:

【中文标题】对具有修改成本的数字列表进行排序【英文标题】:Sorting a list of numbers with modified cost 【发布时间】: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 【参考方案1】:

这个问题看起来像是approximation algorithm 的一个很好的候选,但这只会给我们一个足够好的答案。由于您想要最佳答案,这就是我要改进蛮力方法的方法。

我不会盲目地尝试每个排列,而是使用backtracking 方法来维护找到的最佳解决方案并修剪任何超出我们最佳解决方案成本的分支。我还将添加一个transposition table 以避免重新搜索先前分支使用不同移动排列达到的状态。

我还会添加一些启发式方法来探索更有可能在任何其他动作之前达到良好结果的动作。例如,优先选择成本较低的动作。我需要先进行试验,然后才能判断哪种启发式方法最有效。

我也会尝试在原始数组中找到longest increasing subsequence of numbers。这将为我们提供不需要移动的数字序列,这将大大减少我们需要探索的分支数量。这也大大加快了几乎已排序的列表的搜索速度。

我希望这些改进能够处理远大于 8 的列表,但在处理大量随机数列表时,我更喜欢近似算法。


根据大众的需求(1 人),我将使用 genetic algorithm(我最熟悉的元启发式)来解决这个问题。

首先,我将从计算数字的最长递增子序列开始(见上文)。不属于该集合的每个项目都必须移动。我们现在只需要知道顺序是什么。

用作遗传算法输入的基因组只是一个数组,其中每个元素代表一个要移动的项目。项目在数组中出现的顺序表示它们必须移动的顺序。适应度函数将是原始问题中描述的成本计算。

我们现在拥有将问题插入标准遗传算法所需的所有元素。其余的只是调整。很多很多的调整。

【讨论】:

有时近似算法也是一个不错的选择。如果您认为某些东西可以在这里工作,那么添加它会很棒;) @Oscar 我添加了遗传算法解决方案。我只是使用了我所知道的东西,所以对于这个问题,可能会有其他东西收敛得更快(请参阅元启发式***文章中的所有 30 亿种算法)。

以上是关于对具有修改成本的数字列表进行排序的主要内容,如果未能解决你的问题,请参考以下文章

对具有不均匀空格的空格分隔列表进行排序

在树状通用列表中按字母数字顺序对子项进行排序的扩展方法

根据两个或多个值对通用列表进行排序

列表排序

python对目录下的文件进行 多条件排序

《问题总结》frontpagesetting企业分类排序之后,修改下拉选项值,排序列表重新回到原始状态