【问题标题】:fastest integer sort implementation for 200-300 bit integers?200-300位整数的最快整数排序实现?
【发布时间】:2011-10-19 14:20:25
【问题描述】:

对于 200-300 位大小的整数,最快的整数排序实现是什么?确切的 int 大小是固定的;我有多达 2 GB 的此类整数(全部在 RAM 中)。

我听说可以在 O(n log log M) 甚至 O(n sqrt(log log M)) 时间对这样的集合进行平均排序,其中 n 是整数个数,M 是最大整数.内存使用是有限的(我可能会额外使用 0.5-1 GB)。分拣可以就地进行; in 可能不稳定(重新排序重复)。

是否有这种排序方法的 C/C++ 实现,例如Han & Thorup (2002)?

【问题讨论】:

  • 整数是随机的吗?有没有可能有帮助的内部模式?这是两个问题:高效的大整数比较和快速排序功能。快速排序算法有很多评价……你需要找到一个快速的比较。
  • 它们不是随机的,而是相当大的。我想测试更快的基于签名的方法或基于 van Emde Boas 树的方法,例如“Han&Thorup 2002”。我有,但我想得到完整的实施。
  • 一个 300 位大小的整数? Let me googol it for you
  • 也许您还应该担心您的排序算法会占用多少内存。有些算法在原地运行良好,有些则不行。
  • 我打赌 MSD 递归基数排序从内存使用和缓存位置(我认为对于数据量非常重要)的角度来看是最有效的。 en.wikipedia.org/wiki/…

标签: c++ c sorting integer


【解决方案1】:

Radix Sort 可用于使用固定大小的键对数据进行排序。由于这种情况并不经常满足,因此对该技术的讨论不多,但当排除密钥大小时,它可能是 O(n)。

【讨论】:

  • O(n m) 其中m 是最大整数的大小(即位数)。
  • 在我正确阅读问题之前,这也是我的答案。 OP 已经提到了具有渐近运行时间的方法,对于 m-位值)。出于实际原因,基数排序可能仍然会获胜,但您没有提到任何这些。
  • @John,OP 提到了一种无法被公众评估的单一算法,因为它位于付费墙后面。一点谷歌搜索在维基百科上找到了这个宝石,但仍然没有详细的算法描述:en.wikipedia.org/wiki/Integer_sorting 就复杂性而言,它们都是 O(n),具有基于密钥长度的不同常数乘数。实际花费的时间取决于代码的复杂性和理论上的密钥切片。
  • @Mark:完全同意实际运行时间将在很大程度上取决于实施因素,事实上我认为这很重要,可以包含在您的答案中。然而,仅仅告诉已经知道排序可以在 O(n) 时间内完成的人,基数排序可以在 O(n) 时间内完成排序并没有增加太多。这是基于这样的假设(可能不正确),即在进行了足够多的调查以找到 Han 和 Thorup 之后,OP 也会遇到(相对众所周知的)基数排序。
  • @Mark:至于付费墙,我必须承认我没有想到,因为我很幸运能够通过我的大学进入。但是,在这种情况下,也可以从 Yijie Han's website 获得该论文。
【解决方案2】:

如果内存使用确实受到限制。我会将每个字节分开并将它们从最高有效字节到最低有效字节存储到一个 trie 数据结构中。如果您按排序顺序插入字节,则可以迭代 trie 并对所有数据进行排序。

【讨论】:

  • 什么是时间 O() 复杂度?需要多少内存
  • 这取决于您的密钥有多相似以及您对每个字节使用的排序算法。维基百科的文章将能够比我更好地解释它的优势..en.wikipedia.org/wiki/Trie
【解决方案3】:

签名排序适用于大字长,预期时间复杂度为 'O (n lg lg n)',但对于小字长,您可以使用 von Emde Boas 排序获得相同的复杂度。最近,Han 和 Thorup 发布了更快的排序算法,其预期时间复杂度为“O (n sqrt(lg lg n))”。我不确定你是否可以在网上找到这些算法的实现,但可能有一些关于 MIT 和Harvard 的精彩文章和讲座。

【讨论】:

    【解决方案4】:

    我认为最合理的做法是创建一个指向 bigint 的指针数组,并对指针数组进行排序。我会建议某种模板化快速排序,具有智能比较功能。

    比较函数大部分时间应该能够通过查看最重要的 4 个字节来决定。如果它们不匹配,则决定比较。如果它们确实匹配,那么您将查看接下来的 4 个字节,直到 int 结束。

    我猜测数据范围可能足够大,因此基数排序是不切实际的。如果您的数据是随机的,快速排序通常会足够快,并且其缓存性能优于大多数非基数排序。

    【讨论】:

    • 如果你对指针进行排序,我认为你很可能会遇到一些严重的缓存局部性问题,因为你仍然需要随机访问 2Gb 来执行比较。
    • 但是当您进行非本地交换时(您希望这样做,以尽量减少交换次数),在所有情况下您都会遇到 2 GB 的缓存局部性问题。但是使用间接点,您至少可以避免交换时的大量复制。
    • @g&f.是的,但是....您将遇到每件事的缓存问题。 QuickSort 最终到达缓存有效的地步。许多其他种类没有。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多