Search code examples
randomgame-maker

Weighted random number (without predefined values!)


currently I'm needing a function which gives a weighted, random number. It should chose a random number between two doubles/integers (for example 4 and 8) while the value in the middle (6) will occur on average, about twice as often than the limiter values 4 and 8. If this were only about integers, I could predefine the values with variables and custom probabilities, but I need the function to give a double with at least 2 digits (meaning thousands of different numbers)!

The environment I use, is the "Game Maker" which provides all sorts of basic random-generators, but not weighted ones.

Could anyone possibly lead my in the right direction how to achieve this?

Thanks in advance!


Solution

  • The sum of two independent continuous uniform(0,1)'s, U1 and U2, has a continuous symmetrical triangle distribution between 0 and 2. The distribution has its peak at 1 and tapers to zero at either end. We can easily translate that to a range of (4,8) via scaling by 2 and adding 4, i.e., 4 + 2*(U1 + U2).

    However, you don't want a height of zero at the endpoints, you want half the peak's height. In other words, you want a triangle sitting on a rectangular base (i.e., uniform), with height h at the endpoints and height 2h in the middle. That makes life easy, because the triangle must have a peak of height h above the rectangular base, and a triangle with height h has half the area of a rectangle with the same base and height h. It follows that 2/3 of your probability is in the base, 1/3 is in the triangle.

    Combining the elements above leads to the following pseudocode algorithm. If rnd() is a function call that returns continuous uniform(0,1) random numbers:

    define makeValue()
       if rnd() <= 2/3    # Caution, may want to use 2.0/3.0 for many languages
          return 4 + (4 * rnd())
       else
          return 4 + (2 * (rnd() + rnd()))
    

    I cranked out a million values using that and plotted a histogram:

    House-shaped distribution