首先了解我的情况:
我需要一个随机的三角形分布,并且正在计划使用Python的random.triangular。以下是源代码(Python 3.6.2):
def triangular(self, low=0.0, high=1.0, mode=None):
"""Triangular distribution.
Continuous distribution bounded by given lower and upper limits,
and having a given mode value in-between.
http://en.wikipedia.org/wiki/Triangular_distribution
"""
u = self.random()
try:
c = 0.5 if mode is None else (mode - low) / (high - low)
except ZeroDivisionError:
return low
if u > c:
u = 1.0 - u
c = 1.0 - c
low, high = high, low
return low + (high - low) * (u * c) ** 0.5
我查看了所引用的Wiki页面,发现我想要的用途有一种特殊情况,可以简化事情,并且可以使用以下功能实现:
def random_absolute_difference():
return abs(random.random() - random.random())
进行一些快速计时可以发现简化版本可以显着提高速度(每次运行我的代码时,此操作将重复执行一百万次以上):
>>> import timeit
>>> timeit.Timer('random.triangular(mode=0)','import random').timeit()
0.5533245000001443
>>> timeit.Timer('abs(random.random()-random.random())','import random').timeit()
0.16867640000009487
现在来看一个问题:我知道python的random模块仅使用伪随机性,random.triangular使用一个随机数,而特例代码使用2个随机数。特殊情况下的结果是否会因为使用2个连续的random调用而random.triangular仅使用1个连续调用而显着降低随机性?使用简化代码还有其他无法预料的副作用吗?
编辑:参考此解决方案的另一个问题,我为两个分布创建了直方图,显示了它们的可比性:
您的情况可triangular
归结为以下表达式:
1 + (0 - 1) * ((1.0 - u) * (1.0 - c)) ** 0.5
然后进一步:
1 - 1 * ((1.0 - u) * 1.0) ** 0.5
然后进一步:
1 - (1.0 - u) ** 0.5
And with my timings, this last expression runs much faster than random.triangular(mode=0)
and has comparable speed to abs(random.random()-random.random())
. Note that triangular
contains a try/except statement, which may explain some of the performance difference (for example, replace that statement with just "mode = 0" and see).
import timeit
timeit.Timer('random.triangular(mode=0)','import random').timeit()
timeit.Timer('1 - (1.0 - random.random()) ** 0.5','import random').timeit()
timeit.Timer('abs(random.random()-random.random())','import random').timeit()
但是,我看不出为什么使用两个随机数而不是一个会产生“较少随机”的三角形分布数的原因-只要两种方法产生的分布相同。实际上,使用两个随机数会比仅使用一个随机数给您更多的三角分布数,因为有更多的随机性可用于此目的。(如果您要测试这两种方法的正确性,则可以使用Kolmogorov–Smirnov检验以及三角形分布的CDF,因为三角形分布是连续的。例如,在SciPy scipy.stats.kstest
。如果多次测试返回的p值非常接近0,则表明该数字来自错误的分布。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句