PS 2: I think the correct way to write the function that returns a number in the range -1 / 1 is:
Math.floor(Math.random * 3) - 1 In this case, you could indeed use int() instead of a static Math method, so I guess I was wrong about your function needing a Math.round call. 2010/5/9 Juan Pablo Califano <[email protected]> > 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 <[email protected]> > > 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 >> [email protected] >> http://chattyfig.figleaf.com/mailman/listinfo/flashcoders >> > > _______________________________________________ Flashcoders mailing list [email protected] http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

