寻找具有尽可能少的比较操作的排序算法

时间:2009-05-15 06:19:25

标签: algorithm sorting

我想对人类进行比较的项目进行排序:

  • 图片
  • 工作项目的优先顺序
  • ...

对于这些任务,比较次数是性能的限制因素。

  • 所需的最低比较次数(我假设> N N 项目?)
  • 哪种算法可以保证这个最小数量?

11 个答案:

答案 0 :(得分:5)

Pigeon hole sorting是N阶,并且如果数据可以被窃取,则可以很好地与人类一起使用。一个很好的例子就是在选举中计票。

答案 1 :(得分:5)

要回答这个问题,我们需要做出很多假设。

让我们假设我们正在通过可爱来分类图片。目标是在最短的时间内从人类获得最大可用信息。这种互动将主导所有其他计算,因此它是唯一重要的计算。

正如其他人提到的,人类可以很好地处理在一次互动中订购几件物品。假设我们每轮可以获得相对顺序的八个项目。

每轮将七条边引入有向图中,其中节点是图片。如果节点A可以从节点B到达,那么节点A比节点B更可靠。记住这个图。

现在,让我告诉你一个海军和空军解决问题的方法。他们都希望快速获得一群人的身高。海军告诉人们排队,然后如果你比你面前的人短,切换位置,重复直到完成。在最坏的情况下,它是N * N比较。

空军告诉人们站在正方形的格子里。他们在sqrt(N)人身上一对一地进行洗牌,这意味着最坏的情况是sqrt(N)* sqrt(N)== N比较。然而,人们只是沿着一个维度排序。因此,人们面朝左,然后再次做同样的洗牌。现在我们进行了2 * N比较,但这种情况仍然不完善,但对政府工作来说已经足够了。有一个短角,对面有一个高大的角落,有一个清晰的对角线高度梯度。

如果你不关心完美,你可以看到空军方法如何在更短的时间内获得结果。您还可以看到如何有效地获得完美。你已经知道,最短和最长的男人都在两个角落里。第二短的可能在最短的后面或旁边,第三短的可能在他后面或旁边。一般来说,某个人的身高等级也是他从短角落到曼哈顿的最大距离。

回顾图形类比,每轮呈现的八个节点是目前最常见的最长入站路径长度的八个节点。最长入站路径的长度也表示节点的最小可能排序等级。

您将按照此计划使用大量CPU,但您将尽可能充分利用人力资源。

答案 2 :(得分:4)

从我曾经在这个主题上做过的任务......

比较计数用于以随机顺序对数据进行操作的各种排序算法

Size      QkSort    HpSort   MrgSort     ModQk   InsrtSort
  2500     31388     48792     25105     27646     1554230
  5000     67818    107632     55216     65706     6082243
 10000    153838    235641    120394    141623    25430257
 20000    320535    510824    260995    300319   100361684
 40000    759202   1101835    561676    685937
 80000   1561245   2363171   1203335   1438017
160000   3295500   5045861   2567554   3047186

这些比较计数适用于对“近乎排序”的数据进行操作的各种排序算法。除此之外,它还显示了快速排序的病态情况。

Size      QkSort    HpSort   MrgSort     ModQk   InsrtSort
  2500     72029     46428     16001     70618      76050
  5000    181370    102934     34503    190391    3016042
 10000    383228    226223     74006    303128   12793735
 20000    940771    491648    158015    744557   50456526
 40000   2208720   1065689    336031   1634659  
 80000   4669465   2289350    712062   3820384
160000  11748287   4878598   1504127  10173850

从中可以看出,合并排序是最佳的比较次数。

我不记得快速排序算法的修改是什么,但我相信一旦各个块达到一定大小就会使用插入排序。通常这样做是为了优化快速排序。

您可能还想查找Tadao Takaoka的'Minimal Merge Sort',这是合并排序的更高效版本。

答案 3 :(得分:3)

你应该考虑人类可能进行非传递性比较,例如:他们喜欢A over B,B over C而C也超过A.因此,在选择排序算法时,请确保在发生这种情况时不会完全破坏。

答案 4 :(得分:3)

人们非常擅长从最佳到最差订购5-10件事,并且在这样做时能得出更一致的结果。我认为尝试应用经典的排序算法可能在这里不起作用,因为通常采用人类多重比较的方法。

我认为你应该采用循环式方法,并尝试每次都将其分解为最一致的组。每次迭代只会使结果更加确定。

写作也很有趣:)

答案 5 :(得分:2)

如果比较相对于簿记成本而言比较昂贵,您可以尝试以下我称之为“锦标赛排序”的算法。首先,一些定义:

  1. 每个节点都有一个数字“得分”属性(必须能够保存从1到节点数的值),以及一个“最后节拍”和“伙伴 - 失败者”属性,它们必须是能够保存节点引用。
  2. 如果节点应该在另一个节点之前输出,则该节点比另一个节点“更好”。
  3. 如果没有已知的元素比已经输出的元素更好,则元素被认为是“合格的”,如果已知任何未输出的元素比它更好,则“不合格”。
  4. 节点的“得分”是已知优于1的节点数。

要运行算法,最初为每个节点分配1分。重复比较两个得分最低的合格节点;在每次比较之后,将失败者标记为“不合格”,并将失败者的得分添加到获胜者的位置(失败者的得分不变)。将失败者的“失败者”属性设置为获胜者的“最后击败”,并将失败者的“最后击败”属性设置为失败者。迭代这个直到只剩下一个符合条件的节点。输出该节点,并使符合条件的所有节点成为赢家击败(使用获胜者的“最后节拍”和“同伴输家”属性链)。然后在剩余的节点上继续算法。

与1,000,000项目的比较数量略低于Quicksort的库存库实施;我不确定该算法如何与更现代版本的QuickSort进行比较。簿记成本很高,但如果比较足够昂贵,节省的费用可能是值得的。该算法的一个有趣特征是它只执行与确定要输出的下一个节点相关的比较;我知道没有其他算法可以使用该功能。

答案 6 :(得分:1)

我认为你不可能得到比Wikipedia page on sorting更好的答案。

要点:

  • 对于任意比较(你不能使用像基数排序这样的东西),你能达到的最好的是O(n log n)
  • 各种算法实现了这一点 - 请参阅“算法比较”部分。
  • 在典型情况下,常用的QuickSort是O(n log n),但在最坏的情况下是O(n ^ 2);通常有办法避免这种情况,但如果你真的担心比较的代价,我会选择像MergeSort或HeapSort这样的东西。它部分取决于您现有的数据结构。

如果人类正在进行比较,他们是否也在进行排序?您是否有需要使用的固定数据结构,或者是否可以使用平衡二叉树插入排序有效地创建副本?存储要求是什么?

答案 7 :(得分:1)

Here是算法的比较。两个更好的候选者是快速排序和合并排序。快速排序通常更好,但最坏情况下表现更差。

答案 8 :(得分:1)

合并排序肯定是这里的方法,因为您可以使用Map / Reduce类型算法让几个人并行进行比较。

Quicksort本质上是一种单线程排序算法。

您还可以调整合并排序算法,这样您就不会比较两个对象,而是向人类展示五个项目的列表,并让他或她对它们进行排名。

另一种可能性是使用着名的“热门或非热门”网站使用的排名系统。这需要更多的比较,但是,比较可以按任何顺序和并行进行,如果您有足够的类人猿可供使用,这将比经典排序更快。

答案 9 :(得分:1)

这些问题确实引发了更多问题。

我们是在谈论进行比较的单个人吗?如果你正在谈论一群试图按顺序排列物体的人,那将是一个非常不同的挑战。

信任和错误的问题怎么样?不是每个人都可以信任或者把事情弄清楚 - 如果在任何一个点上你为一次比较提供了错误的答案,某些种类就会出现灾难性的错误。

主观性怎么样? “按照可爱的顺序排列这些图片”。一旦你达到这一点,它可能变得非常复杂。正如其他人提到的那样,“热或不热”之类的东西在概念上是最简单的,但效率不高。在最复杂的情​​况下,我会说谷歌是一种将对象分类为订单的方式,搜索引擎推断人类进行的比较。

答案 10 :(得分:0)

最好的一个是合并排序

最短运行时间为n * log(n)[Base 2] 它的实施方式是

如果列表的长度为0或1,则它已经排序。

否则:

将未排序的列表分成两个大小约为一半的子列表。

通过重新应用合并排序来递归地对每个子列表进行排序。

将两个子列表合并回一个排序列表。