繁体   English   中英

偏向该范围最小值的范围内的随机数

[英]Random number within a range biased towards the minimum value of that range

我想生成范围(1 - 100000)内的随机数,但不是纯粹随机的,我希望结果基于一种分布。 我的意思是,总的来说,我希望数字“聚集”在范围 (1) 的最小值附近。

我已经阅读了有关 Box–Muller 变换和正态分布的信息,但我不太确定如何使用它们来实现数字生成器。

如何使用 C# 实现这样的算法?

有很多方法可以做到这一点(使用统一分布prng),我知道的很少:

  1. 组合更均匀的随机变量以获得所需的分布。

    我不是数学专家,但肯定有这方面的方程式。 从随机性和统计的角度来看,这种解决方案通常具有最佳特性。 有关更多信息,请参阅著名的:

    但是我们知道组合的分布数量有限。

  2. 对均匀随机变量应用非线性 function

    这是最简单的实现。 您只需在<0..1>范围内使用浮动随机数在它们上应用您的非线性 function (将分布更改为您想要的形状)(而结果仍在<0..1>范围内)并将结果重新调整为例如,您的 integer 范围(在 C++ 中):

     floor( pow( random(),5 ) * 100000 )

    问题是这只是分布的盲目拟合,因此您通常需要稍微调整常量。 渲染直方图和随机图以直接查看结果质量是个好主意,如下所示:

    您还可以避免过于盲目地使用 BEZIERS,如下所示:

  3. 伪随机生成器之后的分布

    我知道有两种方法,更简单的是:

    1. 创建足够大的数组n
    2. 用分布后的所有值填充它

      因此,只需遍历您想要的所有值 output 并计算其中有多少将在n大小的数组中(来自您的分布)并将该数字的计数添加到数组中。 请注意,由于四舍五入,数组的填充大小可能略小于n 如果n太小,您将丢失一些较少出现的数字。 因此,如果您将最不可能数的概率乘以n它应该至少>=1 填充后将n更改为实际数组大小(其中实际填充数字的数量)。

    3. 打乱数组

    4. 现在使用数组作为随机数的线性列表

      因此,您只需从数组中选择一个数字并移至下一个,而不是random() 一旦你进入第n个值,重新排列数组并再次从第一个开始。


    该解决方案具有非常好的统计特性(精确地遵循分布),但随机特性不好,需要数组和偶尔的洗牌。 有关更多信息,请参阅:


    另一个变体是避免使用数组和改组。 它是这样的:

    1. 获取<0..1>范围内的随机值
    2. 应用逆累积分布 function 转换为目标范围

      如您所见,它就像#2 Apply non linear function...方法,但您直接使用分布而不是“一些”非线性 function。 因此,如果p(x)x<0..1>范围内的概率,其中1表示100% ,那么我们需要一个 function 来累积直到x的所有概率(抱歉,不知道英语中的确切数学术语)。 对于整数:

       f(x) = p(0)+p(1)+...+p(x)

      现在我们需要逆 function g()到它,所以:

       y = f(x) x = g(y)

      现在,如果我的 memory 对我有很好的帮助,那么这一代应该是这样的:

       y = random(); // <0..1> x = g(y); // probability -> value

      许多发行版都知道g() function 但对于那些不知道(或者我们懒得推导它)的发行版,您可以在p(x)上使用二进制搜索。 懒得写代码了,所以这里的线性搜索速度较慢:

       for (x=0;x<max;x++) if (f(x)>=y) break;

      所以当把所有东西放在一起(并且只使用p(x) )时,我得到了这个(C++):

       y=random(); // uniform distribution pseudo random value in range <0..1> for (f=0.0,x=0;x<max;x++) // loop x through all values { f+=p(x); // f(x) cumulative distribution function if (f>=y) break; } // here x is your pseudo random value following p(x) distribution

    这种解决方案通常具有非常好的统计和随机属性,并且不需要分布是连续的 function(它甚至可以只是一个值数组)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM