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