Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Whenever we want to pick a random number from a vector we use a method called rand(). I want to know how it works from the backend.
rand has a seed value - e.g. setting it to the current time...
srand( time(NULL ) ); // second good enough
Then there is some math such as this....
unsigned int seed; // set by srand
unsigned int rand() {
seed = seed * number + offset;
return seed;
}
The number and offset are chosen, so the whole of the range of `unsigned int are covered. This generally means some form of prime number.
As mentioned in the comments, this is a very complex area.
If srand is not called, then seed has an initial value, which means that (ignoring thread timing issues), your program will get the same results each time it is run.
Getting the same results is handy for re-running tests, but problematic if it is say a game logic.
There is no "back-end" involved for rand.
BTW, in C++ you'll better use <random> standard header and related utilities, which are in the C++ standard library.
The rand function is part of the C standard library. It is unrelated to C++ vectors.
They (both the rand function and utilities from <random>) are based upon pseudo-random number generators, a quite complex field. You can still get a PhD by inventing better PRNGs.
If you want to understand how rand is (or can be) implemented, you'll better study the source code of some existing free software C standard library (like e.g. GNU glibc or musl-libc).
If you want to understand how <random> is implemented, study the source code of your C++ standard library. If you use the GCC compiler (e.g. compiling with the g++ program), it is provided by it.
Related
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 1 year ago.
Improve this question
I want to populate an array with three different random integers.
int itemA[3] = {rand() % 20 + 1, rand() % 20 + 1, rand() % 20 + 1};
Currently I can only seed the random integer if it is in the main. Can someone tell me how to seed it in the header file where my array is?
From what I've found so far, I think I need srand ( time(0) ) in there, but it only does what I want it to do if it is in the main.
This is a surprisingly deep and important question—so much so that it’s mentioned in my profile. The answer is simple: you don’t do this in the header, even though inline variables make it possible to do so. The reason is important: as global state, the seed must be set once (consider that, if multiple headers each set the seed with time(0) before drawing their “random” numbers, they would typically all get the same results).
There are corollaries to this: since the main program is the only part that (by definition) knows the user’s intentions, it should perform such initialization; for example, the user might wish to reproduce previous results by specifying a seed via a command-line option. Even if your program doesn’t support such features (yet), you already have to have a source file to contain main, so you might as well seed the RNG there.
You might object that you’re not writing main, and perhaps that you have no source files at all. However, that just means that you’re writing a (perhaps header-only) library, which immediately implies that for composability you mustn’t arrogate the responsibility for initialization (what if more than one library did?.
The same logic applies to any other process-global parameters like the current working directory or environment variables. It’s fine for libraries (and internal header files, treating them as miniature libraries) to provide functions to help main manipulate such things (e.g., to collect entropy for the seed or add elements to PATH-like environment variables), but they should never take such actions on their own.
This question already has answers here:
What common algorithms are used for C's rand()?
(3 answers)
Closed 2 years ago.
My question is straightforward. I know abour srand and rand, I know how to seed my random generator and so on. I am specifically interested in the mathematics behind srand. How does the computer use let's say 3333 as a seed and calculates a "random" number?
The c standard library's and therefore the c++ standard library's std::rand implementation is up to the library implementation. It is not mandated by the standard. The following function
(source: https://xkcd.com/221/)
would be a perfectly valid implementation for it.
That is the reason why it should under no circumstances be used any more. Instead defer to the well-defined, implementation independent and portable mersenne twister.
It depends on the library implementation but in general it would be enough to calculate a well mixed hash of the argument.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm writing a genetic algorithm to solve the Master Mind game. I've done lots of research on best approaches and it's incredibly important to have a diverse population. I'm trying to determine how to get really good random numbers in C++. I've done srand(time(NULL)) at the start of my program to set the seed then I've simply used rand(). What I would like to know is how random is that really? Is it pretty good? Are there other better libraries for random numbers?
I know number theory and randomness is a very complicated subject; do you have any pointers in writing your own version of rand()?
For crypto, you need very strong properties on your random numbers. Much of the literature out there focusses on these sorts of requirements. A typical solution would be seeding iterated applications of SHA-256 using environmental noise (hard drive delays, network packets, mouse movements, RDRAND, HAVEGE, ...).
For Monte-Carlo simulations or AI applications, the randomness requirements are much lower indeed. In fact, very simple generators will be good enough. The most basic is the infamous Linear Congruential generator, which is considered a bit old-fashioned now, because the output patterns sometimes produce noticeable and unwanted sampling effects (in particular, some experimental studies done in the 70s and 80s are quite probably flawed because of this). These days, the Mersenne Twister is more popular, and is more than adequate for a computer game. It's available in the C++ standard library: see std::mt19937.
rand()'s randomness is really bad. It is a bog standard LCG and generally has bad randomness and bad quality of projection. If you are serious about quality of randomness for your application, you need to go with something better. Then it depends on whether you want to keep to the standard library, or not.
If you want to use standard library, go with <random> header and Mersenne Twister.
But, I would recommend to you to use the PCG random family instead. Its fast, it has good quality and fixes most of mistakes of <random>.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I'm currently expanding a simulation model that relies heavily upon random normal distributed numbers. Currently it uses std::normal_distribution, but it's too slow.
Is there a way to implement a fast random normal distribution? The values don't have to be unique as long as it follows a normal distribution.
The Ziggurat generator by Marsaglia and Tsang (JSS, 2000) has been seen to be both statistically sound and fast. You do however want the revised Ziggurat normal generator which uses a better underlying uniform generator as per the comment of Leong et al (JSS, 2005).
I have the original papers as well as a few review papers in this GitHub directory which is part of a Ziggurat C++ implementation for R.
std::normal_distribution is a distribution, not a generator. You may want to try out other generator from the standard library and see what's fastest (see http://en.cppreference.com/w/cpp/numeric/random).
If the quality of the numbers is not that important, you could fall back to very simple algorithms, as simple as taking r=++i%6, for example.
A Linear congruential generator is easy to implement, too (actually, most standard rand() implementation use some implementation thereof. However, it will probably not be faster than using std::linear_congruential_engine. At the above linked site there's also a number of readily "configured" random number generators.
There's also an algorithm by the late Marsaglia, which can be found here and which is quite efficient w.r.t. performance and number quality.
At the end, make sure to use proper optimization flags when testing for performance.
The standard <random> library allows to produce random numbers using combinations of generators and distributions. You are using the normal distribution, and what you want is a faster generator then the default, have a look here.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I've used
#include<stdlib>
#include<time>
using namespace std;
srand((unsigned)time(0));
int n=(rand()>>8)%4;
but what other random functions are there, or what other function could be used as random number generators?
EDIT: I don't really have a particular reason for asking this question, I just wanted to know if C++ had any other random functions.
Boost Random Number Library offers a broad range of generators (quality vs performance) and some typical random distributions. Everything rather nice and straightforward to use.
If you want some other methods/libraries - then google for cryptographic random numbers, also you can use this document as a reference.
Don't invent your own solutions unless you are an expert/researcher in the field/etc, take advantage of already existing solutions which were usually written by Smart People, and thoroughly examined by other Smart People.
The rand() and srand() functions are all the C++ Standard specifies. And if it comes to writing your own, be aware of what John von Neumann said:
"Anyone who considers arithmetical
methods of producing random digits is
of course in a state of sin"
This code is pretty efficient. Although users may begin to notice a pattern after a few iterations.
int FastRandom()
{
return 10;
}
Not strictly C++, but Windows specific:
CryptGenRandom
I'm sure all operating systems have their equivalent cryptographically secure random generator functions.
int unixrand()
{
int x;
int f = open("/dev/random", O_RDONLY);
if (f < 0) return -1; /* Error */
if (sizeof(x) != read(f, &x, sizeof(x))) {
close(f);
return -1;
}
close(f);
if (x < 0) x = ~x;
return x;
}
(Cross-posting from an answer I just wrote to a similar question)
Have a look at ISAAC (Indirection, Shift, Accumulate, Add, and Count). Its uniformly distributed and has an average cycle length of 2^8295.
It's fast too, since it doesnt involve multiplication or modulus.
Bruce Schneier and John Kelsey wrote a random number generator you may be interested in. Rather, it's a seed generator. Even though Yarrow is no longer supported, you may be interested in how it gathers entropy.
OpenSSL has an API that is relatively easy to access and pretty portable. And Mozilla comes with a decent API that wraps whatever the OS offers.
Personally, though, I generally use Boost.Random, which was already suggested.
Random gives you a good random number at uniform distribution and does a pretty good job at that.
Anything else would mean that you want to actually skew the distribution.
For example, using Microsoft's GUIDs generator would give you a random id that is less likely to be repeated and takes into account things like time and computer.
Time is usually the most random operation that is also cheap to perform, but it's still possible to predict.
If you want true randomness, using some kind of external input is your only solution.
Quantum Random Bit Generator is one service that provides such data.