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

时间:2017-07-11 15:49:23

标签: python random

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

我希望在1442,000之间随机生成91,000个数字,我希望这些数字的平均值为60,000

我知道如何使用random来生成整数:

random.randint(42000, 91000)

我可以把它放在for循环中,但是,如何将它们的均值调整为60,000

2 个答案:

答案 0 :(得分:1)

有很多方法可以在两个值和特定均值之间生成随机数。 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 distribution examples

beta版本的平均值为alpha/(alpha+beta),结果总是在0到1之间,因此要将其扩展到您的用例,请在此函数中将其包装起来:

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会改变分布的形状而不改变平均值;它将改变分布的中位数,模式,方差和其他属性。

您可以在函数中包含其他发行版以适合您的用例,但我猜测上述两个版本将适合您想要的任何用例。

这些也会产生浮点数,所以如果你想要整数,你必须通过编辑函数或者在调用函数后明确地将它们强制转换为整数。

答案 1 :(得分:1)

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(如果您不知道如何,请询问另一个问题!)。使用这个其他随机数生成器将提高终止的机会。

提高终止机会并因此找到结果的第二种方法是用较小的块构建结果,每个块都有所希望的意思:用我提出的方法创建5000块20个元素。

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