Упрощение большой сложности этого экспоненциального алгоритма

У меня есть алгоритм подсчета, для которого я пытаюсь получить общее описание big-o. Он ужасно вложен и ужасно экспоненциален. Вот:

 1. For each T_i in T
 2. For k = 1 to max_k
 3. For each of 2^k*(n choose k) items
 4. For each t in T_i
 5. check if the item is in t...etc.

Вот построчное представление каждого времени выполнения

  1. Это простое разбиение, и я просто дам ему константу c1.
  2. max_k — небольшое число, всегда меньше n, возможно, около 4 или 5. Ниже я буду использовать k.
  3. Этот цикл всегда выполняется 2^k*(n выбирает k) раз
  4. Считая строку 1 константой, мы можем обобщить эту строку и знать, что в худшем случае она никогда не будет срабатывать более 2^n раз, но обычно будет выполняться часть 2^n раз, поэтому мы назовем ее (2^ п)/с2
  5. Это простая операция оператора if внутри всех этих циклов, поэтому c3.

Умножение всего этого вместе дает:

c1 * k * 2^k * (n choose k) * (2^n)/c2 * c3

Поскольку мне нужно представление большого O, игнорирование констант дает:

k * 2^k * (n choose k) * (2^n)

Известно, что (n выбирает k) ограничено сверху (n * e/k)^k, поэтому:

O(k * 2^k * (n * e / k)^k * (2^n))

Мой вопрос в том, что я могу здесь игнорировать... 2 ^ n, безусловно, является доминирующим термином, поскольку n всегда больше, чем k, и обычно намного больше. Можно ли упростить это до O (2 ^ n)? Или О(2^ужасно)? Или я должен оставить в 2 ^ k, как в O (2 ^ k * 2 ^ n)? (или оставить все термины?)

Насколько я понимаю, если k или max_k могут составить конкуренцию или превзойти n, то они жизненно необходимы. Но поскольку над ними всегда доминируют, можно ли их отбросить, как члены более низкого порядка полиномиального времени выполнения? Я полагаю, что весь экспоненциальный беспорядок времени работы сбивает меня с толку. Любые советы высоко ценится.


person Mike V    schedule 03.07.2012    source источник


Ответы (1)


Насколько я понимаю, если k или max_k могут составить конкуренцию или превзойти n, то они жизненно необходимы

Верно, но наоборот - это означает, что его нельзя игнорировать, когда дело доходит до большой нотации O, даже если она не конкурирует с n. Его можно игнорировать, только если max_k ограничено константой (существует константа c такая, что k <= c). Например, алгоритмы O(n * logk) не являются O(n), поскольку коэффициент k не ограничен и, следовательно, существует k такое, что nlogk > c*n для каждой константы c.

Поскольку выражение, которое вы получили, является продуктом, все, что вы можете игнорировать, это константы, что в вашем случае - только e дает вам O(k*2^k * (n/k)^k * 2^n).

Если k ограничено, то вы можете удалить его из выражения и в большой нотации O, и вы получите O(n^k* 2^n). Обратите внимание, что даже в этом случае, несмотря на n^k << 2^n, его все же нельзя игнорировать, потому что для каждой константы c существует некоторое n такое, что c*2^n < n^k *2^n, поэтому алгоритм не является O(2^n).

Меньшие факторы можно игнорировать, когда дело доходит до сложения. Если k < n, то O(n + k) = O(n), потому что есть константа c,N такая, что для всех n > N: c*n < n + k, но это, конечно, неверно при работе с продуктом.

person amit    schedule 03.07.2012
comment
Если верно, что n всегда больше k, достаточно ли этого для ограничения k и, следовательно, его удаления? Я думаю, это то, что вы говорите, но я хочу быть уверен. Ваш пример с n*lg(k) вполне ясен — спасибо за это. - person Mike V; 03.07.2012
comment
@Chucktown: If it is true that n is always greater than k, is that sufficient for bounding k and thus removing it? Нет. Когда мы говорим k is bounded, мы имеем в виду, что существует КОНСТАНТ c, такой что k < c. Я отредактирую, чтобы уточнить это. - person amit; 03.07.2012
comment
@amit: Отлично - спасибо за разъяснения. Итак, поскольку я изобретатель этого алгоритма, если я утверждаю, что k никогда не может быть больше, чем, скажем, 20, то теперь у меня есть мое c, таким образом ограничивая k константой, а не n, таким образом, получая мою более простую введите время выполнения. Согласны ли вы с этим? - person Mike V; 03.07.2012
comment
@Чактаун: Да. Если вы знаете, что k гарантированно меньше 20 (или любой другой константы), то вы получите: k*2^k * (n/k)^k * 2^n <= 20 * 2^20 * (n/20)^20 * 2^n, которое находится в O(n^20 * 2^n). Обратите внимание, что единственный k, который не игнорируется, находится в показателе степени, поскольку он влияет на (n/k)^k. - person amit; 03.07.2012
comment
@amit: Ваши ответы потрясающие. Спасибо за ваш вклад здесь, и, судя по вашей репутации, в миллионе других мест. - person Mike V; 03.07.2012