Python: генерирует n случайных целых чисел между двумя значениями, суммируя до заданного числа - PullRequest
0 голосов
/ 27 декабря 2018

Я бы очень хотел сгенерировать n случайных целых чисел между двумя значениями (min, max), сумма которых равна заданному числу m.

Примечание: я нашел похожие вопросы в stackoverflow, однако они делаютне решить именно эту проблему (использование функции Дирихле и, следовательно, чисел от 0 до 1).

Пример: мне нужно 8 случайных чисел (целых) между 0 и 24, где сумма 8 сгенерированных чисел должна быть равна 24.

Любая помощь приветствуется.Спасибо.

Ответы [ 3 ]

0 голосов
/ 27 декабря 2018

Ну, вы можете использовать целочисленное распределение, которое естественно суммирует с некоторым фиксированным числом - Полиномиальный один.

Просто сдвигайте вперед и назад, и он должен работать автоматически

Код

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)
0 голосов
/ 27 декабря 2018

это случай теории номеров разделов .вот решение.

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 это довольно медленно, так как это дает все случаи для этого размера раздела.

0 голосов
/ 27 декабря 2018

Это одно из возможных решений, основанное на этом ответе.Похоже, что метод 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]
...