Hi.
How to generate unequal probability random number.
I mean i.e when I want to generate a number between 1 and 10, these numbers does not have equal probability, this unequality can be an integer (i.e 2 has probability two times of other numbers) or it can be a float value (i.e 3 and 4 have probability 0.2 times of other values).
How can I achieve this?
#include <iostream>
#include <map>
#include <random>
#include <iterator>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
double weights[] =
{0, // do not generate the number 0
1, // number 1 at base probability
2, // number 2 twice as often
0.2, // number 3 at 1/5th probability
0.2, // number 4 at 1/5th probability
1, 1, 1, 1, 1, 1}; // 5..10 at base probability
std::discrete_distribution<> d(std::begin(weights), std::end(weights));
std::map<int, int> m;
for(int n=0; n<10000; ++n) {
++m[d(gen)];
}
for(auto p : m) {
std::cout << p.first << " generated " << p.second << " times\n";
}
}
That was awesome. I compiled this with -std=c++0x option in G++.
Can you please explain your code? it's a little strange to me. What are random_device or mt19937?
Most strange part is last for. Please explain this.
std::random_device is the hardware random number generator (where hardware provides access to such). On Linux, std::random_device uses /dev/urandom by default.
I use it as a source of the seed for mt19937, but you could use it directly:
1 2
for(int n=0; n<10000; ++n)
++m[d(rd)];
mt19937 is the canonical Mersenne Twister pseudo random number generator. It has very good number-theoretical properties, so I usually use it by default (the drawback is that it's a bit slower than other PRNGs)
the last loop is just a range-for over the map, a C++11 syntax
This is standard C++, it works on Windows without modification. (well, you need VC11 beta for the range-for loop, but the <random> library has been around for many years)