Weighted random number (without predefined values!)

泄露秘密 提交于 2019-12-23 04:48:09

问题


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!


回答1:


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:




回答2:


For the case someone needs this in Game Maker (or a different language ) as an universal function:

if random(1) <= argument0
   return argument1 + ((argument2-argument1) * random(1))
else
   return argument1 + (((argument2-argument1)/2) * (random(1) + random(1)))

Called as follows (similar to the standard random_range function):

val = weight_random_range(FACTOR, FROM, TO)

"FACTOR" determines how much of the whole probability figure is the "base" for constant probability. E.g. 2/3 for the figure above. 0 will provide a perfect triangle and 1 a rectangle (no weightning).



来源:https://stackoverflow.com/questions/29915888/weighted-random-number-without-predefined-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!