Question Regarding Random Number Generation in Lua - random

I was playing around with the lua interpretor and made this little program that generates two numbers and compares them. The program runs until the numbers match. The first number is randomly generated using math.random(), and is set to 1, and 100000. The second value that is generated to compare is between 1 and 100. It also keeps track of how many times the program loops. The program works as intended, but something strange happens when I run it.
The values that come up are always either 1, 31, 62, or 92. I've run the program many times, but it keeps generating these numbers. I have some understanding of how random numbers are generated, but this just seems weird. I'll paste the code in below. If someone can explain what's going on here, I would appreciate it greatly. Thanks!
counter=0;
a=0;
b=1;
while(a~=b)do
a=math.random(1,1000000);
b=math.random(1,100);
counter=counter+1;
if(a==b)then
print(a..", "..b..", and it took "..counter.." times")
end
end

The behaviour of the pseudo-random number generator changed in Lua 5.4. The 5.4 Reference Manual states, under §8.2 – Incompatibilities in the Libraries, that
The pseudo-random number generator used by the function math.random now starts with a somewhat random seed. Moreover, it uses a different algorithm.
If you are curious, that new algorithm is xoshiro256**.
What this means is that programs running in Lua environments prior to 5.4 must explicitly call math.randomseed to seed the pRNG. You want to do this only once in your program.
Without seeding the pRNG, the sequence of numbers produced will be the same each time you run your program. This is because, prior to 5.4, Lua's math.random is implemented using C rand or POSIX random, both of which default to a seed of 1 if not explicitly seeded.
The classic way to seed a pRNG is to use the current time (os.time). This is a simple approach, but has the fault that running this program twice in the same second will have the same result.
local counter = 0
local a = 0
local b = 1
math.randomseed(os.time())
while a ~= b do
a = math.random(1, 1000000)
b = math.random(1, 100)
counter = counter + 1
if a == b then
print(a .. ", " .. b .. ", and it took " .. counter .. " times")
end
end
Documentation links, for comparison:
5.3: math.random math.randomseed
5.4: math.random math.randomseed

Related

Shouldn't the same srand value produce the same random numbers?

When I repeatedly run this code,
srand 1;
my #x = (1..1000).pick: 100;
say sum #x;
I get different answers each time. If I'm resetting with srand why shouldn't it produce the same random numbers each time?
The error occurs in the REPL.
The error occurs in this file:
use v6.d;
srand 1;
my $x = rand;
say $x; # OUTPUT: 0.5511548437617427
srand 1;
$x = rand;
say $x; # OUTPUT: 0.308302962221659
say $*KERNEL; # OUTPUT: darwin
I'm using:
Welcome to Rakudo™ v2022.07.
Implementing the Raku® Programming Language v6.d.
Built on MoarVM version 2022.07.
It should produce the same numbers for a given piece of code all of the time. And I haven't been able to reproduce your observation in any way.
There may be something spooky going on under the hood, though:
$ raku -e 'srand 1; (my $x = (1..1000).pick(1)).say'
(761)
$ raku -e 'srand 1; (my #x = (1..1000).pick(1)).say'
[471]
On the surface, you'd say that these values should be the same, as each only generates a single value. But apparently a different number of random values is actually calculated under the hood, causing the visibly different values. Is that perhaps what is going on in your case?
(This answer is a paraphrase of jnthn's comment in the GitHub issue opened based on this question).
Setting srand 1 will cause the same sequence of random numbers to be generated -- that is, the nth random number will be the same. However, since Raku (really, Rakudo and/or MoarVM, assuming you're using those backends) uses random numbers internally, you won't always be in the same position in that sequence (i.e., your n might be different) and thus you might not get the same random number.
This is further complicated by Rakudo's optimizer. Naively, repeating the same code later in the program should consume the same number of random numbers from the sequence. However, the optimizer may well remove some of those random number uses from subsequent calls, which can result in different random numbers.
I'm unclear to what degree the current behavior is intended versus a bug in Rakudo/MoarVM's implementation; please see the previously linked issue for additional details.

Are pseudo random number generators less likely to repeat?

So they say if you flip a coin 50 times and get heads all 50 times, you're still 50/50 the next flip and 1/4 for the next two. Do you think/know if this same principle applies to computer pseudo-random number generators? I theorize they're less likely to repeat the same number for long stretches.
I ran this a few times and the results are believable, but I'm wondering how many times I'd have to run it to get an anomaly output.
def genString(iterations):
mystring = ''
for _ in range(iterations):
mystring += str(random.randint(0,9))
return mystring
def repeatMax(mystring):
tempchar = ''
max = 0
for char in mystring:
if char == tempchar:
count += 1
if count > max:
max = count
else:
count = 0
tempchar = char
return max
for _ in range(10):
stringer = genString()
print repeatMax(stringer)
I got all 7's and a couple 6's. If I run this 1000 times, will it approximate a normal distribution or should I expect it to stay relatively predictable? I'm trying to understand the predictability of pseudo random number generation.
Failure to produce specific patterns is a typical weakness of PRNGs, but the probability of hitting a substantial run of repeated digits at random is so small it's hard to demonstrate that weakness.
It's perfectly reasonable for a PRNG to use only a 32-bit state, which (traditionally) means producing a sequence of four billion numbers and then repeating from the start again. In that case your sequence of 50 coin-flips coming out the same is probably never going to happen (four billion tries at something that has a one in a quadrillion chance is unlikely to succeed); but if it does, then it's going to appear way too often.
Superficially you're looking for k-dimensional equidistribution as a test for whether or not you can expect to find a prescribed pattern in the output without deeper analysis of the specific generator. If your generator claims at least 50-dimensional equidistribution then you're guaranteed to see the 50-heads state at least once.
However, if your generator emits 32-bit results but you only test whether each result maps to heads or tails, you have some chance at success even if the generator fails the k-dimension test, and that chance depends on the specifics of the generator and the mapping function.
If you adjust the implementation of your generator to return just one bit at a time, then you have an opportunity to try to squeeze 50 heads out of just 50 bits of state (or potentially as few as 18, but that generator would probably be faulty). Provided the generator visits all 2**50 possible states, one of those states will produce 50 heads in a row. You may get a few more heads when adjacent states start or end with more zeroes.

srand(time(NULL)) c++ isnt working properly [duplicate]

This question is about a comment in this question
Recommended way to initialize srand? The first comment says that srand() should be called only ONCE in an application. Why is it so?
That depends on what you are trying to achieve.
Randomization is performed as a function that has a starting value, namely the seed.
So, for the same seed, you will always get the same sequence of values.
If you try to set the seed every time you need a random value, and the seed is the same number, you will always get the same "random" value.
Seed is usually taken from the current time, which are the seconds, as in time(NULL), so if you always set the seed before taking the random number, you will get the same number as long as you call the srand/rand combo multiple times in the same second.
To avoid this problem, srand is set only once per application, because it is doubtful that two of the application instances will be initialized in the same second, so each instance will then have a different sequence of random numbers.
However, there is a slight possibility that you will run your app (especially if it's a short one, or a command line tool or something like that) many times in a second, then you will have to resort to some other way of choosing a seed (unless the same sequence in different application instances is ok by you). But like I said, that depends on your application context of usage.
Also, you may want to try to increase the precision to microseconds (minimizing the chance of the same seed), requires (sys/time.h):
struct timeval t1;
gettimeofday(&t1, NULL);
srand(t1.tv_usec * t1.tv_sec);
Random numbers are actually pseudo random. A seed is set first, from which each call of rand gets a random number, and modifies the internal state and this new state is used in the next rand call to get another number. Because a certain formula is used to generate these "random numbers" therefore setting a certain value of seed after every call to rand will return the same number from the call. For example srand (1234); rand (); will return the same value. Initializing once the initial state with the seed value will generate enough random numbers as you do not set the internal state with srand, thus making the numbers more probable to be random.
Generally we use the time (NULL) returned seconds value when initializing the seed value. Say the srand (time (NULL)); is in a loop. Then loop can iterate more than once in one second, therefore the number of times the loop iterates inside the loop in a second rand call in the loop will return the same "random number", which is not desired. Initializing it once at program start will set the seed once, and each time rand is called, a new number is generated and the internal state is modified, so the next call rand returns a number which is random enough.
For example this code from http://linux.die.net/man/3/rand:
static unsigned long next = 1;
/* RAND_MAX assumed to be 32767 */
int myrand(void) {
next = next * 1103515245 + 12345;
return((unsigned)(next/65536) % 32768);
}
void mysrand(unsigned seed) {
next = seed;
}
The internal state next is declared as global. Each myrand call will modify the internal state and update it, and return a random number. Every call of myrand will have a different next value therefore the the method will return the different numbers every call.
Look at the mysrand implementation; it simply sets the seed value you pass to next. Therefore if you set the next value the same everytime before calling rand it will return the same random value, because of the identical formula applied on it, which is not desirable, as the function is made to be random.
But depending on your needs you can set the seed to some certain value to generate the same "random sequence" each run, say for some benchmark or others.
Short answer: calling srand() is not like "rolling the dice" for the random number generator. Nor is it like shuffling a deck of cards. If anything, it's more like just cutting a deck of cards.
Think of it like this. rand() deals from a big deck of cards, and every time you call it, all it does is pick the next card off the top of the deck, give you the value, and return that card to the bottom of the deck. (Yes, that means the "random" sequence will repeat after a while. It's a very big deck, though: typically 4,294,967,296 cards.)
Furthermore, every time your program runs, a brand-new pack of cards is bought from the game shop, and every brand-new pack of cards always has the same sequence. So unless you do something special, every time your program runs, it will get exactly the same "random" numbers back from rand().
Now, you might say, "Okay, so how do I shuffle the deck?" And the answer -- at least as far as rand and srand are concerned -- is that there is no way of shuffling the deck.
So what does srand do? Based on the analogy I've been building here, calling srand(n) is basically like saying, "cut the deck n cards from the top". But wait, one more thing: it's actually start with another brand-new deck and cut it n cards from the top.
So if you call srand(n), rand(), srand(n), rand(), ..., with the same n every time, you won't just get a not-very-random sequence, you'll actually get the same number back from rand() every time. (Probably not the same number you handed to srand, but the same number back from rand over and over.)
So the best you can do is to cut the deck once, that is, call srand() once, at the beginning of your program, with an n that's reasonably random, so that you'll start at a different random place in the big deck each time your program runs. With rand(), that really is the best you can do.
[P.S. Yes, I know, in real life, when you buy a brand-new deck of cards it's typically in order, not in random order. For the analogy here to work, I'm imagining that each deck you buy from the game shop is in a seemingly random order, but the exact same seemingly-random order as every other deck of cards you buy from that same shop. Sort of like the identically shuffled decks of cards they use in bridge tournaments.]
Addendum: For a very cute demonstration of the fact that for a given PRNG algorithm and a given seed value, you always get the same sequence, see this question (which is about Java, not C, but anyway).
The reason is that srand() sets the initial state of the random generator, and all the values that generator produces are only "random enough" if you don't touch the state yourself in between.
For example you could do:
int getRandomValue()
{
srand(time(0));
return rand();
}
and then if you call that function repeatedly so that time() returns the same values in adjacent calls you just get the same value generated - that's by design.
A simpler solution for using srand() for generating different seeds for application instances run at the same second is as seen.
srand(time(NULL)-getpid());
This method makes your seed very close to random as there is no way to guess at what time your thread started and the pid will be different also.
srand seeds the pseudorandom number generator. If you call it more than once, you will reseed the RNG. And if you call it with the same argument, it will restart the same sequence.
To prove it, if you do something simple like this, you will see the same number printed 100 times:
#include <stdlib.h>
#include <stdio.h>
int main() {
for(int i = 0; i != 100; ++i) {
srand(0);
printf("%d\n", rand());
}
}
It seems that every time rand() runs, it will set a new seed for the next rand().
If srand() runs multiple times, the problem is if the two running happen in one second (the time(NULL) does not change), the next rand() will be the same as the rand() right after the previous srand().

Random number generator confuses with srand function

I want to learn why my code is not working as I expect. I mean I want to generate a double number between 0 and 1 and I have learnt that when I use
(double)rand() / RAND_MAX, it works well. However I read that srand(time(NULL))
changes each generated random number every time I compile. However When I use them together the program generates same random number all the time. Why does this happen? Thanks.
Here is my code:
//srand(time(NULL));
number = (double)rand() / (double)RAND_MAX;
The srand() function initializes the pseudo-random number generator. You can think of that like it is pointing to the rand() a number to start its 'calculations'. Every time you compile and run your program the srand() function gives your rand() function the seed of time(NULL) (which by the way is a very big number changing every second). If you don't use the srand(), your rand() will always return the same sequence of numbers because it is given by default a standart non-changing seed (number to start the 'calculations'). You can try to give your srand() a static parameter like: srand(1500) You will see that it will return different numbers but their sequence will again be the same every time u compile and run.
For more info read here:
http://www.cplusplus.com/reference/cstdlib/srand/
http://www.cplusplus.com/reference/cstdlib/rand/

Attempt to "go back" without goto statement

The code examples are gonna be in Lua, but the question is rather general - it's just an example.
for k=0,100 do
::again::
local X = math.random(100)
if X <= 30
then
-- do something
else
goto again
end
end
This code generates 100 pseudorandom numbers between 0-30. It should do it between 0-100, but doesn't let the loop go on if any of them is larger than 30.
I try to do this task without goto statement.
for k=0,100 do
local X = 100 -- may be put behind "for", in some cases, the matter is that we need an 'X' variable
while X >= 30 do --IMPORTANT! it's the opposite operation of the "if" condition above!
X = math.random(100)
end
-- do the same "something" as in the condition above
end
Instead, this program runs the random number generation until I get a desired value. In general, I put all the codes here that was between the main loop and the condition in the first example.
Theoretically, it does the same as the first example, only without gotos. However, I'm not sure in it.
Main question: are these program codes equal? They do the same? If yes, which is the faster (=more optimized)? If no, what's the difference?
It is bad practice to use Goto. Please see http://xkcd.com/292/
Anyway, I'm not much into Lua, but this looks simple enough;
For your first code: What you are doing is starting a loop to repeat 100 times. In the loop you make a random number between 0 and 100. If this number is less than or equal to 30, you do something with it. If this number is greater than 30, you actually throw it away and get another random number. This continues until you have 100 random numbers which will ALL be less than or equal to thirty.
The second code says: Start a loop from 0 to 100. Then you set X to be 100. Then you start another loop with this condition: As long as X is greater than 30, keep randomizing X. Only when X is less than 30 will your code exit and perform some action. When it has performed that action 100 times, the program ends.
Sure, both codes do the same thing, but the first one uses a goto - which is bad practice regardless of efficiency.
The second code uses loops, but is still not efficient - there are 2 levels of loops - and one is based on psuedo-random generation which can be extremely inefficient (maybe the CPU generates only numbers between 30-100 for a trillion iterations?) Then things get very slow. But this is also true for you're first piece of code - it has a 'loop' that is based on psuedo-random number generation.
TLDR; strictly speaking about efficiency, I do not see one of those being more efficient than the other. I could be wrong but it seems the same things is going on.
you can directly use math.random(lower, upper)
for k=0,100 do
local X = math.random(0, 30)
end
even faster.
As I see this pieces of code do the same, but using goto always isn't the best choice (in any programming language). For lua see details here

Resources