Re: random question
by CountZero (Bishop) on Sep 08, 2013 at 09:14 UTC
|
| [reply] [d/l] [select] |
|
Excellent points. I’ll add one more observation:
The call to time() is presumably there to add entropy (randomness). But time returns the number of seconds since the epoch; and for a run of 101 values, the script completes in less than a second, so time() returns at most two different values! This adds almost nothing to the randomness of the result.
I’m no mathematician, but I’d be surprised if the output of the algorithm being tried (when properly debugged) is any more “random” than Perl’s out-of-the-box equivalent:
print int(rand(1e4)), "\n" for 0 .. 100;
(Note that the first call to rand implicitly calls srand here.)
| [reply] [d/l] [select] |
|
| [reply] |
|
| [reply] |
|
Very well, but that is still less than half the length of the data you feed it.
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James My blog: Imperial Deltronics
| [reply] |
Re: random question
by kcott (Archbishop) on Sep 08, 2013 at 08:22 UTC
|
G'day perlaintdead,
"I posted a very simple (and apparently bad) RNG and ..."
A link to that would have been useful.
Is Random Number Generator what you're referring to?
Have you read rand and srand? Have you looked at the four CPAN modules that both of those have links to (at the end of their documentation)? Have you looked at the source code of those modules? Have you you followed up on the other advice given previously?
Change
print RandomMutation()."\n" for 0..100;
to
print RandomMutation()."\n" for 0..5;
Add print statements throughout your code to see what's causing the repetition.
| [reply] [d/l] [select] |
|
| [reply] |
|
| [reply] |
Re: random question
by Eily (Monsignor) on Sep 08, 2013 at 12:50 UTC
|
Since each of your variables depends of the result of an operation on an other, and since time doesn't do much (because the value of localtime only changes every second as expressed by Athanasius), and since you reset srand each time you call your function, I would be surprised if you didn't end with a loop very fast. Because if you get the same randseed twice, rand will give you the same numbers, and so you'll go through exactly the same list of numbers until the value of localtime changes.
That's what you get for calling srand with the ouput of rand:
eval { $n = int rand(20); srand $n; print $n.' ' } for (1..10)
13 9 0 3 15 4 13 9 0 3
You just put additional layers to that problem, and a restart every second.
As for your toASCII sub, have a look at pack, unpack, and the perlpacktut.
My advice: if you want to make your own RNG: do go on. But do it from scratch, do not use rand, because that's actually what does all the work in your programs, and it prevents you to see the flaws in what you do. If you try and make your own RNG, and use it for a large scale number generation, you'll learn far more than trying to improve something that's possibly better than whatever you may achieve. | [reply] [d/l] [select] |
Re: random question
by Anonymous Monk on Sep 08, 2013 at 14:46 UTC
|
I'm finding a random-number generator that relies on the built-in rand() and srand() quite odd. As the others have told you, you should not call srand() more than once in the program, and it's probably better to not call it at all! (Perl has done that for you already.)
Anyway, here's a simple one that returns numbers in the range 0..65535:
use Digest::SHA 'sha384_hex';
my $rng = generate_rng('salty' . localtime() . $$);
print $rng->(), "\n" for 0..100;
sub generate_rng {
my $seed = shift;
return sub {
$seed = sha384_hex($seed);
my $rnd = hex(substr($seed, 0, 4));
return $rnd;
};
}
For further study, you might want to look at OpenBSD's rand() which is about as simple as it gets. (It's also a poor one; its use is discouraged.) | [reply] [d/l] [select] |
|
I think there's a minuscule probability that this RNG leaves (at least) one number never to generate, shortening its ideal cycle. Potential fix:
sub generate_rng {
my $seed = shift;
my $count = 0;
return sub {
$seed = sha384_hex($seed . $count++);
my $rnd = hex(substr($seed, 0, 4));
return $rnd;
};
}
Take my methods with a grain of salt since I'm an amateur at best in this subject -- I wouldn't know a bad RNG from a good one.
Anyway, it appears that the OP is trying to increase the randomness of rand() by various voodoo methods. This is a futile task and he's much more likely to worsen it by making it more biassed. For example, a lot of newbies try to out-random random by saying rand() + rand() and getting a triangular distribution as a result. | [reply] [d/l] [select] |
Re: random question
by 5mi11er (Deacon) on Sep 08, 2013 at 21:11 UTC
|
| [reply] |
Re: random question
by perlaintdead (Scribe) on Sep 08, 2013 at 08:48 UTC
|
| [reply] |
|
What do you mean by "if i don't force scalar context"? You are not "forcing" scalar context anywhere in your script?
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James My blog: Imperial Deltronics
| [reply] |
Re: random question
by Preceptor (Deacon) on Sep 09, 2013 at 16:01 UTC
|
| [reply] |
|
| [reply] |
|
sub mostRandom{
return 4;
}
| [reply] [d/l] |
|
| [reply] |