Perl 什么';这个洗牌算法的效率和质量如何?

Perl 什么';这个洗牌算法的效率和质量如何?,perl,sorting,random,performance,Perl,Sorting,Random,Performance,最近关于的这个问题让我想到了我有时在Perl中洗牌数组的方式 @shuffled = sort { rand() <=> rand() } @array; @shuffled=sort{rand()rand()}@array; 在上述问题中提出的解决方案是,它在线性时间内工作 问题是:我的代码片段的效率有多高?这种无序排列“真的”随机吗?这只是直觉,但我认为使用这样的排序将生成一个集合,其顺序在某种程度上取决于原始集合的顺序。真正随机排序的结果不应该完全依赖于原始集合的顺序。我无

最近关于的这个问题让我想到了我有时在Perl中洗牌数组的方式

@shuffled = sort { rand() <=> rand() } @array;
@shuffled=sort{rand()rand()}@array;
在上述问题中提出的解决方案是,它在线性时间内工作


问题是:我的代码片段的效率有多高?这种无序排列“真的”随机吗?

这只是直觉,但我认为使用这样的排序将生成一个集合,其顺序在某种程度上取决于原始集合的顺序。真正随机排序的结果不应该完全依赖于原始集合的顺序。我无法解释为什么/如何,也许其他人可以(或表明它实际上是随机的)


至于它的效率有多高,我不确定,但它的效率可能不会比使用
sort
的任何其他排序低很多,因为AFAIK
rand()
相对便宜。不过,我可能错了。

我不是Perl内部专家,所以我不知道“排序”在这里如何工作。然而,大多数排序函数都希望在比较中保持一致性,如果函数本身是随机的,我希望它们能够不可预测地工作。不幸的是,不可预测性与随机性不同,因此我对你的随机数组没有信心。它可能倾向于将元素按某种顺序排列,就像匆忙创建的复杂递归关系可能不是随机的一样

与其分析排序函数,我建议使用Fisher-Yates


正如Knuth所说,随机性太重要了,不能听天由命。

事实上,我有点惊讶于你提出的随机洗牌能奏效。在Perl
sort
函数的实现中,它尝试根据比较函数的值将数组元素按升序排列。问题是,您的比较函数不会返回一致的答案!有时它可能会说
“foo”lt“bar”
,而有时它可能会说
“bar”lt“foo”
。这可能会混淆排序算法,使其永远不会终止,或以致命错误或其他灾难性故障终止。

sort上的perl文档说明了这一点

需要比较函数才能正常工作。如果它返回不一致的结果(例如,有时说$x[1]小于$x[2],有时说相反),则结果定义不明确

所以这样做是个坏主意


埃塔:我刚刚做了一个基准测试。在100000个元素的数组上,使用FY shuffle的速度也快10倍以上。

有一个更好的Fisher-Yates shuffle函数,它不使用中内置的
排序功能。

首先,您知道,无论使用sort()的比较器,都不可能比O(n log n)快。因此,即使它执行的洗牌是公平的,它的性能也会更差

那么洗牌公平吗?对于某些(易于分析的)排序算法来说,这显然是不公平的。考虑一个简单的冒泡排序-为了使一个元素从一端移动到另一端,比较函数必须评估n个连续调用的正- 1的2 ^ N概率,对于n中的1个事件应该是什么。对于快速排序,很难进行分析,最终可能是公平的。但如果它是正确的很重要,那就用正确的方式去做

$ perldoc List::Util
⋮
  shuffle LIST
       Returns the elements of LIST in a random order

           @cards = shuffle 0..51      # 0..51 in a random order
⋮
这是我的建议。



@shuffled = map {
  $_->[1]
} sort {
  $a->[0] <=> $b->[0]
} map {
  [ rand(), $_ ]
} @array;
@洗牌=地图{ $_->[1] }分类{ $a->[0]$b->[0] }地图{ [rand(),$\] }@数组;
我收集的信息和你一样多,但也只是直觉而已。我希望有人,至少假装知道:)@Tim:我不认为rand()是一个洗牌,它不是一个正确的算法。其结果是不可预测的,但不是随机的。除此之外,你是在重复我说过的话。如果你使用的是真正的随机排序(洗牌),那么初始排序是不相关的;它严重拉伸排序,并且洗牌数组的方法不正确。我从来没有在关键点使用过它(洗牌很少是关键的),但是作为测试的一种快速技巧。但在某种程度上,它仍然很优雅;)brian put的新标题改变了讨论的性质和目的,使之倒退。brian更改了标题,因为这是一个关于Perl邮件列表的常见问题解答和关于IRC的#Perl,经常被问到,perlfaq4包含了答案。感谢您指出Perl的精彩文档。我可以补充一点,命令行中的perldoc-qshuffle是查找相同信息的另一种方法。