我非常想在两个等于和等于给定数m的值(最小值,最大值)之间生成n个随机整数。
注意:我在stackoverflow中发现了类似的问题,但是它们并不能完全解决这个问题(使用dirichlet函数,因此数字介于0和1之间)。
示例:我需要在0到24之间的8个随机数(整数),其中8个生成的数字之和必须等于24。
感谢您的帮助。谢谢。
答案 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)