Выше, строго говоря, будет работать.Но для 15 чисел от 0 до 6 вероятность генерации 12 не так велика.Фактически мы можем рассчитать количество возможностей с помощью:
F (s, 1) = 1 для 0≤s≤6 и
F (s, n) = Σ 6 i = 0 F (si, n-1) .
Мы можем рассчитать это с помощьюзначение:
from functools import lru_cache
@lru_cache()
def f(s, n, mn, mx):
if n < 1:
return 0
if n == 1:
return int(mn <= s <= mx)
else:
if s < mn:
return 0
return sum(f(s-i, n-1, mn, mx) for i in range(mn, mx+1))
Это означает, что существует 9'483'280 возможностей из 4'747'561'509'943 общих возможностей для генерации суммы 12, или 0,00019975%.Таким образом, потребуется около 500 624 итераций, чтобы найти такое решение.
Поэтому мы должны лучше стремиться найти прямой способ генерации такой последовательности.Мы можем делать это каждый раз, вычисляя вероятность генерации числа: вероятность генерации i в качестве числа в качестве первого числа в последовательности n чисел, которые суммируют до s - F (si, n-1, 0, 6) / F (s, n, 0, 6) .Это будет гарантировать, что мы сгенерируем единый список по списку возможностей. Если мы будем каждый раз рисовать одинаковое число, то оно не будет соответствовать равномерному распределению по всему списку значений, соответствующих данному условию:
Мы можем сделать это рекурсивно с помощью:
from numpy import choice
def sumseq(n, s, mn, mx):
if n > 1:
den = f(s, n, mn, mx)
val, = choice(
range(mn, mx+1),
1,
p=[f(s-i, n-1, mn, mx)/den for i in range(mn, mx+1)]
)
yield val
yield from sumseq(n-1, s-val, mn, mx)
elif n > 0:
yield s
С помощью вышеуказанной функции мы можем сгенерировать массивы numpy:
>>> np.array(list(sumseq(15, 12, 0, 6)))
array([0, 0, 0, 0, 0, 4, 0, 3, 0, 1, 0, 0, 1, 2, 1])
>>> np.array(list(sumseq(15, 12, 0, 6)))
array([0, 0, 1, 0, 0, 1, 4, 1, 0, 0, 2, 1, 0, 0, 2])
>>> np.array(list(sumseq(15, 12, 0, 6)))
array([0, 1, 0, 0, 2, 0, 3, 1, 3, 0, 1, 0, 0, 0, 1])
>>> np.array(list(sumseq(15, 12, 0, 6)))
array([5, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1])
>>> np.array(list(sumseq(15, 12, 0, 6)))
array([0, 0, 0, 0, 4, 2, 3, 0, 0, 0, 0, 0, 3, 0, 0])