Отредактировано :
Не глядя слишком много, я должен догадаться, что алгоритм должен быть ограничен O(n!/(n-r)!)
, где n := len(interables)
, поскольку это - то, сколько существует различных перестановок. https://en.wikipedia.org/wiki/Permutation#k-permutations_of_n. Максимум, когда r == n
, это дает O(n!)
Глядя на другую реализацию перестановки, я получаю сложность времени O(n^r)
, которая составляет самое большее O(n^n)
, когда r == n
Полагаю, вы получили реализацию Python от https://github.com/python/cpython/blob/3.8/Doc/library/itertools.rst? Я получил свой результат, посмотрев на вторую / более простую реализацию на этой странице, скопированную ниже:
def permutations(iterable, r=None):
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
for indices in product(range(n), repeat=r):
if len(set(indices)) == r:
yield tuple(pool[i] for i in indices)
Существует один цикл for
, поэтому сложность будет примерно на порядок, сколько раз вы имеетециклproduct
вернет генератор, который выдаст n^r
элементов на основе заданных параметров.
Это неоптимально, так как он вычисляет перестановки с заменами и использует if
для фильтрации, чтобы получить перестановки без замен,Вот откуда взялся подход O(n^r)
.
Примечание: itertools фактически реализован в C, поэтому он может использовать алгоритм, отличный от того, что описан в Python, и, следовательно, это может неточно отражать действительную сложность itertools.permutation
.
Также из-за генераторов и ленивых вычислений ваша программа не сталкивается с трудоемкостью сразу при вызове функции перестановки.