Add shuffle_buffer.

This commit is contained in:
Drup 2016-01-16 16:30:22 +01:00
parent be57b29f84
commit 964b5c61bd
3 changed files with 44 additions and 0 deletions

View file

@ -698,6 +698,34 @@ let random_array a k =
let random_list l = random_array (Array.of_list l) let random_list l = random_array (Array.of_list l)
(* See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle *)
let shuffle_array a =
for k = Array.length a - 1 downto 0+1 do
let l = Random.int (k+1) in
let tmp = a.(l) in
a.(l) <- a.(k);
a.(k) <- tmp;
done
let shuffle_buffer n seq k =
let seq_front = take n seq in
let a = to_array seq_front in
let l = Array.length a in
if l < n then begin
shuffle_array a ;
of_array a k
end
else begin
let seq = drop n seq in
let f x =
let i = Random.int n in
let y = a.(i) in
a.(i) <- x ;
k y
in
seq f
end
(** {2 Sampling} *) (** {2 Sampling} *)
(** See https://en.wikipedia.org/wiki/Reservoir_sampling#Algorithm_R *) (** See https://en.wikipedia.org/wiki/Reservoir_sampling#Algorithm_R *)

View file

@ -498,6 +498,14 @@ val random_list : 'a list -> 'a t
(** Infinite sequence of random elements of the list. Basically the (** Infinite sequence of random elements of the list. Basically the
same as {!random_array}. *) same as {!random_array}. *)
val shuffle_buffer : int -> 'a t -> 'a t
(** [shuffle_buffer n seq] returns a sequence of element of [seq] in random
order. The shuffling is *not* uniform. Uses O(n) memory.
The first [n] elements of the sequence are consumed immediately. The
rest is consumed lazily.
@since NEXT_RELEASE *)
(** {2 Sampling} *) (** {2 Sampling} *)
val sample : int -> 'a t -> 'a array val sample : int -> 'a t -> 'a array

View file

@ -446,6 +446,14 @@ val random_list : 'a list -> 'a t
(** Infinite sequence of random elements of the list. Basically the (** Infinite sequence of random elements of the list. Basically the
same as {!random_array}. *) same as {!random_array}. *)
val shuffle_buffer : n:int -> 'a t -> 'a t
(** [shuffle_buffer n seq] returns a sequence of element of [seq] in random
order. The shuffling is not uniform. Uses O(n) memory.
The first [n] elements of the sequence are consumed immediately. The
rest is consumed lazily.
@since NEXT_RELEASE *)
(** {2 Sampling} *) (** {2 Sampling} *)
val sample : n:int -> 'a t -> 'a array val sample : n:int -> 'a t -> 'a array