TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Good Knuth, Bad Knuth

26 点作者 vinutheraj超过 15 年前

9 条评论

fhars超过 15 年前
As far as I can tell, the "correct" shuffle in that post is wrong, int(rand() * $i) is always smaller than $i, so it will never generate a permutation where an element stays at the same position.<p>It is obvious from the numbers, too: the loop goes from $length - 1 to 1, so it has $length - 1 iterations, in the first iteration there are $length - 1 possible values for $r, in the second $length - 2, and the last iteration will always swap elements 0 and 1, for a total of (N-1)! different paths through the program, which are clearly not sufficient to generate N! different permutations.<p>[Edit: I had an off-by-one in my calculations, too. I hope it is correct now.]<p>[Edit: Actually, there still is an error in the first sentence: the algoritm will never leave the current element in its place, so the only element that is guaranteed not to stay at the same position is the last one. Run this:<p><pre><code> for my $i (1..1000000) { my @a = (1..10); my @b = shuffle(@a); if ($b[10] == 10) { die "Criticism is wrong $i"; } } ]</code></pre>
评论 #929150 未加载
astine超过 15 年前
I can honestly say that that isn't the algorithm that would have occured to me. In CL, this is the what I would have thought to do:<p><pre><code> (defun butnth (index list) (append (subseq list 0 index) (subseq list (1+ index)))) (defun shuffle (list) (unless (null list) (let ((index (random (list-length list)))) (cons (nth index list) (shuffle (butnth index list)))))) </code></pre> Building a second sequence by randomly selecting nodes from the old sequnece and inserting them into the new sequence seems more intuitive to me. It certainly works better with lists. If I where working with arays, the OPs method would be more efficient.
评论 #928061 未加载
评论 #928051 未加载
评论 #928005 未加载
rimantas超过 15 年前
Some nice graphs: <a href="http://www.codinghorror.com/blog/archives/001015.html" rel="nofollow">http://www.codinghorror.com/blog/archives/001015.html</a>
jrockway超过 15 年前
The best way to get this right in Perl:<p><pre><code> use List::Util qw(shuffle); shuffle(@list);</code></pre>
评论 #928174 未加载
songism超过 15 年前
This is how python's shuffle works:<p><pre><code> def shuffle(x): for i in reversed(xrange(1, len(x))): j = int(random() * (i+1)) x[i], x[j] = x[j], x[i] </code></pre> In the first loop the last element in the list 'x' has a chance to be exchanged with itself or any of the other elements. Then the second to last element has a chance to be exchanged with itself or any other element.<p>All the way down to the second to last element, which has the chance to be exchanged with itself or the first element.<p>This is exactly how the good Knuth shuffle algorithm works, right?
allenbrunson超过 15 年前
I just happen to have implemented something like this myself recently, which seems easier to me. here it is: generate a large random number for each card, then sort the list according to the random numbers. Can anybody here poke holes in that one?
评论 #928134 未加载
评论 #928266 未加载
评论 #928132 未加载
thisrod超过 15 年前
I'm surprised that the median job candidate gets that wrong. It isn't an especially hard question, and I would have assumed professional programers had a pretty good instinct for combinatorics.
rflrob超过 15 年前
So presumably if the naive interpretation is wrong, then the bias should be predictable. Any ideas how to go about determining which permutations are more likely than they ought to be?
Tichy超过 15 年前
It annoyed me when I heard that some guys slapped their name on that algorithm (having "invented" it independently for a game). It seems like another of those not patent worthy obvious things. Why is it obvious: because you should realise that there is a random number generator in your programming language. Therefore shuffling is silly. You want to assign the cards to slots determined by the random number generator directly. From there on it is pretty straightforward. &#60;/brag&#62;
评论 #928626 未加载
评论 #928496 未加载