生成随机数以获得固定总和(python)

时间:2018-04-05 07:40:43

标签: python list numpy random

我有以下列表:

Sum=[54,1536,36,14,9,360]

我需要生成4个其他列表,其中每个列表将包含从0开始的6个随机数,并且这些数字将总和加起来。例如;

l1=[a,b,c,d,e,f] where a+b+c+d+e+f=54
l2=[g,h,i,j,k,l] where g+h+i+j+k+l=1536

依此类推至l6。我需要在python中执行此操作。可以吗?

2 个答案:

答案 0 :(得分:4)

这可能不是最有效的方法,但它会起作用

totals = [54, 1536, 36, 14]

nums = []
x = np.random.randint(0, i, size=(6,))
for i in totals:
    while sum(x) != i: x = np.random.randint(0, i, size=(6,))
    nums.append(x)
print(nums)
  

[array([3,19,21,11,0,0]),array([111,155,224,511,457,   78]),数组([8,5,4,12,2,5]),数组([3,1,3,2,1,4])]

这是一种更有效的方法

总计= [54,1536,36,14,9,360,0]

nums = []
for i in totals:
    if i == 0: 
        nums.append([0 for i in range(6)])
        continue
    total = i
    temp = []
    for i in range(5):
        val = np.random.randint(0, total)
        temp.append(val)
        total -= val
    temp.append(total)
    nums.append(temp)

print(nums)
  

[[22,4,16,0,2,10],[775,49,255,112,185,160],[2,10,18,2,   0,4],[10,2,1,0,0,1],[8,0,0,0,0,1],[330,26,1,0,2,1],   [0,0,0,0,0,0]]

答案 1 :(得分:2)

生成总和为某个整数的随机数列表是一项非常困难的任务。跟踪剩余数量并按剩余可用数量顺序生成项目会导致非均匀分布,其中系列中的第一个数字通常比其他数字大得多。最重要的是,最后一个将始终与零不同,因为列表中的前一项永远不会总和到所需的总数(随机生成器通常使用最大的开放时间间隔)。在生成后对列表进行混洗可能会有所帮助,但通常也不会产生良好的结果。

解决方案可能是生成随机数,然后对结果进行标准化,如果需要整数,最终将其舍入。

import numpy as np
totals = np.array([54,1536,36,14])  # don't use Sum because sum is a reserved keyword and it's confusing

a = np.random.random((6, 4))  # create random numbers
a = a/np.sum(a, axis=0) * totals  # force them to sum to totals

# Ignore the following if you don't need integers
a = np.round(a)  # transform them into integers
remainings = totals - np.sum(a, axis=0)  # check if there are corrections to be done
for j, r in enumerate(remainings):  # implement the correction
    step = 1 if r > 0 else -1
    while r != 0:
        i = np.random.randint(6)
        if a[i,j] + step >= 0:
            a[i, j] += step
            r -= step

a的每一列代表您想要的其中一个列表。 希望这会有所帮助。