【问题标题】:Algorithm to generate random order of elements生成元素随机顺序的算法
【发布时间】:2009-11-07 01:43:19
【问题描述】:

如何以最低复杂度随机化大约 20 个元素的顺序? (生成随机排列)

【问题讨论】:

标签: algorithm random


【解决方案1】:

Knuth's shuffle algorithm 是个不错的选择。

【讨论】:

  • 嗯,我很失望这就是答案。由于您必须首先遍历列表以填充它,然后对其进行随机播放(使用公认的好算法),我会认为有更好的解决方案。
【解决方案2】:

几个月前,我写了一篇关于获取整数列表的随机排列的博客。 您可以将其用作包含您的元素的集合的索引的排列,然后您就拥有了您想要的东西。

在第一篇文章中,我探索了一些可能性,最后我获得了“一个随机排列具有 O(n) 复杂度的通用列表的函数”,正确封装以处理不可变数据(即,它没有副作用) .

在第二篇文章中,我将其均匀分布。

代码是F#的,希望你不要介意!

祝你好运。

编辑:我没有正式的证明,但直觉告诉我这种算法的复杂度不能低于 O(n)。我真的很高兴看到它做得更快!

【讨论】:

  • 所有排列都必须是可能的,并且将数组重新排列成一个混乱(即排列p,对于所有p(k) != k,对于所有k)需要访问每个元素。因此 O(n) 最坏情况。还是不够正式?
  • 同样的证明也是 O(n) 平均情况,想想看,因为 IIRC 的 (1...n) 的排列比例随着 n 接近而接近 1/e无穷大。
【解决方案3】:

随机化顺序的一种简单方法是创建一个大小正确的新列表(在您的情况下为 20),遍历第一个列表,并将随机位置的每个元素添加到第二个列表中。如果随机位置已经被填满,则放到下一个空闲位置。

我认为这个伪代码是正确的:

list newList
foreach (element in firstList)
    int position = Random.Int(0, firstList.Length - 1)
    while (newList[position] != null)
        position = (position + 1) % firstList.Length
    newList[position] = element

编辑:所以事实证明这个答案实际上并不是那么好。它既不是特别快,也不是特别随机。谢谢你的cmets。要获得好的答案,请滚动回页面顶部:-)

【讨论】:

  • 在最坏的情况下,该算法为 O(n^2)(即,如果您的随机数生成器显示“1, 1, 1, 1, 1, 1, 1, ...”,我让你计算剩下的),不是很优化。
  • 将项目放在下一个空闲位置会减少随机性。与真正随机洗牌相比,这些物品将保持其原始顺序。要解决这个问题,您必须在采取位置时选择一个新的随机位置,这当然会使其速度变慢。
  • 这是一个很好的观点 Guffa。我从来没有意识到这一点。谢谢。至少我在这里学到了一些东西:-)
【解决方案4】:

可能有人已经为您实现了改组。例如,在 Python 中可以使用 random.shuffle,在 C++ 中使用 random_shuffle,在 PHP 中使用 shuffle

【讨论】:

  • 令人惊讶的是,在 PHP 中它被称为 shuffle :) 我会更新我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
  • 1970-01-01
  • 2010-09-24
  • 2017-08-16
  • 2015-01-05
  • 2012-01-05
相关资源
最近更新 更多