By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,701 Members | 1,966 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,701 IT Pros & Developers. It's quick & easy.

random number geneator

P: n/a
Hi all:
I am trying to write a simple program that simulates asking several persons
their birth day and it counts how many persons are asked until two have the
same birth day. The problem that I have is that the first loop I get a
sequence of random numbers untuil I get a match, BUT then on the following
loops I get the SAME random(?) sequence. I am using rand(). I do not want to
get too fancy with the random number generator, but is there a way of
stopping rand() from resetting every time it starts the loop? What other
choices do I have? Can I somehow use the system time to help me get more
random? Here is my code so far:

#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
int const tests = 10000;
int index;
int i,j;
int match = 0;
int days[366] = {0};
int count = 0;

for (j = 1; j <= tests; j++)
{
while (match != 1)
{
index = (rand() % 365) + 1;

if (days[index] != 1)
{
days[index]++;
count++;
}
else
{
for (i = 1; i < 366; i++)
{
days[i] = 0;
}

match = 1;
}

}

cout << count << endl;
}

return 0;
}
Jul 22 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
In comp.lang.c++
"Sonoman" <so*****@aol.com> wrote:
get too fancy with the random number generator, but is there a way of
stopping rand() from resetting every time it starts the loop? What other
choices do I have? Can I somehow use the system time to help me get more
random?


Yes, add ONE call like this:

srand(time(NULL));

and your done.

Jul 22 '05 #2

P: n/a

----- Original Message -----
From: "Sonoman" <so*****@aol.com>
Newsgroups: comp.lang.c++
Sent: Wednesday, January 07, 2004 6:25 PM
Subject: random number geneator

Hi all:
I am trying to write a simple program that simulates asking several persons their birth day and it counts how many persons are asked until two have the same birth day. The problem that I have is that the first loop I get a
sequence of random numbers untuil I get a match, BUT then on the following
loops I get the SAME random(?) sequence. I am using rand(). I do not want to get too fancy with the random number generator, but is there a way of
stopping rand() from resetting every time it starts the loop? What other
choices do I have? Can I somehow use the system time to help me get more
random? Here is my code so far:

#include <iostream>
#include <cstdlib>
add the header, <ctime>

using namespace std;

int main()
{
int const tests = 10000;
int index;
int i,j;
int match = 0;
int days[366] = {0};
int count = 0;

for (j = 1; j <= tests; j++)
{
while (match != 1)
at the begining of the loop add,
"srand(clock());"
{
index = (rand() % 365) + 1;

if (days[index] != 1)
{
days[index]++;
count++;
}
else
{
for (i = 1; i < 366; i++)
{
days[i] = 0;
}

match = 1;
}

} Here you need to put something to change the "seed" in the
"srand(clock());" statement, for example a counter that
requires <Enter> to be pressed every 10 loops
if(counter%10==9) cin.get();
cout << count << endl;
}
I think you wanted the last "}" bracket above "cout << count << endl;"
return 0;
}


Keep in mind that these are still pseudorandom numbers, but at least the
seed will be changed by pressing the <Enter>.
Jul 22 '05 #3

P: n/a

"Pierre Espenan" <wh**************@yahoo.com> wrote in message
news:zi*******************@newsread1.news.pas.eart hlink.net...

[SNIP]

for (j = 1; j <= tests; j++)
{
while (match != 1)


at the begining of the loop add,
"srand(clock());"


This advice is a bad, bad idea regarding randomness. srand should be called
only once(!!) in a program and NEVER inside a loop. The reason is that
calling srand once will yield in a start seed that defines the sequence of
random numbers produced. After calling rand() the internal seed is updated
so that the next call or rand() will result in the next random number of
this specific sequence. If you call srand() more often you are going to jump
from sequence to sequence which will certainly destroy randomness. Although
for this case it might not be a real problem you should refrain from
multiple calls to srand, unless you know exactly what you are doing and what
the results are.

Regards
Chris
Jul 22 '05 #4

P: n/a
On Thu, 08 Jan 2004 05:11:44 +0000, Bruce wrote:
In comp.lang.c++
"Sonoman" <so*****@aol.com> wrote:
get too fancy with the random number generator, but is there a way of
stopping rand() from resetting every time it starts the loop? What other
choices do I have? Can I somehow use the system time to help me get more
random?


Yes, add ONE call like this:

srand(time(NULL));

and your done.


Sound advice, but be aware that time() has low granularity. You may want
to mix in some (platform specific) other elements, like the PID of your
program, or hash the output from netstat and add that. If your program is
designed to run very shortly, this becomes important.

I once was bitten by repeated runs of a program giving exactly the same
results as time() changed only once a second and typically several runs of
the program could be completed in that one second.

Also be aware that many rand() implementations are very poor. For a
typical game this may be acceptable, but for cryptographic operations one
should use some better pseudo random generator (PRNG).

If you really need better random numbers, also have a look at EGD.

HTH,
M4

Jul 22 '05 #5

P: n/a
Chris Theis wrote:

"Pierre Espenan" <wh**************@yahoo.com> wrote in message
news:zi*******************@newsread1.news.pas.eart hlink.net...

[SNIP]

for (j = 1; j <= tests; j++)
{
while (match != 1)


at the begining of the loop add,
"srand(clock());"


This advice is a bad, bad idea regarding randomness. srand should be called
only once(!!) in a program and NEVER inside a loop. The reason is that
calling srand once will yield in a start seed that defines the sequence of
random numbers produced. After calling rand() the internal seed is updated
so that the next call or rand() will result in the next random number of
this specific sequence. If you call srand() more often you are going to jump
from sequence to sequence which will certainly destroy randomness. Although
for this case it might not be a real problem you should refrain from
multiple calls to srand, unless you know exactly what you are doing and what
the results are.


In addition, calling srand() only once allows you to replace
the "clock()" call with some constant so you can get REPEATABLE
sequences of random number for testing purposes. AFTER testing
is completed, restore the clock() call (or something similar).

Mike
Jul 22 '05 #6

P: n/a

"Chris Theis" <Ch*************@nospam.cern.ch> wrote in message
news:yv******************@news.chello.at...

"Pierre Espenan" <wh**************@yahoo.com> wrote in message
news:zi*******************@newsread1.news.pas.eart hlink.net...
[SNIP]

for (j = 1; j <= tests; j++)
{
while (match != 1)


at the begining of the loop add,
"srand(clock());"


This advice is a bad, bad idea regarding randomness. srand should be

called only once(!!) in a program and NEVER inside a loop. The reason is that
calling srand once will yield in a start seed that defines the sequence of
random numbers produced. After calling rand() the internal seed is updated
so that the next call or rand() will result in the next random number of
this specific sequence. If you call srand() more often you are going to jump from sequence to sequence which will certainly destroy randomness. Although for this case it might not be a real problem you should refrain from
multiple calls to srand, unless you know exactly what you are doing and what the results are.
Did you actually try to compile and run the code listed? Did you see what
he is talking about? The same number is generated by rand() in each loop
because the loop has a constant relationship to clock(). Puting in
cin.get() into the loop insures that a different seed is generated each
loop. I ran the modified program for 100 loops and the average for count
came out to 24 which is very close to the average expected by strict
mathematical analysis. The reason srand(clock()) is discouraged within a
loop is that unless special care is taken a new seed will not be generated.
Run the following code and see what happens...

#include <iostream>
#include <ctime>
#include <bitset>

using namespace std;

int main(){
bitset<365> date;
while(1){
srand(clock());
for(int count=1,i=0; ; ++count){
i=rand()%365;
if(date.test(i)) break;
date.flip(i);
}
cout << count << '\n';
date.reset();
cin.get();
}
return 0;
}


Regards
Chris



----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Jul 22 '05 #7

P: n/a
Pierre Espenan wrote:

"Chris Theis" <Ch*************@nospam.cern.ch> wrote in message
news:yv******************@news.chello.at...

"Pierre Espenan" <wh**************@yahoo.com> wrote in message
news:zi*******************@newsread1.news.pas.eart hlink.net...
[SNIP]
>
> for (j = 1; j <= tests; j++)
> {
> while (match != 1)

at the begining of the loop add,
"srand(clock());"


This advice is a bad, bad idea regarding randomness. srand should be

called
only once(!!) in a program and NEVER inside a loop. The reason is that
calling srand once will yield in a start seed that defines the sequence of
random numbers produced. After calling rand() the internal seed is updated
so that the next call or rand() will result in the next random number of
this specific sequence. If you call srand() more often you are going to

jump
from sequence to sequence which will certainly destroy randomness.

Although
for this case it might not be a real problem you should refrain from
multiple calls to srand, unless you know exactly what you are doing and

what
the results are.


Did you actually try to compile and run the code listed?


Did you ever read the documentation for rand()?
If you call rand(), it will also update the seed value. Thus when calling
rand() the next time, it will generate a different random number (and
update the seed value again) such that when calling rand() the next time
a different random value is generated (and the seed is updated again) etc.

It is important to let rand() do this in its own, because randomness in
a computer is a statistical property. If you reseed the random number
generator to often, this statistical property cannot build up (as with
all statistics, it works only for a sufficient large number of samples,
in this case a sufficient large number of random values).
Did you see what
he is talking about? The same number is generated by rand() in each loop
because the loop has a constant relationship to clock().
It doesn't matter. The main problem is, that srand() should be called only
once (!) in a program, not often, especially not before every call to rand()!
BTW: The original code didn't have a call to srand() at all. Thus there could
not have been any realtionship to clock() (which was also not in the original
code).

Common practice is to not use clock() for seeding the random number generator
but using time() to do that.
Puting in
cin.get() into the loop insures that a different seed is generated each
loop.
And how does this help in a program which should run on it's own without
a user?
I ran the modified program for 100 loops and the average for count
came out to 24 which is very close to the average expected by strict
mathematical analysis. The reason srand(clock()) is discouraged within a
loop is that unless special care is taken a new seed will not be generated.


The reason why you shouldn't call srand() more then once is, that you destroy
the randomness of the sequence if you do it. A random number generator is
designed to give a *sequence* of random numbers. It is only the sequence
which shows the properties of randomness. Don't interfere with the
generation of the sequence or you will destroy randomness very easily.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #8

P: n/a

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:3F***************@gascad.at...
Pierre Espenan wrote:

"Chris Theis" <Ch*************@nospam.cern.ch> wrote in message
news:yv******************@news.chello.at...

"Pierre Espenan" <wh**************@yahoo.com> wrote in message
news:zi*******************@newsread1.news.pas.eart hlink.net...
>
[SNIP]
> >
> > for (j = 1; j <= tests; j++)
> > {
> > while (match != 1)
>
> at the begining of the loop add,
> "srand(clock());"

This advice is a bad, bad idea regarding randomness. srand should be called
only once(!!) in a program and NEVER inside a loop. The reason is that
calling srand once will yield in a start seed that defines the sequence of random numbers produced. After calling rand() the internal seed is updated so that the next call or rand() will result in the next random number of this specific sequence. If you call srand() more often you are going
to jump
from sequence to sequence which will certainly destroy randomness.

Although
for this case it might not be a real problem you should refrain from
multiple calls to srand, unless you know exactly what you are doing
and what
the results are.


Did you actually try to compile and run the code listed?


Did you ever read the documentation for rand()?
If you call rand(), it will also update the seed value. Thus when calling
rand() the next time, it will generate a different random number (and
update the seed value again) such that when calling rand() the next time
a different random value is generated (and the seed is updated again) etc.

It is important to let rand() do this in its own, because randomness in
a computer is a statistical property. If you reseed the random number
generator to often, this statistical property cannot build up (as with
all statistics, it works only for a sufficient large number of samples,
in this case a sufficient large number of random values).
Did you see what
he is talking about? The same number is generated by rand() in each loop because the loop has a constant relationship to clock().


It doesn't matter. The main problem is, that srand() should be called only
once (!) in a program, not often, especially not before every call to

rand()! BTW: The original code didn't have a call to srand() at all. Thus there could not have been any realtionship to clock() (which was also not in the original code).

Common practice is to not use clock() for seeding the random number generator but using time() to do that.
Oops! I tried srand(time(NULL)) outside of the loop and this does yield the
correct result without cin.get() so I guess this is the source of all the
problems
generating (pseudo) random numbers I have been having. I just confused
clock()
with time().
Puting in
cin.get() into the loop insures that a different seed is generated each
loop.
And how does this help in a program which should run on it's own without
a user?
I ran the modified program for 100 loops and the average for count
came out to 24 which is very close to the average expected by strict
mathematical analysis. The reason srand(clock()) is discouraged within a loop is that unless special care is taken a new seed will not be

generated.
The reason why you shouldn't call srand() more then once is, that you destroy the randomness of the sequence if you do it. A random number generator is
designed to give a *sequence* of random numbers. It is only the sequence
which shows the properties of randomness. Don't interfere with the
generation of the sequence or you will destroy randomness very easily.

--
Karl Heinz Buchegger
kb******@gascad.at



----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Jul 22 '05 #9

P: n/a
First of all, Thanks for the help. The srand works better outside the loop.
The first time I ran the program I got a sequence of random numbers. BUT on
the second time and the times after that, when I execute the program I get
the same exact sequence of numbers. Does anyone care to explain why? Any
simple solutions out there? Any clever solutions for my print statement? It
just looks to stupid. Here is my current code:

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
int index;
int i;
double j;
int match = 0;
int days[366] = {0};
double count = 0;
double sum = 0;
double average;

srand(clock());

for (j = 1; j <= 10000; j++)
{
while (match != 1)
{
index = (rand() % 365) + 1;

if (days[index] != 1)
{
days[index]++;
count++;
}
else
{
for (i = 0; i < 366; i++)
{
days[i] = 0;
}

match = 1;
sum = sum + count;
average = sum/j;
}
}

if( j == 1 || j == 2 || j == 3 || j == 4 || j == 5 ||
j == 10 || j == 25 || j == 50 || j == 100 ||
j == 1000 || j == 10000)
{
cout << "test # " << j << " asked " << count <<
" persons, the average so far is: " << average << endl;
}

match = 0;
count = 0;
}

return 0;
}
Jul 22 '05 #10

P: n/a
On Fri, 09 Jan 2004 17:21:36 -0500, Sonoman wrote:
First of all, Thanks for the help. The srand works better outside the loop.
The first time I ran the program I got a sequence of random numbers. BUT on
the second time and the times after that, when I execute the program I get
the same exact sequence of numbers. Does anyone care to explain why? Any
simple solutions out there? Any clever solutions for my print statement? It
just looks to stupid. Here is my current code:

srand(clock());


CLOCK(3) Linux Programmer's Manual CLOCK(3)

NAME
clock - Determine processor time

SYNOPSIS
#include <time.h>

clock_t clock(void);

DESCRIPTION
The clock() function returns an approximation of processor time used by
the program.

Clock() always returns (aproximately) the same number. Use time() instead.

HTH,
M4

Jul 22 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.