mannaro
@mannaro
Умею профессионально гуглить

Как быстро выбрать все сочетания из массива (комбинаторика)?

День добрый! Стандартная задача. Есть массив [1,2,3], есть n = 2. Нужно выбрать все сочетания из массива по n. То есть должны получить: [[1,2], [1,3], [2, 3]].
Можно, конечно, пройтись циклом в цикле, но при увеличении размера массива и n вычисления будут выполняться слишком долго ввиду большого количества (> 66%) отсева ненужных сочетаний.

Таки вопрос, как грамотно это реализовать?
  • Вопрос задан
  • 2384 просмотра
Решения вопроса 2
> [(i, j) for i in range(1, 4) for j in range(i + 1, 4)]
[(1, 2), (1, 3), (2, 3)]


Более общий код, но на хаскеле.
Идея такая:
Для каждого элемента списка получаем n-1 сочетания из всех, что идут после него, и добавляем сам элемент.
comb ∷ Int → [a] → [[a]]
comb 0 _ = [[]] -- из нуля элементов можно составить только пустой список
comb n [] = [] -- из пустого списка нельзя составить ничего
comb n lst = do -- списочная монада, работает как вложенные for
	-- tails для [1,2,3] вернёт [[1,2,3], [2,3], [3], []], т.е. все возможные хвосты
	-- мы перебираем все хвосты, кроме последнего пустого
	-- и дербаним его на голову l и остаток ls
	(l:ls) ← filter (not ∘ null) $ tails lst
	-- перебираем сочетания из n - 1 элементов от ls
	ls' ← comb (n - 1) ls
	-- и присобачиваем l к каждому
	return (l:ls')
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@deliro
Хватит костылить тут.
>>> from itertools import combinations
>>> combinations([1, 2, 3], 2)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы