What is the use case of RandomCover?

monarch_dodra monarchdodra at gmail.com
Tue Feb 19 03:27:55 PST 2013


On Tuesday, 19 February 2013 at 09:04:12 UTC, Ivan Kazmenko wrote:
>> Surely, because randomShuffle is re-ordering the elements 
>> in-place, whereas randomCover is not.
>
> Sorry, but that does not answer my question.  If "in-place 
> shuffle" versus "function return value" was the only intended 
> difference, randomCover could as well look like this 
> (simplified to int[] case for expressiveness):
>
> -----
> int[] randomCover(int[] r, ref/*or not*/ Random rnd)
> {
> 	auto s = r.dup;
> 	randomShuffle(s, rnd);
> 	return s;
> }
> -----
>
> However, there are ~70 lines in the implementation quite 
> different from just calling randomShuffle, presumably for some 
> purpose.  And my question is, what is that purpose?

Hum... randomShuffle and randomSample actually have nothing to do 
with each other.

RandomSample will not shuffle anything, but will just (lazily) 
iterate on the original range, skipping elements, making it a 
"random sample". It will not, in any circumstance, re-arrange any 
element.

Try this:

//--------
import std.random;
import std.algorithm;
import std.stdio;
import std.array;

void main()
{
    int[25] arr;
    foreach(i, ref a; arr) a = i;
    assert(isSorted(arr[]));
    foreach(_; 0 .. 10)
    {
       auto sample = randomSample(arr[], 4).array();
       assert(isSorted(sample));
       writefln("[%(%3s,%)]", sample);
    }
}
//--------
[  8, 12, 16, 21]
[  5, 12, 17, 23]
[  1, 15, 21, 22]
[  9, 15, 21, 23]
[  6,  7, 13, 24]
[  4,  6,  9, 11]
[  9, 12, 20, 23]
[  5, 14, 20, 23]
[  0,  2, 10, 24]
[  1,  9, 13, 23]
//--------








I also want to comment on your "randomSample" vs "randomSuffle" 
implementation suggestion. Keep in mind that:
a) randomSample doesn't allocate, whereas yours suggestion doesn't
b) randomSample gives direct access to the elements, whereas your 
suggestion doesn't.

If you don't care about a) and b), then by all means, dup away, 
and get better performance!

But think about the fact that you wouldn't be able to do 
something like this...

//--------
import std.random;
import std.algorithm;
import std.stdio;
import std.array;

void main()
{
     int[25] arr;
     foreach(_; 0 .. 10)
     {
         auto sample = randomSample(arr[], 5);
         foreach(ref a; sample)
             ++a;
     }
     writefln("[%(%3s,%)]", arr[]);
}
//--------




Last but not least, be warned there is an old-standing bug with 
anything in phobos that takes a PRNG by value. Basically, the 
PRNG will be duplicated, and generate the same sequence over and 
over. Ergo, do NOT pass a specific random generator to things 
like randomSample or randomSuffle.

This problem is one of the major reason we are currently (and 
slowly) re-designing random into random2.


More information about the Digitalmars-d-learn mailing list