From 08403bac9f9d4f56f4f9047be572de7958383519 Mon Sep 17 00:00:00 2001 From: octachron Date: Wed, 11 Nov 2015 23:36:55 +0200 Subject: [PATCH] CCRandom: Add sample_without_replacement --- src/core/CCRandom.ml | 14 ++++++++++++++ src/core/CCRandom.mli | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/src/core/CCRandom.ml b/src/core/CCRandom.ml index cc387065..cf53c8eb 100644 --- a/src/core/CCRandom.ml +++ b/src/core/CCRandom.ml @@ -78,6 +78,20 @@ let replicate n g st = if n = 0 then acc else aux (g st :: acc) (n-1) in aux [] n +(* Sample without replacement using rejection sampling. *) +let sample_without_replacement (type elt) ?(compare=compare) k (rng:elt t) st= + let module S = Set.Make(struct type t=elt let compare = compare end) in + let rec aux s k = + if k <= 0 then + S.elements s + else + let x = rng st in + if S.mem x s then + aux s k + else + aux (S.add x s) (k-1) in + aux S.empty k + let list_seq l st = List.map (fun f -> f st) l exception SplitFail diff --git a/src/core/CCRandom.mli b/src/core/CCRandom.mli index e42e1f01..2c1ebcc7 100644 --- a/src/core/CCRandom.mli +++ b/src/core/CCRandom.mli @@ -76,6 +76,14 @@ val replicate : int -> 'a t -> 'a list t (** [replicate n g] makes a list of [n] elements which are all generated randomly using [g] *) +val sample_without_replacement: + ?compare:('a -> 'a -> int) -> int -> 'a t -> 'a list t +(** [sample_without_replacement n g] makes a list of [n] elements which are all + generated randomly using [g] with the added constraint that none of the generated + random values are equal + @since 0.15 + *) + val list_seq : 'a t list -> 'a list t (** Build random lists from lists of random generators @since 0.4 *)