2

Possible Duplicate:
Biased Random Number Generator

for once I need a random number generator with at least two numbers that have higher probabality than the others.

i.e for example: random 1->10 in a sequence of 1000. Numbers A=3 and B=7.

A - should repeat approx. at least 20% of the time. B - should repeat approx. at least 30% of the time.

That should cover at least 50% of the 1000 sequence. Also the insertion of A and B should be somewhat probable/random in themselves. Not just add A and B every Nth step. Total/exact control isn't needed.

Any Ideas?

I'm a noob - c++ style code would be greatly appreciated!

Community
  • 1
  • 1
ichad.c
  • 131
  • 2
  • 8

2 Answers2

2

One way you can do this is to randomly generate a number between 0.0 and 1.0, and choose what number to generate based on that number. For example, to implement your example scenario (pseudocode):

let "result" be an array of 1000 integers
let "i" be an integer
for i = 1 to 1000:
    let "j" be a random number between 0.0 and 1.0
    if j < 0.2:
        let result[i] be 3
    else if j < 0.5:
        let result[i] be 7
    else:
        let "k" be an integer
        do, while k = 3 or k = 7:
            let "k" be a random number in the range 1 to 10
        let result[i] be k
end

Basically, j is used to partition the range 1 to 10 into three parts - one part covering from 0% to 20% of the range (the first if), the second covering from 20% to 50% of the range (i.e. 30% wide, the second if), and the last covering the remaining 50%. Depending on which part we randomly fall in, we chose the number to generate as appropriate.

Mac
  • 14,615
  • 9
  • 62
  • 80
  • That still depends on the original random generator. Also forgot to be MORE specific. It's use is for an Arpregiator - used in music synthesizers. Say the values are array[24] (that's two octaves in music, a distubution mapping would bunch the values too close to the given points - A & B in my case. A & B should have probability(interger) and the rest should be random(integer). – ichad.c Jul 04 '12 at 23:01
  • Sorry, just read the update to your reply - that should work. Thanks! – ichad.c Jul 04 '12 at 23:06
1

You should use the <random> library for this.

#include <random>

#include <iostream>
#include <algorithm>
#include <iterator>

int main() {
    // create a discrete distribution where the third object has 20% probability and
    //   the seventh has 30%
    std::vector<double> probabilities(10, 5.0/8.0);
    probabilities[2] = 2.0;
    probabilities[6] = 3.0;
    std::discrete_distribution<int> dist(begin(probabilities),end(probabilities));

    // our underlying source of randomness
    std::random_device r;
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
    std::mt19937 eng(seed);

    // create a function object that uses the distribution and source of randomness to
    //   produce values from 1 to 10
    auto rand = [&]{ return dist(eng) + 1; };

    std::vector<int> x;

    // store 1000 random values
    for (int i=0;i<1000;++i)
        x.push_back(rand());

    // count how many of each value, to verify that 3 comes out ~200 times and 7 comes
    //   out ~300 times
    for (int i=1;i<=10;++i)
        std::cout << i << ": " << count(begin(x),end(x),i) << '\n';

    // print all the values
    copy(begin(x),end(x),std::ostream_iterator<int>(std::cout, " "));
}
bames53
  • 86,085
  • 15
  • 179
  • 244