Сложность времени
Сложность времени можно суммировать до следующего отношения повторения:
T(n) = n * T(n-1) + n * 2^(n-1)
, так как существует основнаяцикл выполняется n
раз, и каждый раз подмножества оставшихся элементов (n-1
) сначала генерируются (T(n-1)
) и , а затем повторяются (2^(n-1)
) .
примечание отношение предполагает, что любая другая операция в цикле занимает постоянное время , что является разумным приближением, поскольку ее эффекты по мере роста n
минимальны.Например, эта операция:
if subset not in set
не не требует постоянного времени (это занимает линейное время в длине списка, также set.append(subset)
не является постоянным временем в целом), но позволяет пропуститьэто пока (вы понимаете, как анализировать код).
Отношение рекуррентности предполагает сложность , по крайней мере, экспоненциальную .
Пространственная сложность
Прежде всего генерируются все подмножества n
, это означает, по крайней мере, сложность O(2^n)
.Однако из-за рекурсии и повторной генерации подмножеств на каждом шаге сложность пространства больше, чем это.В частности, на каждом шаге цикла генерируется одна текущая копия подмножеств n-1
, а затем увеличивается до исходных подмножеств.У нас есть:
S(n) = S(n-1) + 2^n
, так как каждый вызов подмножества создает 1
промежуточную текущую копию оставшихся подмножеств (т. Е. S(n-1)
) плюс это объединяет те в исходные подмножества, которые 2^n
.
примечание мы не учитываем объем памяти, необходимый для хранения каждого элемента набора подмножеств, который сам требует хранениясложности около O(n)
, но для простоты считаем, что это постоянное хранилище O(1)
(например, для сохранения подмножества в виде слова, в двоичном кодировании, для небольшого n <= 64
), поэтому все хранилище подмножеств (безсчитая вспомогательное хранилище) будет просто иметь сложность O(2^n)
(иначе, как отмечено в комментарии, сложность хранилища для простого хранения всех подмножеств n
имеет порядок O(n 2^n)
).
Отношение рекуррентности предполагаетсложность , по крайней мере, экспоненциальная .
Решение
Поскольку основная теорема не может быть применена для этих рекуррентных соотношений (так какнотаd) проверить методы решения рекуррентных отношений первого порядка с переменными коэффициентами , чтобы решить вышеуказанные отношения (сложность пространства подобна арифметической прогрессии, в то время как сложность времени имеет более сложную форму) и приобрести точную форму сложности(хотя решение может быть очень сложным, и оно все равно будет экспоненциальным в одну или другую сторону)
Лучшая сложность
Лучшая сложность времени и пространства может бытьдостигается путем использования структуры и свойств подмножеств (с учетом определенного порядка, например, лексикография ).
В частности, тесные отношения, которые уже созданное подмножество имеет к своему предшественнику и преемнику.Таким образом, преемник (следующее подмножество в последовательности) может быть сгенерировано с минимальными изменениями, внесенными в его предшественник (например, добавление или удаление только одного элемента).
Например, код генерирует много дубликатов , которые он затем проверяет, если они уже существуют, этого можно избежать все вместе.Кроме того, рекурсия не нужна, поэтому временная и пространственная сложность рекурсии может быть устранена.Кроме того, требуется только постоянное хранилище внутри основного цикла (учитывая, что следующее подмножество может быть сгенерировано только с минимальным постоянным количеством изменений, внесенных в предыдущее подмножество) и так далее.Все эти оптимизации так или иначе эксплуатируют симметрии и свойства подмножеств в определенном порядке.
PS.Вы также можете исследовать подобные вопросы на computer.science.stackexchange , который более полно связан с алгоритмической сложностью