How do you create pseudo random numbers sequentially in c/c++? - c++

srand(time(NULL));
for (it=hand.begin(); it < hand.end(); it++)
(*it) = rand() % 13 + 1;
This code does not work to create many random numbers at a time.
Is there a way to do it that isn't as complex as Mersennes and isn't operating system dependent?

PRNGs don't create many PRNs at once. Each output is dependent on the previous output, PRNGs are highly stateful.
Try:
srand(time(NULL)); // once at the start of the program
for( int i = 0; i < N; ++i )
r[i] = rand();
Even APIs that return an entire block of output in a single function call, have just moved that loop inside the function.

Call srand just once, at the start of your program. Then call rand() (not srand(rand())) to generate each random number.

Boost.Random has lots of good random number generators which are easy to use.

George Marsaglia posted a Multiply With Carry PRNG some time ago in sci.math.
I cannot say how good it is or how well it behaves, but you might want to give it a try.
It should be OS and platform independent.

"please make sure you answer the question"
OK
for (int i=n1; i < n2; ++i)
{
int k;
do k = rand(); while (i !=k);
// k is a sequential pseudo random number
}
There may be issues with efficiency...

Related

How to Generate a 'Future-Index' Pseudo-Random Number Without Generating Its Preceding Numbers [duplicate]

Is there any (non-cryptographic) pseudo random number generator that can skip/drop N draws in O(1), or maybe O(log N) but smaller than O(N).
Especially for parallel applications it would be of advantage to have a generator of the above type. Image you want to generate an array of random numbers. One could write a parallel program for this task and seed the random number generator for each thread independently. However, the numbers in the array would then not be the same as for the sequential case (except for the first half maybe).
If a random number generator of the above type would exist, the first thread could seed with the seed used for the sequential implementation. The second thread could also seed with this seed and then drop/skip N/2 samples which are generated by the first thread. The output array would then be identical to the serial case (easy testing) but still generated in less time.
Below is some pseudo code.
#define _POSIX_C_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
void rand_r_skip(unsigned int *p_seed, int N)
{
/* Stupid O(N) Implementation */
for (int i = 0; i < N; i++)
{
rand_r(p_seed);
}
}
int main()
{
int N = 1000000;
unsigned int seed = 1234;
int *arr = (int *)malloc(sizeof(int) * N);
#pragma omp parallel firstprivate(N, seed, arr) num_threads(2)
{
if (omp_get_thread_num() == 1)
{
// skip the samples, obviously doesn't exist
rand_r_skip(&seed, N / 2);
}
#pragma omp for schedule(static)
for (int i = 0; i < N; i++)
{
arr[i] = rand_r(&seed);
}
}
return 0;
}
Thank you all very much for your help. I do know that there might be a proof that such a generator cannot exist and be "pseudo-random" at the same time. I am very grateful for any hints on where to find further information.
Sure. Linear Conguential Generator and its descendants could skip generation of N numbers in O(log(N)) time. It is based on paper of F.Brown, link.
Here is an implementation of the idea, C++11.
As kindly indicated by Severin Pappadeux, the C, C++ and Haskell implementations of a PCG variant developed by M.E. O'Neill provides an interface to such jump-ahead/jump-back functionality: herein.
Function names are: advance and backstep, which were briefly documented hereat and hereat, respectively
Quoting from the webpage (accessed at the time of writing):
... a random number generator is like a book that lists page after page of statistically random numbers. The seed gives us a starting point, but sometimes it is useful to be able to move forward or backwards in the sequence, and to be able to do so efficiently.
The C++ implementation of the PCG generation scheme provides advance to efficiently jump forwards and backstep to efficiently jump backwards.
Chris Dodd wrote the following:
Obvious candidate would be any symmetric crypto cipher in counter mode.

How do i Pick a Random Number from an array in c++? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
int array[5];
int Random;
for (int i = 0; i <5; i++)
{
cin>>array[i];
}
for (int j = 0; j < 5; j++)
{
Random = array[rand() % array[j]];
}
cout << Random << endl;
This is giving me continously return 1 but i want different number every time
Rand is basically obsolete.
There were just so many complaints about how bad it was (because to use it correctly you had to remember to do a couple of things). Even Peris in his answer does not correct for uneven ranges.
So please try and use the modern random library it is much more powerful. Though its documentation is hard going you don't need to read it all. Here is a simple example of how to use it.
#include <random>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> array(5, 0);
for (int i = 0; i < 5; ++i)
{
std::cin >> array[i];
}
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, array.size() - 1);
std::cout << array[dis(gen)];
}
Notes:
rd: Random device. Gives some initial randomness to help initialize things.
Think of this as the `srand(time())` in the old random (but better).
mt19937: This is the algorithm used to generate the random number.
It is initialized with some random value from rd. But it
is a well know well understood random algorithm.
Also be seperating this out into its own object.
We don't have a central random number place. This means
different applications can have their own unique random number stream.
Note: If you want a random number stream. But the same stream
every time (testing/debugging) then don't use the random
device to initialize this object. Just use a nice normal
integer and it will give a random stream of numbers but each
time you run the application you get the same stream (which is useful
for debugging when you don't actually want real randomness).
dis: The main issue with the old rand() is that if just gave a number.
It was up to the user of the number to build appropriate distributions
and to be blunt most people either got it wrong or did not bother.
In the random library there are several built in distributions but uniform
is a nice easy one that is often useful (and I hope obvious).
rand() doesn't return a true-random, rather it returns a pseudo-random.
It all depends on the initial seed you provide to the random generator. If the initial seed is the same, then the consequent numbers you'll get from pseudo-random-algorithm is the same.
Then you should change the initial seed for the rand() on each call (in this case, each execution of your program). What else is a better changing value than time?
Note:
array[rand() % array[j]]; line on your code is highly vulnerable to segmentation fault by array index going out of bound.
Here is the solution.
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
// Initialize the srand seed.
srand (time(NULL));
int size = 5;
int array[size];
int Random;
for (int i = 0; i <5; i++)
{
cin>>array[i];
}
int index = rand() % size;
Random = array[index];
cout << Random << endl;
}
UPDATE:
As many others suggested, you can move to std::uniform_int_distribution for better results. My answer only updates your initial code.

First random number is always smaller than rest

I happen to notice that in C++ the first random number being called with the std rand() method is most of the time significant smaller than the second one. Concerning the Qt implementation the first one is nearly always several magnitudes smaller.
qsrand(QTime::currentTime().msec());
qDebug() << "qt1: " << qrand();
qDebug() << "qt2: " << qrand();
srand((unsigned int) time(0));
std::cout << "std1: " << rand() << std::endl;
std::cout << "std2: " << rand() << std::endl;
output:
qt1: 7109361
qt2: 1375429742
std1: 871649082
std2: 1820164987
Is this intended, due to error in seeding or a bug?
Also while the qrand() output varies strongly the first rand() output seems to change linearly with time. Just wonder why.
I'm not sure that could be classified as a bug, but it has an explanation. Let's examine the situation:
Look at rand's implementation. You'll see it's just a calculation using the last generated value.
You're seeding using QTime::currentTime().msec(), which is by nature bounded by the small range of values 0..999, but qsrand accepts an uint variable, on the range 0..4294967295.
By combining those two factors, you have a pattern.
Just out of curiosity: try seeding with QTime::currentTime().msec() + 100000000
Now the first value will probably be bigger than the second most of the time.
I wouldn't worry too much. This "pattern" seems to happen only on the first two generated values. After that, everything seems to go back to normal.
EDIT:
To make things more clear, try running the code below. It'll compare the first two generated values to see which one is smaller, using all possible millisecond values (range: 0..999) as the seed:
int totalCalls, leftIsSmaller = 0;
for (totalCalls = 0; totalCalls < 1000; totalCalls++)
{
qsrand(totalCalls);
if (qrand() < qrand())
leftIsSmaller++;
}
qDebug() << (100.0 * leftIsSmaller) / totalCalls;
It will print 94.8, which means 94.8% of the time the first value will be smaller than the second.
Conclusion: when using the current millisecond to seed, you'll see that pattern for the first two values. I did some tests here and the pattern seems to disappear after the second value is generated. My advice: find a "good" value to call qsrand (which should obviously be called only once, at the beginning of your program). A good value should span the whole range of the uint class. Take a look at this other question for some ideas:
Recommended way to initialize srand?
Also, take a look at this:
PCG: A Family of Better Random Number Generators
Neither current Qt nor C standard run-time have a quality randomizer and your test shows. Qt seems to use C run-time for that (this is easy to check but why). If C++ 11 is available in your project, use much better and way more reliable method:
#include <random>
#include <chrono>
auto seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
std::uniform_int_distribution<uint> distribution;
uint randomUint = distribution(generator);
There is good video that covers the topic. As noted by commenter user2357112 we can apply different random engines and then different distributions but for my specific use the above worked really well.
Keeping in mind that making judgments about a statistical phenomena based on a small number of samples might be misleading, I decided to run a small experiment. I run the following code:
int main()
{
int i = 0;
int j = 0;
while (i < RAND_MAX)
{
srand(time(NULL));
int r1 = rand();
int r2 = rand();
if (r1 < r2)
++j;
++i;
if (i%10000 == 0) {
printf("%g\n", (float)j / (float)i);
}
}
}
which basically printed the percentage of times the first generated number was smaller than the second. Below you see the plot of that ratio:
and as you can see it actually approaches 0.5 after less than 50 actual new seeds.
As suggested in the comment, we could modify the code to use consecutive seeds every iteration and speed up the convergence:
int main()
{
int i = 0;
int j = 0;
int t = time(NULL);
while (i < RAND_MAX)
{
srand(t);
int r1 = rand();
int r2 = rand();
if (r1 < r2)
++j;
++i;
if (i%10000 == 0) {
printf("%g\n", (float)j / (float)i);
}
++t;
}
}
This gives us:
which stays pretty close to 0.5 as well.
While rand is certainly not the best pseudo random number generator, the claim that it often generates a smaller number during the first run does not seem to be warranted.

Exponential number generator sometimes gives "weird" results

I am building a simulation in C++ and I have an exponential generator to make the burst times of the processes.
Usually it returns values as such: 3.14707,1.04998. But frequently 1/10 occasions such numbers turn out: 2.64823e-307
This is the code of the generator (I am using srand ( time(NULL) ); at the beginning of the program):
double exponential(float u)
{
double x,mean;
mean = 10;
// generate a U(0,1) random variate
x = rand();
u = x / RAND_MAX;
return (-mean * log(u));
}
And this is how I assign the values. The while part inside is my effort to get rid of such values but it didn't work:
for (int i = 0; i < nPages; i++)
{
index[i] = i;
arrival[i]= poisson(r);
burst[i]=exponential(u);
while (burst[i]<1 || burst[i]>150)
{
cout<<"P"<<i<<endl;
burst[i]=(burst[i-1]+burst[i+1])/2;
}
}
Why do you use the C library instead of the C++ library ??
std::random_device rd;
std::default_random_engine gen(rd());
std::exponential_distribution<double> dist(lambda);
double x = dist(gen);
If the size of burst is nPages, then
for (int i = 0; i < nPages; i++)
{
//...
burst[i]=(burst[i-1]+burst[i+1])/2;
}
will step outside its bounds, so you are likely to end up with nonsense.
You need to think about what is required at the edges.
As far as the comments about rand go rand considered harmful is worth a watch. In your case taking log of 0 is not sensible.
Using your exponential function copied verbatim, I cannot reproduce the error you describe. Issues with the PRNG cranking out either 0 or RAND_MAX should only show up one time out of RAND_MAX apiece, not 10% of the time. I suspect either a buggy compiler, or that what you have shared is not the actual code that produces the described problem.

A random number generator that can get different numbers in < a second

I'm in need of a C++ (pseudo, i don't care) random number generator that can get me different numbers every time I call the function. This could be simply the way I seed it, maybe there's a better method, but every random generator I've got doesn't generate a new number every time it's called. I've got a need to get several random numbers per second on occasion, and any RNG i plug in tends to get the same number several times in a row.
Of course, I know why, because it's seeded by the second, so it only generates a new number every second, but I need to, somehow, get a new number on every call. Can anyone point me in the right direction?
Sounds like you do it like this:
int get_rand() {
srand(time(0));
return rand();
}
Which would explain why you get the same number within one second. But you have to do it like this:
int get_rand() {
return rand();
}
And call srand once at program startup.
You only need to seed the generator once with srand() when you start, after that just call the rand() function. If you seed the generator twice with the same seed, you'll get the same value back each time.
You should only seed the PRNG once.
Boost.Random has a variety of pretty good random number generators.
If you're generating a large number of random numbers, you could try an XORShift generator. For longs (8 bit):
// initial setup
unsigned long x = ... init from time etc ...
// each time we want a random number in 'x':
x ^= x << 21;
x ^= x >> 35;
x ^= x << 4;
This code generates a unique random number only once.
#include <ctime>
# include <iostream>
using namespace std;
int main()
{
int size=100;
int random_once[100];
srand(time(0));
for (int i=0;i<size;i++) // generate unique random number only once
{
random_once[i]=rand() % size;
for(int j=0;j<i;j++) if (random_once[j]==random_once[i]) i--;
}
for ( i=0;i<size;i++) cout<<" "<<random_once[i]<<"\t";
return 0;