可以使用MapReduce进行2 ^ 32个数字的随机随机播放

时间:2011-11-14 00:41:19

标签: algorithm mapreduce

对2 32 数字进行排序的典型算法是:

  1. 创建一个包含2个 32 数字的数组,并将它们从0填充到2 32 -1
  2. 设n =数组中的项数= 2 32
  3. 从0到n-1随机选择一个数字,从数组中删除数字,然后将其推入堆栈
  4. 现在,n减1,堆栈大小增加1
  5. 转到3.直到数组为空,最后一个堆栈是解决方案
  6. 2 32 = 4,294,967,296项

    2 32 * 4 = 17,179,869,184字节,如果我们使用4字节无符号整数

    由于我在一台机器上没有那么多内存,使用memmap()可能是一个很好的选择(可能是最直接的方法)。

    出于好奇,我想知道我是否可以使用MapReduce来解决这个问题? Map和Reduce功能会是什么样的?

    这个想法在我脑海中浮现,因为虽然我在一台机器上没有那么多内存,但我在局域网上的所有盒子里肯定都有那么多内存。 MapReduce中数据的分布式特性可能有所帮助。

    虽然可以选择适合MapReduce的等效算法,但可能很难想出一个不会降低上述算法随机性的算法。

4 个答案:

答案 0 :(得分:5)

文章“MapReduce:大型集群上的简化数据处理”描述了(第3页,第3节之前)如何使用MapReduce进行分布式排序。对2 ^ 32个数字进行随机混洗的一种方法是给每个数字一个随机生成的80位密钥,然后用这个密钥对数字+密钥进行排序。使用80位密钥时,关系很少(预期数量约为2 ^ -17),您可以使用最终传递将它们按随机顺序排列。

毫无疑问,如果您准备进行大量相对较低级别的编程,有更好的方法可以做到这一点,但随机随机播放和排序都需要在机器之间进行大量严重的数据移动,而且很可能是很多工作都会被用来使分类变得聪明 - 这样你就可以重复使用它。

答案 1 :(得分:2)

如果你只需要能够从一个大的随机排列中抽样元素,你就不必通过创建和改组整个事物来实现它。查看this blog post以获取如何从分组密码生成“安全”(加密难以猜测)排列的示例。

答案 2 :(得分:1)

您的映射步骤可能是在输入的子阵列上应用Fisher-Yates算法。

然后,缩小步骤必须通过随机合并来组合混洗子阵列(在每一步中考虑剩余的部分大小)。

但是,我认为这并不比仅仅在一台机器上对磁盘进行Fisher-Yates shuffle提供任何优势,因为它所做的就是用网络速度的瓶颈取代随机磁盘访问的瓶颈。

答案 3 :(得分:0)

  

我需要一个唯一的(非重复的)32位密钥用于索引目的

为什么不在应用程序中维护一个计数器并增加它。

如果它是分布式应用程序,那么你可以ZooKeeper。有一个类似的SO thread

ZooKeeper在Java中运行,Java和C都有bindings