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.

Reply via email to