Steven, sorry to contradict you, but although your code is simple and sort
of works, there a couple of problems with it.

First, the sorting function is wrong. A sorting function is supposed to
return -1,0 or 1. But it only returns -1 or 0.

The problem is you are coercing the result to int. You should use Math.round
instead.

int(Math.random() * 2) will return 1 or 0, never 2, because the biggest
value Math.random will return will be close to 1, but never will be 1. So,
if Math.random returns say, 0.9, after you multiply you get 1.8; since
you're using int(), decimals will just be discarded (instead of rounded) and
the result will be 1. There's no way you'll get 2, only 1 or 0. Then you
substract 1, so your sorting function will return either -1 or 0.

Second, you don't need to sort the whole list. It's much more work than it's
needed to shuffle the array. While the Fisher-Yates algorithm is linear, the
sort is not. That is, if you have 40 items, you know the Fisher-Yates will
"visit" each list slot only once. That's not the case with the sort method.
It grows exponentially. Well, maybe not exactly exponential, I'm not
possitive, but it's not linear anyway, as this code shows:

var list:Array = [];
var numItems:int = 40;
for(var i:int = 0; i < numItems; i++) {
list[i] = i;
}

var calls:int = 0;
function randomize(a:int, b:int):int
{
calls++;
return int(Math.random() * 2) - 1;
}

list.sort(randomize);
trace("calls:" + calls);

Change numItems and you'll see what I mean. Bottom line, you're doing more
work than you need: you're calling a function instead of doing your
comparison inline and you are calling Math.random more than it's actually
needed to sort the list.

Third, the sorting algorithm works under the assumption that given two
objects they allways sort the same: either the first one is less than, equal
or greater than the second. That doesn't hold true if your sorting function
returns a random result. And I think maybe that's why the number of calls
that the above code prints vary even when you have the same number of items.

Cheers
Juan Pablo Califano

PS. I also used the method you describe (for years) until I read about its
problems, so I thought maybe this is a good opportunity to pass this info
on. To be honest, though, I don't think it will be a problem
preformance-wise unless you have a rather big array.

2010/5/9 Steven Sacks <flash...@stevensacks.net>

> Here's a very clean, fast and simple way to randomize an array.
>
> array.sort(randomizeFunction);
>
> function randomize(a:int, b:int):int
> {
>    return int(Math.random() * 2) - 1;
> }
>
> If you're not happy with Math.random()'s randomness, there are plenty of
> other random number generators out there, such as:
>
>
> http://lab.polygonal.de/2007/04/21/a-good-pseudo-random-number-generator-prng/
>
> And Grant Skinner's Rndm:
> http://www.gskinner.com/blog/archives/2008/01/source_code_see.html
>
> _______________________________________________
> Flashcoders mailing list
> Flashcoders@chattyfig.figleaf.com
> http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
>
_______________________________________________
Flashcoders mailing list
Flashcoders@chattyfig.figleaf.com
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

Reply via email to