C# 返回范围(a,b)内指数分布的随机双精度函数

C# 返回范围(a,b)内指数分布的随机双精度函数,c#,distribution,exponential,C#,Distribution,Exponential,我想从a到b生成一个随机数。问题是,数字必须服从指数分布 这是我的密码: public double getDouble(double low, double high) { double r; (..some stuff..) r = rand.NextDouble(); if (r == 0) r += 0.00001; return (1 / -0.9)

我想从
a
b
生成一个随机数。问题是,数字必须服从指数分布

这是我的密码:

public double getDouble(double low, double high)
        {
            double r;
            (..some stuff..)
            r = rand.NextDouble();
            if (r == 0) r += 0.00001;
            return (1 / -0.9) * Math.Log(1 - r) * (high - low) + low;
        }

问题是(1/-0.9)*Math.Log(1-r)不在0和1之间,因此结果不会在
a
b
之间。有人能帮忙吗?提前谢谢

指数分布不局限于正值,因此值可以从0到inf。有很多方法可以将[0,无穷大]缩放到某个有限区间,但结果不会是指数分布。 如果你只想得到a和b之间指数分布的一部分,你可以简单地从[RaRb]中画出r,这样-log(1-ra)=a和-log(1-rb)=b,即

为什么要检查r==0?我想您应该检查log的参数是否大于0,所以检查r(或者在这种情况下是rbound int)==1。
也不清楚为什么(1/-.9)因子???

我误解了你在第一个答案中的问题:)你已经在使用反转采样了

要将一个范围映射到另一个范围,有一种典型的数学方法:

f(x) = (b-a)(x - min)/(max-min) + a
在哪里

(这是线性缩放,因此将保留分布)

(您可以验证:如果您为
x
输入
min
,它将导致
a
,如果您为
x
输入
max
,您将得到
b

现在的问题是:指数分布的最大值为
inf
。所以,你不能使用这个等式,因为它总是
无论什么/inf+0
-So
0
。(这在数学上是有道理的,但ofc不符合您的需要)

因此,唯一正确的答案是:两个固定数字之间不可能存在指数分布,因为您无法映射[0,inf]->[a,b]

因此,您需要某种权衡,以使结果尽可能呈指数级

出于好奇,我绞尽脑汁研究了各种可能性,发现在这方面,你这个简单的人比不上数学:p

然而,我用Excel和140万条随机记录做了一些测试: 我选择了一个随机数作为“限制”(10),并将计算结果四舍五入到小数点后1位。(0,0.1,0.2等等)这个数字我用来执行线性变换,最大值为10,输入任何大于1的结果

在140万次计算(生成10-20次)中,仅生成了7-10个大于1的随机数:

(映射值后的概率密度函数:第100列:=1,第0列:=0)

因此:

  • 使用上述线性方法,将值映射到
    [0,1]
    ,假设变换的最大值为10
  • 如果在转换后遇到大于1的值,只需绘制另一个随机数,直到该值小于1

  • 140万次测试中只有7-10次出现,这应该足够接近了,因为重新绘制的数字将再次呈伪指数分布

  • 如果你想建造一艘宇宙飞船,它的导航依赖于0到1之间的完美指数分布的数字——不要这样做,否则你应该做得很好
  • (如果你想欺骗一点:如果你遇到一个大于1的数字,只要找到与它的期望值差异最大的记录(即Max(出现次数<期望出现次数)),然后假设该值为:P)

由于对指数分布的支持是0到无穷大的,无论速率如何,我假设您要求的指数在
a
下方和
b
上方截断。另一种表达方式是指数随机变量
X
a为条件。这个问题可能更适合谢谢,这使问题对我来说非常清楚:)//范围为C的指数分布35;双ExpInRange(随机R,双a,双B,双速率=1.0){double ERA=Math.Exp(-Rate*a);return-Math.Log(ERA-R.NextDouble()*(ERA-Math.Exp(-Rate*B)))/Rate;}
f(x) = (b-a)(x - min)/(max-min) + a
b = upper bound of target
a = lower bound of target
min = lower bound of source
max = upper bound of source
x = the value to map
def exp_in_range(a, b, rate = 1.0)
  exp_rate_a = Math.exp(-rate * a)
  return -Math.log(exp_rate_a - rand * (exp_rate_a - Math.exp(-rate * b))) / rate
end