根据分布生成一组随机整数列表

1 投票
2 回答
684 浏览
提问于 2025-04-16 03:00

我希望我能把这个解释得清楚,如果没解释好,我会再试一次。

我想生成一个包含5个随机数字的数组,这些数字加起来要等于10,并且这些数字的范围是在[0,2n/m]之间。

我正在使用numpy这个库。

到目前为止,我写的代码是这样的:

import numpy as np

n=10
m=5
#interval that numbers are generated on
randNumbers= np.random.uniform(0,np.divide(np.multiply(2.0,n),fronts),fronts)
#Here I normalize the random numbers
normNumbers = np.divide(randNumbers,np.sum(randNumbers))
#Next I multiply the normalized numbers by n
newList = np.multiply(normNumbers,n)
#Round the numbers two whole numbers
finalList = np.around(newList)

这段代码大部分情况下是有效的,但有个问题就是结果的四舍五入不太准确,最后加起来会是9或者11,而不是10。有没有办法可以让我实现这个目标,而不用担心四舍五入的错误,或者有没有什么方法可以解决这个问题?如果你希望我解释得更清楚,我可以的,因为我在口头上解释的时候有点困难 :)。

2 个回答

1

只需要用上面的方法生成四个数字,然后把这四个数字加起来,再用10减去这个和,就可以得到最后一个数字。

1

这个代码会生成所有加起来等于10的可能组合,并随机选择其中一个。

from itertools import product
from random import choice
n=10
m=5
finalList = choice([x for x in product(*[range(2*n/m+1)]*m) if sum(x) == 10])

可能有更有效的方法,但这个方法在结果之间选择是比较公平的。

我们来看看当n=10和m=5时,这个过程是怎么工作的。

2*n/m+1 = 5,所以这个表达式变成了

finalList = choice([x for x in product(*[range(5)]*5) if sum(x) == 10])

`*[range(5)]*5` 是在使用参数解包。这相当于

finalList = choice([x for x in product(range(5),range(5),range(5),range(5),range(5)) if sum(x) == 10])

product() 会给出参数的笛卡尔积,在这个例子中有5的5次方个元素,但我们会过滤掉那些加起来不等于10的组合,最后留下381个值。

choice() 用来从结果列表中随机选择一个值。

撰写回答