繁体   English   中英

在Python中使用给定间隔和均值的随机数生成器,而不是C#

[英]Random Number Generator with given Interval and Mean in Python not C#

我正在将Python 2.7.12Anaconda 4.2.0 (64-bit) 尝试使用随机包生成随机数。 我需要在一个interval内生成n数字,其均值应为specified value 例如:

我希望14随机生成的数字介于42,00091,000之间,并且我希望这些数字的平均值为60,000

我知道如何使用随机产生整数:

random.randint(42000, 91000)

我可以将其置于for循环中,但是,如何将其均值调整为60,000呢?

有很多方法可以在两个值和特定平均值之间生成随机数。 Python为这些方式中的某些方式内置了方法,但是当我说有很多方式时,我是说真的。

最简单的方法是使用三角分布。 random.triangular(low, high, mode)将以指定的模式从低和高之间的分布中产生一个数字。 这可能已经足够了,但是如果您真的想要一个平均值,可以使用以下函数:

def triangular_mean(low, high, mean):
    mode = 3 * mean - low - high
    return random.triangular(low, high, mode)

如果您想变得更复杂,可以通过调用random.beta(alpha,beta)来使用beta分布。 这些真的很灵活而且很奇怪。 这张来自Wikipedia的图片突显了它们的奇怪之处。 Beta发行示例

Beta分布的平均值是alpha/(alpha+beta) ,结果始终在零到一之间,因此,为了将其扩展到您的用例,让我们将其包装在以下函数中:

def beta_mean(low, high, mean, alpha):
    offset = low
    scale = high - low
    true_mean = (mean - offset)/scale
    beta = (alpha/true_mean) - alpha
    return offset + scale * random.beta(alpha, beta)

在上面的函数中,alpha将更改分布的形状而不会更改均值; 它将更改中位数,众数,方差和分布的其他属性。

您可以包装其他分布以适合您的用例的函数,但是我猜测以上两种将适合您想要的任何用例。

它们还会产生浮点数,因此,如果要整数,则必须将其转换为整数,方法是编辑函数或在调用它们后显式转换它们。

while True:  # until a good sample was found
  s = [ random.randint(42000, 91000) for _ in range(13) ]
  v = 60000 + (60000 - (sum(s) / len(s))) * 13
  if 42000 <= v <= 91000:
    s.append(v)
    break
print sum(s) / len(s)  # will print 60000

这会从标准生成器中创建13个随机值,并计算出第14个值,以使平均值恰好为60000。由于第14个值可能不在给定范围内,因此会反复尝试此操作,直到可能出现第14个有效值为止。

这既不优雅也不好。 但是问题也是。

编辑:

这种方法适用于给定的数字,但是由于它正在重试,因此可能会无限期地运行于不同的数字(例如,范围= [42k,91k],均值= 60k,计数= 100k)。

如果您随机创建99999个元素,则它们的均值将约为(42k + 91k)/ 2,并且用于将其平衡回60k的单个元素将不够用(因此始终超出范围)。 您可以使用稍微复杂一些的随机数生成器,生成42k和91k之间的随机数,平均数为60k(如果您不知道该问题,请询问另一个问题!)。 使用此其他随机数生成器将提高终止的机会。

提高终止机会并找到结果的第二种方法是从较小的块构建结果,每个较小的块具有期望的平均值:用我介绍的方法创建20个元素的5000个块。

当然,您可以结合使用这两种方法。

暂无
暂无

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

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