разделить общую сумму K способов комбинаторика питона - PullRequest
2 голосов
/ 09 мая 2019

У меня есть общее количество плотности N. Мне нужно найти все способы, которыми я могу разделить эту плотность на k групп, предполагая некоторую минимально делимую часть d.

Итак, если N = 4, k =3, d = 1, мне нужно:

[
    (1, 1, 2),
    (1, 2, 1),
    (2, 1, 1),
]

Если N = 5, k = 3, d = 1:

[
    (1, 1, 3),
    (1, 3, 1),
    (3, 1, 1),
    (1, 2, 2),
    (2, 1, 2),
    (2, 2, 1),
]

Такое ощущение, что это должно соответствовать некоторой базовой проблеме комбинаторики, но я не могу думать об этом. Этот пост ссылается на очень похожую операцию в R, но не на python.

Один наивный способ сделать это - отфильтровать результат itertools.product только для кортежей, которые суммируются с N, но это выглядит не элегантно:

import itertools


def compositions(N, k, d=1):
    for seq in itertools.product(*[range(d, N, d)] * k):
        if sum(seq) == N:
            yield seq

Пример

>>> list(compositions(7, 3))
[(1, 1, 5),
 (1, 2, 4),
 (1, 3, 3),
 (1, 4, 2),
 (1, 5, 1),
 (2, 1, 4),
 (2, 2, 3),
 (2, 3, 2),
 (2, 4, 1),
 (3, 1, 3),
 (3, 2, 2),
 (3, 3, 1),
 (4, 1, 2),
 (4, 2, 1),
 (5, 1, 1)]

Есть еще идеи?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...