Python:生成两个值之间的n个随机整数,这些数字加起来等于给定数字

时间:2018-12-26 21:14:06

标签: python random integer

我非常想在两个等于和等于给定数m的值(最小值,最大值)之间生成n个随机整数。

注意:我在stackoverflow中发现了类似的问题,但是它们并不能完全解决这个问题(使用dirichlet函数,因此数字介于0和1之间)。

示例:我需要在0到24之间的8个随机数(整数),其中8个生成的数字之和必须等于24。

感谢您的帮助。谢谢。

3 个答案:

答案 0 :(得分:1)

这是partition number theory的情况。这是解决方案。

def partition(n,k,l, m):
    if k < 1:
        raise StopIteration
    if k == 1:
        if n <= m and n>=l :
            yield (n,)
        raise StopIteration
    for i in range(l,m+1):
        for result in partition(n-i,k-1,i,m):                
            yield result+(i,)

n = 24 # sum value
k = 8 # partition size
l = 0 # range min value
m = 24 # range high value 

result = list(partition(n,k,l,m ))

这将提供满足条件的所有组合。 ps,这非常慢,因为这给出了该分区大小的所有情况。

答案 1 :(得分:0)

这是一个基于this答案的可能解决方案。看来dirichlet方法仅在0到1之间起作用。应该完全考虑原始答案。一旦您评论它已达到目的,我将很乐意将其删除。

别忘了对原始答案进行投票。

target = 24

x = np.random.randint(0, target, size=(8,))
while sum(x) != target: 
    x = np.random.randint(0, target, size=(8,))

print(x)
# [3 7 0 6 7 0 0 1]

答案 2 :(得分:0)

好吧,您可以使用整数分布,它自然会求和成某个固定数字-Multinomial一个。

来回移动,它应该会自动工作

代码

import numpy as np

def multiSum(n, p, maxv):
    while True:
        v  = np.random.multinomial(n, p, size=1)
        q  = v[0]
        a,  = np.where(q > maxv) # are there any values above max
        if len(a) == 0: # accept only samples below or equal to maxv
            return q

N = 8
S = 24
p = np.full((N), 1.0/np.float64(N))

mean  = S / N
start = 0
stop  = 24
n = N*mean - N*start

h = np.zeros((stop-start), dtype=np.int64)
print(h)
for k in range(0, 10000):
    ns = multiSum(n, p, stop-start) + start # result in [0...24]
    #print(np.sum(ns))
    for v in ns:
        h[v-start] += 1

print(h)