Problems in generating random numbers [duplicate] - c

This question already has answers here:
Why do I always get the same sequence of random numbers with rand()?
(12 answers)
Closed 8 years ago.
I'm using the following code for generate the random numbers in C programming, but for every compilation a particular set of random numbers are generating repeatedly. Can anybody mention the correction here???
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
main()
{
int i,a[40];
for(i=0;i<40;i++)
{
a[i] = rand() % 6;
printf("%d\n", a[i]);
}
getch();
}

You need to initialize random seed to a different value, please see http://www.cplusplus.com/reference/cstdlib/rand/

Per the documentation,
If rand() is called before any calls to srand() are made, the same sequence shall
be generated as when srand() is first called with a seed value of 1. [emph. mine]
You need to mix it up, something like this:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include <time.h>
main()
{
int i,a[40];
// seed the PRNG with some random value
// the current time is often used. You might want to incorporate
// other sources of entropy as well.
srand(time(NULL));
for( i = 0 ; i < 40 ; i++ )
{
a[i] = rand() % 6;
printf("%d\n", a[i]);
}
getch();
}
One should note that
seed the PRNG just once at beginning of execution
The reason for incorporating more sources of entity, rather than just relying on the current system clock is that the system clock itself is not very random -- to invocations quite close to each other my result in similar sequences. Other good sources of entropy include:
hard disk statistics
network I/O
process activity
keystroke latency
mouse movements
etc.
Although looking at user interface components such as keystrokes and mouse movements won't buy you much in the way of entropy if your software is running, say, on a server, where the keyboard and mouse are likely to be idle for long periods of time.

Do something like this (inserted line) to seed the random number generator:
//...
int i,a[40];
srand(clock()); //inserted line
for(i=0;i<40;i++)
//...
The clock() function will provide a different seed value each clock tick, resulting in a new and different initialization to the rand() function.

Related

srand(time(NULL)) function [duplicate]

This question already has answers here:
srand() — why call it only once?
(7 answers)
How to use function srand() with time.h? [duplicate]
(5 answers)
Closed 4 years ago.
#include <stdio.h>
#include <stdlib.h>
int main( void){
int x = rand()%100;
printf("%d\n", x);
return 0;
}
The code above generates a random number correctly. Is this correct? But, other sources always include library and srand(time(NULL)). Why do we have to include include library and srand(time(NULL))? Are there any reasons to include?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main( void){
srand(time(NULL));
int x = rand()%100;
printf("%d\n", x);
return 0;
}
Because if you run this code many times, you will get the same result! (also, rand() return the same result in each run). Hence, you can initialize the seed of random in each run of the code to get a different random result by srand. Using time(NULL) to set a different seed of random through srand.
srand is a random number generator function which will randomize the number produced by rand function.
Imagine you have a (huge) library with (huge) books filled with (apparently random, but fixed) numbers.
When you do rand() you get the current number on the current book and advance to the next.
When you do srand(<number>) you select the book rand() will use from that point forward.
time(NULL) return the number (after conversion) of seconds since about midnight 1970-01-01. That number changes every second, so using that number to "select a book" pretty much guarantees a new sequence of "random" numbers every time your program runs.
If you don't select a book, the rand() function takes numbers from book #1 (same as srand(1)).
Having fixed random numbers may be useful in certain situations. For example, you want to test different functions with the same data.

Shuffling an array

What this code is supposed to do is shuffle an array, nonetheless every time I run it on a I get the same "shuffled" array (of course by inputting the same un-shuffled array) I thought the srand(time(NULL)); part was going to make sure of that. If that is not it I don’t know how to make it really shuffle it.
So to sum up I need to know why my code is shuffling the array the same way every time.
# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# include <time.h>
int main(){
int n;
int m;
int tmp;
int i;
printf("Please input the number of elements in your array:\n");
scanf("%d", &n);
int baraja[n];
int tempbaraja[n];
for (int i = 0; i < (sizeof(baraja)/sizeof(baraja[0])); i ++){
printf("Please input the %d element of your array:\n",i);
scanf("%d",&baraja[i]);
}
printf("Unshuffled array:\n");
for (i=0;i < n;i++) {
printf(" %d \n",baraja[i]);
}
for (int i = 0; i < n; i ++){
tempbaraja[i] = baraja[i];
}
for (int i = 0; i < n; i ++){
srand(time(NULL));
m = rand() % n;
if (tempbaraja[m] == baraja[m]){
tmp = baraja[m];
baraja[m] = baraja[i];
baraja[i] = tmp;
}else{
}
}
printf("Shuffled array:\n");
for (i=0;i < n;i++) {
printf(" %d \n",baraja[i]);
}
}
You need to move srand(time(NULL)); outside the for loop.
If you see, rand() is a pseudo-random number generator. srand() is used to provide the seed based on which the random number will be generated by rand().
If every time you seed with the same time(NULL) before each call to rand(), each outcome of rand() is going to be the same.
To achieve the desired result, you need to seed the random number generator only once using srand() and later on each call of rand(), it will give you the random numbers.
Note: Though it is not mandatory, it's good practice to have an explicit return 0 at the end of main().
Get srand(time(NULL)) out of the loop.
From srand reference:
Two different initializations with the same seed will generate the
same succession of results in subsequent calls to rand.
So for each iteration you are initializing the random number generator and getting the first item, which is always the same.
You're misusing srand, it should only be called once outside of the loop. These is also a chance that the srand and rand implementations may be particularly bad on the platform you're running on, leading to poor performance if the program is re-executed quickly.
Alright, I'll answer the followup question. Why is srand() in a loop bad?
The rand() function produces a sequence of acceptably random numbers, without needing srand() at all. The problem is that it's a fixed sequence, so every time you run the program, you'll get the same set of "random" numbers.
The goal of srand(time(NULL)) is to pick a starting value different from any previous starting value. The time() function call is only being used to pick a different starting point, with the drawback that the result only changes once per second. Running the program twice in the same second can be a problem with programs launched from a script file or batch job, but usually not when launched from keyboard or mouse events.
So, using srand(time(NULL)) in the loop has one major evil effect. You only get one new random number every wall-clock second.
Even if you had a high-precision timer to sample from, or used:
unsigned counter = time(NULL);
srand(counter++);
..to choose a different starting value, there are still problems. The distribution of random number chosen from sequential starting points is not as "random" as the overall sequence, and may be quite bad for some generators. If you had a source of starting points that was random enough to give good result from srand();rand();, then you probably wouldn't need rand() at all. You could just use those starting values directly!
Finally, srand() slows down your program. Visual C++ in particular has notoriously slow rand() and srand(), and MinGW uses that library too. (The technical issue is due to storing the seed value in thread local storage, which takes over 100 instructions to find on each call.) However, even a statically linked non-thread-safe version involves an extra call and return that you don't need.
Those are the major reasons that I know of for not using srand() in a loop. Most developers would be happy with "it's not necessary".
The glibc srand() manual page, which states: "The srand() function sets its argument as the seed for a new sequence of pseudo-random integers to be returned by rand(). These sequences are repeatable by calling srand() with the same seed value." Specifically your program potentially violated the clause : "..sequences are repeatable by calling srand() with the same seed value." because it could seed rand() more than once per second with the time -- resulting in identical pseudo-random number sequences.

Random Number Generator in C [duplicate]

This question already has answers here:
Pseudo-random number generator
(12 answers)
Closed 9 years ago.
I'm trying to generate a random number 0 - 59, and am not satisfied with the rand() function in C. Here is the code I'm playing around with:
#include <stdlib.h>
#include <time.h>
main()
{
int num;
srand(time(NULL));
num = rand();
num = num % 59;
printf("%d\n", num);
}
I've repeated the run on this code and noticed that the random numbers being generated don't really seem that random. The generated numbers produced are definitely following a pattern, as each time I run the program the number gets progressively larger until it wraps back around to the beginning (i.e. 2, 17, 21, 29, 38, 47, 54, 59, 4, 11....etc).
Is there a way I can seed the function so that every time I re-run the function I get a true random number with a 1/60 chance of being generated? Or are there any alternative methods I can implement myself rather than using the rand() function in C?
Is there a way I can seed the function so that every time I re-run the function I get a true random number
No, the C standard library uses a PRNG (pseudorandom number generator). You will never get true random numbers.
You can, however, seed it with something that changes more frequently than time(), for example, on POSIX:
struct timeval tm;
gettimeofday(&tm, NULL);
srandom(tm.tv_sec + tm.tv_usec * 1000000ul);
Also, using the modulo operator for generating a random number is not a good solution (it severely decreases entropy). If you have a BSD-style libc implementation, use
uint32_t n = arc4random_uniform(60);
Or, if you don't have this function:
// random() is guaranteed to return a number in the range [0 ... 2 ** 31)
#define MAX_RANDOM ((1 << 31) - 1)
long n;
do {
n = random();
} while (n > (MAX_RANDOM - ((MAX_RANDOM % 60) + 1) % 60));
n %= 60;
Note the use of random() - it is superior to rand() (which had and has a number of low-quality implementations). This function can be seeded using srandom().
Or are there any alternative methods I can implement myself rather than using the rand() function in C?
You can (of course, else how would the writers of the C library implementation do it?), but you better not - it's a separate science to write a good PRNG, so to say.
The way your program is written, you must re-run it each time to get a new random number, which also means it gets re-seeded each time. Re-seeding a PRNG is bad.
You want to seed once, then generate a bunch of random numbers.
Do it this way:
int main(void)
{
int num, i;
srand(time(NULL)); // Seed ONCE
for(i=0; i<100; ++i) // Loop 100 times for random numbers
{
num = rand();
num = num % 59;
printf("%d\n", num);
}
}
Now you should get much better results.
Each time you re-run the program, you re-seed with time(), and that function only advances once a second (if you re-run the program quickly enough you'll get the same result).
The fact that it seems to increment until it rolls over suggests that the first call to rand() is returning the un-modified seed -- that number which increments once per second. In that case you're getting the same results (or very similar results) as if you'd run:
printf("%d\n", time(NULL) % 59);
I'm sure you can see what's wrong with that.
In this case, if you used the 'more correct' rand() * 59 / RAND_MAX, which is meant to prefer a value from the 'more random' bits, you would have an even worse situation -- the results wouldn't change at all for maybe 500 seconds, or more.
Fundamentally you need to find a less predictable seed, but you may also want to see that it's properly mixed before you use it.
Reading from /dev/urandom should provide a good seed, in which case you won't need to worry about mixing, but otherwise calling rand() a couple of times should help to do away with the especially glaring artefacts of the low-quality seed you started with (except, of course, the problem that it only changes once a second).

Simple random number generator in C isn't working

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char** argv) {
srand(time(NULL));
int r = rand();
printf("%d\n", r);
return (EXIT_SUCCESS);
}
When I run this code snippet repeatedly in the space of a few seconds, I get an increasing series of number such as 213252683, 213975384, 214193875, 214445980. It looks to me like I'm just printing out the system time - that hypothesis seems to be confirmed when I add the line printf("%d\n", time(NULL)); to the code. What am I doing wrong? I'm running on Mac OS X 10.6.1 (Snow Leopard), but I'm only using Standard Library functions, so it shouldn't make a difference. Thanks!
Pseudorandom numbers are generated as a chaotic sequence derived from an initial seed. srand initializes the randomness by setting this seed. Apparently, the first random number in the sequence is the seed itself - which is the time() value you set.
This is the reason, why the right way to generate a random sequence is to call srand() only once at the beginning of the program, and then only call rand() (well, maybe until the sequence starts looping, which shouldn't happen too soon, but that depends on the generating function). Calling srand() too often will, as you have seen, deteriorate the randomness.
The random number generator differs widely, so this will be difficult to reproduce on other machines. It looks like the first number from your implementation is just the seed value. On mine, for example, the first number appears to be linearly related to the seed. Generally, you will call srand once in a program, and rand many times, and successive calls will get more random-looking results. If you want to avoid this problem, it would be reasonable to do:
srand(time(NULL));
rand();
int r = rand();
printf("%d\n", r);
The first rand call makes sure the seed doesn't get returned, and the next one should pick up something that appears more random. Note that if you run the program twice in a short enough time span (such that time(NULL) is the same in both runs) you will get exactly the same results. This is definitely to be expected - use a different seed value (pid + time might be a good start, or just a higher-resolution time) if this is a problem.
When I run this code snippet repeatedly in the space of a few seconds,
I get an increasing series of number such as 213252683, 213975384,
214193875, 214445980.
I cannot reproduce this. On my system (Debian Linux) I get numbers that are not ordered. Also, the results are not the same as what you get when you print time(NULL).
This is as it should be: You are seeding the random number generator with the current time (in seconds). Thus as long as the time (down to seconds) is the same, your program will print the same result.
What am I doing wrong?
Well, that depends on what you want. If you want random numbers for every run, you need a better source of randomness. You could try functions like gettimeofday, which have higher resolution (typically ms, I believe). Also, mix in other sources of randomness, like the ID of your process.
In most programs, the effect you see is no problem, because typically srand() is only called at the start, and then rand() returns a different number on every call.
If you want "secure" (i.e. unpredictable) random numbers, that's a whole other game. See e.g. Wikipedia for an overview.
In case it helps I generally use it that way:
int rand_between(int min, int max)
{
static int flag = 1;
FILE *urandom;
unsigned int seed;
if (flag)
{
flag = 0;
if (!(urandom = fopen ("/dev/urandom", "r")))
fprintf(stderr, "Cannot open /dev/urandom!\n");
fread(&seed, sizeof(seed), 1, urandom);
srand(seed);
}
return ((int)rand() % (max - min)) + min;
}
To get a random uppercase letter:
char letter = (char)rand_between('A', 'Z');
You should use random() instead of rand(). It is superior to rand() in every way, and it is also included in stdlib.
Try the following code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
int r = random();
printf("%d\n", r);
return (EXIT_SUCCESS);
}

Why isn't this number random?

For the following piece of code:
#include<stdlib.h>
#include<stdio.h>
int main()
{
int x;
x = rand()%100;
printf("The Random Number is: %i", x);
return 0;
}
It always seems to print the random number as 83. Why is this?
Most random number generators are repeatable. You need to seed the generator before using it which you typically do using the system time.
#include <time.h>
srand(time(NULL));
Obligatory XKCD reference:
As people have said, you need to seed the pseudo random number generator properly.
The trouble is, it still only generates pseudo random numbers. Most "true" random number generators require access to some physical phenomenon that is random in nature (for example, clock skews or temperature fluctuations).
Otherwise, the XKCD reference is not too far from the truth. Nor is Dilbert.
Because the pseudo-random number generator used by rand is always initialized with the same seed.
In order to initialize it with a different seed, you can use the srand function, and initialize it as, say, srand(time(NULL)).
Because 83 is a random number, isn't it ?
More seriously, it is useful to have programs providing a repeatable behavior so by default, rand always returns the same sequence of numbers if you don't change the seed.
Seed the random number generator by including <time.h> and calling srand(time(0)); (edited thanks to my commenters)
You can not generate a random number which is truly random until and unless your random number generator has access to a truly random physical phenomenon as quoted earlier by peter. But for a general use you can use C's standard library functions for generating random numbers. Here is a sample code for generating random number between two limits(max and min):
#include<stdio.h>
#include<stdlib.h>
#define MIN 1
#define MAX 5
#define QUANTITY 5
int main()
{
int i;
//stores the time in seconds
time_t seconds;
//getting the system time
time(&seconds);
//initializing the random generator with system time
//as the seed value
srand((long)seconds);
for(i = 0; i < QUANTITY; i++)
{
printf("%f\t",((float)rand())/RAND_MAX*(MAX-MIN)+MIN);
}
printf("\n");
return 0;
}

Resources