按给定比例随机生成数字
我需要在一个给定的正区间(a,b)上生成数字,并且这些数字要符合指数分布。通过反累积分布函数方法,我做了一个生成指数分布数字的程序。但是,这个生成的数字是一个正数,而我希望它能落在我指定的区间内。我该怎么做才能只在这个区间内生成数字呢?
下面是使用反累积分布函数方法生成指数分布数字的代码,使用的是Python:
u = random.uniform(0,1)
return (-1/L)*math.log(u)
其中L是一个给定的正参数。
提前谢谢你!
1 个回答
一个结果 x 的概率通常是 L 乘以 exp(-Lx)。不过,当我们只关注区间 [a,b] 时,x 在这个区间内的概率会被放大,放大的程度是根据在 a 和 b 之间的累积分布函数(CDF)所占的比例来计算的:从 a 到 b 的积分是 L 乘以 exp(-Lt) 的积分,结果是 -(exp(-Lb) - exp(-La))。
因此,x 的概率密度函数(pdf)可以表示为:
L 乘以 exp(-Lx) 除以 (exp(-La) - exp(-Lb)),
这意味着在 x 的累积分布函数(cdf)为:
从 a 到 x 的积分 [ L 乘以 exp(-Lt) 除以 (exp(-La) - exp(-Lb)) ] dt
= [-exp(-Lx) + exp(-La)] / [exp(-La) - exp(-Lb)] = u
现在我们进行反转:
exp(-Lx) = exp(-La) - u [exp(-La) - exp(-Lb)]
-Lx = -La + log( 1 - u [1 - exp(-Lb)/exp(-La)])
x = a + (-1/L) log( 1 - u [1 - exp(-Lb)/exp(-La)])
这段代码如下:
u = random.uniform(0,1)
return a + (-1/L)*math.log( 1 - u*(1 - math.exp(-L*b)/math.exp(-L*a)) )
需要注意的是:如果 L 或 a 很大,math.exp(-L*a)
会变成 0,这样会导致 ZeroDivisionError
错误。