For those who don't know what randomize does: it takes a list and gives it back to you with the elements randomly rearranged. Another way of saying it is that it gives you a random permutation of the list you provide. Now, in the manual, it doesn't say that the permutation you get is as equally likely as any other you would get. So technically, randomize is working as advertised, but I think that Lutz and the user base would agree that it would be best to get an equally likely random permutation from randomize.
Here is the culprit code, from nl-math.c, lines 1104-1110, in function p_randomize():
Code: Select all
for(i = 0; i < (length - 1); i++)
{
j = random() % length;
cell = vector[i];
vector[i] = vector[j];
vector[j] = cell;
}
In newLISP, this would be:
Code: Select all
;; From Algorithm P of Knuth in TAOCP: Seminumerical Algorithms.
(define (randomize* lst)
(let ((N-1 (- (length lst) 1)))
(for (i 0 (- N-1 1))
(swap i (unif i N-1) lst))
lst))
;; Uniformly draw an integer in the range {a,...,b}.
(define (unif a b) (+ a (rand (+ 1 (- b a)))))