+4  A: 

I'll be surprised if anyone improves on the Knuth shuffle. It's O(n).

It takes O(n) random numbers, which is not sufficient for me.

This citation claims an O(n log n) algorithm.

We'd all love to see see O(log n) or O(1).

O(log n) algorithms usually depend on "divide and conquer" bisection, which brings to mind cutting the deck and dividing each half.

But I can't help but think that if a faster algorithm were accessible Knuth would have found it.

duffymo
thanks for that interessting link... this would also explain why i couldnt manage to find any faster solution! :-P
Gnark
A: 

The only possible optimization I can think of is making the random number generator faster. An easy solution is to generate random ints in the first place:

import java.util.Random;
Random rand = new Random();

for (int i = 0; i < a.length ; i++) {
    swap(rand.nextInt(i+1), i, a);
}

...

Alternatively, you can invent a faster way to generate more or less random numbers (uniformly distributed or not, suited to your needs). However, there's no way you can overcome the O(n) limitation.

Eemeli Kantola
+1  A: 

A sequence of length n has n! permutations. If each permuation needs to be possible, there must be a possible sequence of random numbers for each one.

To randomly permute an array of length n, you can therefore generate a single random number from the range 1..n! uniformly at random. This identifies a single permutation, which you can then apply.

You might improve your question to ask how many random bits are needed. By the same argument, that will be log(n!). To give you an idea about the asymptotic behaviour of that function, consider:

Let n > 3:

n = log(2^n) < log(n!) < log(n^n) = n * log(n)

So n random bits can not be enough (for n > 3). In fact, one can prove that log(n!) is not in O(n).

meriton
But if you read the Knuth citation, you'll see that it is indeed O(n).
duffymo
No. That algorithm states that you can find a random permutation with O(n) random real numbers from the range [0,1], where the number are represented with sufficient accuracy to select among n different array indices. This can not be accomplished with a fixed-bit random numbers. It is easy to see that at least the first random number will require log n bits, leading to a bit-complexity of O(n log n).
meriton