Я решаю вопрос об алгоритме, и мой анализ состоит в том, что он будет работать на O (2 ^ sqrt (n)). Насколько большой это? Это соответствует O (2 ^ n)? Это все еще неполиномиальное время?
Я решаю вопрос об алгоритме, и мой анализ состоит в том, что он будет работать на O (2 ^ sqrt (n)). Насколько большой это? Это соответствует O (2 ^ n)? Это все еще неполиномиальное время?
Ответы:
Это интересный вопрос. К счастью, если вы знаете, как решить эту проблему, это не особенно сложно.
Для функций F : N → R + и г : N → R + , мы имеем ф ∈ O ( г ) тогда и только тогда , когда Нт вир п → ∞ ф ( п ) / г ( п ) ∈ R .
Функция f : N → R + имеет не более чем полиномиальный рост тогда и только тогда, когда существует постоянная k ∈ N такая, что f ∈ O ( n ↦ n k ). Давайте работать это для произвольного , но фиксированного к ∈ N .
Пт вир п → ∞ 2 ( п 1/2 ) / п K =
Нт п → ∞ 2 ( п 1/2 ) / п K =
Нт п → ∞ е лог (2) п 1/2 / е лог ( п ) k =
lim n → ∞ e log (2) n 1/2 - log ( n ) k = ∞ ∉ R
Первое равенство верно, потому что и знаменатель, и знаменатель являются монотонно растущими устойчивыми функциями. Второе равенство использует тождество x y = e log ( x ) y . Предел не является конечным, поскольку показатель степени в конечном выражении не ограничен выше. Не давая формальное доказательство, то можно предположить , что будет известно , что п 1/2 доминирует журнал ( п ) асимптотически. Следовательно, рассматриваемая функция превышает полиномиальный рост.
Однако его рост строго меньше экспоненциального, где экспонента определяется (для меня, для этой цели) как O ( n ↦ 2 c n ) при c > 0. Показывать это еще проще.
lim sup n → ∞ 2 c n / 2 ( n 1/2 ) = lim n → ∞ 2 c n - n 1/2 = ∞ ∉ R
для любого фиксированного c > 0. Следовательно, сложность функции где-то действительно находится между полиномом и экспонентой.
Насколько большой это? Что ж, O (2 ^ sqrt (n)) точно такой же большой, как и он :-(
Чтобы понять, что это значит, представьте, что ваш алгоритм будет не просто O (2 ^ sqrt (n)), но что на самом деле он занимает ровно 2 ^ sqrt (n) наносекунды на вашем компьютере:
n = 100: 2 ^ 10 = 1024 наносекунд. Нет времени вообще. n = 1000: 2 ^ 31.xxx = 2 миллиарда наносекунд. Две секунды, это заметно. n = 10000: 2 ^ 100 ≈ 10 ^ 30 наносекунд = 10 ^ 21 секунд = 30 триллионов лет.
Это намного лучше, чем 2 ^ n наносекунд, где n = 100 займет 30 триллионов лет, но все же размер проблем, которые вы можете решить, весьма ограничен. Если вы считаете проблему «разрешимой», если ваш компьютер может решить ее за одну неделю, это примерно 6 x 10 ^ 14 наносекунд, то есть n = 2400. С другой стороны, до n = 400 можно решить за миллисекунду.
(На практике для n = 10000 O (2 ^ sqrt (n)) и O (2 ^ n) занимают одно и то же время: слишком долго ждать.)
Он превосходит любой многочлен. Возьмите другой алгоритм, занимающий n ^ 1000 секунд. Что практически неразрешимо при n = 2. Этот алгоритм занимает больше времени, пока n не составит около 885 миллионов. Но действительно, кого это волнует? В этот момент количество лет, которое требуется обоим алгоритмам, составляет 9 000 цифр.