Что означает более быстрый алгоритм в теоретической информатике?


18

Если существует алгоритм, работающий во времени O(f(n)) для некоторой задачи A, и кто-то придумывает алгоритм, работающий во времени, O(f(n)/g(n)) , где g(n)=o(f(n)) , считается ли это улучшением по сравнению с предыдущим алгоритмом?

Имеет ли смысл в контексте теоретической информатики придумать такой алгоритм?


4
Под «более быстрым алгоритмом» мы понимаем «асимптотически более быстрый алгоритм».
Юваль Фильмус

@YuvalFilmus, что ты имеешь в виду под «асимптотически»
не определено

1
Запуск во времени . o(f(n))
Юваль Фильмус

Ответы:


26

Нет, алгоритм, работающий во времени , где g ( n ) = o ( f ( n ) ) , не обязательно считается улучшением. Например, предположим, что f ( n ) = n и g ( n ) = 1 / n . Тогда O ( f ( n ) / g (O(f(n)/g(n))g(n)=o(f(n))f(n)=ng(n)=1/n является худшей временной границей, чем O ( f ( n ) ) = O ( n ) .O(f(n)/g(n))=O(n2)O(f(n))=O(n)

Чтобы улучшить алгоритм, работающий во времени , вам нужно придумать алгоритм, работающий во времени o ( f ( n ) ) , то есть во времени g ( n ) для некоторой функции g ( n ) = o ( f ( n ) )f(n)o(f(n))g(n)g(n)=o(f(n)) .

Если все, что вам известно, это то, что алгоритм работает за время , то неясно, является ли алгоритм, работающий за время O ( g ( n ) ), улучшением, независимо от того, f ( n ) , g ( n) ) являются Это потому, что большой O является только верхней границей времени выполнения. Вместо этого, общепринято рассматривать временную сложность в худшем случае, и оценить его как большое & thetas , а не просто как большой O .O(f(n))O(g(n))f(n),g(n)ΘO


21
Возможно, лучше взять в первом абзаце. Использование убывающей функции кажется немного обманчивым. g(n)=1
Дэвид Ричерби

1
@DavidRicherby: Может быть, немного, но OP никогда не говорил, что у них есть алгоритм, работающий в поэтому нельзя допустить монотонности. O(g(n))
Кевин

7
@Kevin Конечно, но контекст - это информатика, а в информатике нотация big-O обычно используется для неубывающих функций. Вероятно, спрашивающий думал в этих условиях.
Дэвид Ричерби

11

Помните , что Обозначение предназначено для анализа того, как растет задача для различных размеров ввода, а конкретно оставляет мультипликативные факторы, нижайший порядок термин, и константу.O(...)

Предположим, у вас есть алгоритм , фактическое время выполнения которого составляет 1 n 2 + 2 n + 1 (при условии, что вы действительно можете посчитать инструкции и узнать точные значения времени и т. Д., Что по общему признанию является огромным допущением в современных системах). Затем предположим, что вы придумали новый алгоритм, который оказывается O ( n ) , но фактическое время выполнения составляет 1000 n + 5000 . Также предположим, что вы знаете, что программное обеспечение для использования этого алгоритма никогда не увидит проблему размером n > 10 .O(n2)1n2+2n+1O(n)1000n+5000n>10

Итак, что бы вы выбрали - алгоритм , который займет 15000 единиц времени, или алгоритм O ( n 2 ), который займет всего 121 единицу? Теперь, если ваше программное обеспечение развивается для обработки проблемных размеров n > 100000 , какой из них вы бы выбрали? Что бы вы сделали, если размер вашей проблемы сильно варьируется?O(n)O(n2)n>100000


2
«никогда не вижу проблемы размером n> 10» - тогда мы бы вообще не использовали нотацию O, не так ли ...
AnoE

5
@AnoE Простые числа ради аргумента. Та же самая логика применима, если вы анализируете для проблемы размером 10 против 1e5 или анализируете для 1e6 против 1e9.
Твальберг

1
@AnoE Большинство компьютерных программ не пытаются справиться с бесконечно растущим размером проблемы. Так что будет компромисс. Вот почему Big-O для теоретической информатики, и концепции могут быть применены для улучшения реальных программ.
mbomb007

Точно, @ mbomb007. Заголовок вопроса: «Что означает более быстрый алгоритм в теоретической информатике?» и он имеет это в теле: «Имеет ли это смысл в контексте теоретической информатики ...».
AnoE

@AnoE Из опыта, обозначение O используется, когда n <10 все время! Не то чтобы это была хорошая идея ... но это полностью то, что сделано!
Cort Ammon - Восстановить Монику

5

Как правило, это означает, что для любого размера ввода, который достаточно велик, наихудшее время работы старого алгоритма медленнее, чем нового. Это эквивалентно формализму , где g - временная сложность нового алгоритма, а f - временная сложность старого.g(n)o(f(n))gf

Иногда, однако, компьютерные ученые заботятся о средней производительности. Классическим примером является Quicksort: его наихудший среда является , тогда как мы знаем , другие , которые работают в thetas ; ( п авторизуйтесь п ) время, но он широко используется на практике из - за его хорошей среднем случае время работает. Кроме того, его можно настроить так, чтобы он работал очень быстро в случаях, наиболее часто встречающихся в условиях дикой природы, таких как массивы, которые в основном находятся в правильном порядке.Θ(n2)Θ(nlogn)

И иногда даже теоретики-компьютерщики используют «быстрее» так же, как обычные люди. Например, большинство реализаций классов String имеют оптимизацию Short String (также называемую Small String Optimization), даже если она ускоряет работу только для коротких строк и является чисто служебной информацией для более длинных. По мере того как размер входных данных становится все больше и больше, время выполнения операции String с SSO будет увеличиваться на небольшой постоянный член, поэтому по определению, которое я дал в первом абзаце, удаление SSO из класса String делает его «быстрее На практике, тем не менее, большинство строк маленькие, поэтому SSO позволяет большинству программ использовать их быстрее, и большинство профессоров в области компьютерных наук знают лучше, чем ходя вокруг, требуя, чтобы люди говорили только о порядках асимптотической сложности времени.


1

Нет единого определения того, что такое «более быстрый алгоритм». Не существует руководящего органа, который решает, является ли алгоритм более быстрым, чем другой.

Чтобы указать, почему это так, я хотел бы предложить два разных сценария, которые демонстрируют эту мутную концепцию.

Первый пример - это алгоритм, который ищет связанный список неупорядоченных данных. Если я могу сделать ту же самую операцию с массивом, у меня не останется никаких изменений в большой О производительности. Оба поиска O (n). Если я просто посмотрю на большие значения О, я могу сказать, что я вообще не улучшился. Однако известно, что в большинстве случаев поиск в массиве выполняется быстрее, чем при просмотре связанного списка, поэтому можно решить, что это сделало алгоритм «быстрее», даже если большое значение «О» не изменилось.

Если я могу использовать традиционный пример программирования робота для приготовления бутерброда из PBJ, я могу показать, что я имею в виду, другим способом. Рассмотрим только тот момент, когда открывают банку с арахисовым маслом.

Pick up the jar
Grab the lid
Unscrew the lid

Против

Pick up the jar
Put the jar back down
Pick up the jar
Put the jar back down
Pick up the jar
Put the jar back down
Pick up the jar
Put the jar back down
Pick up the jar
Put the jar back down
Pick up the jar
Grab the lid
Unscrew the lid

Даже в самых академических теоретических условиях, которые я могу придумать, вы поймете, что люди признают, что первый алгоритм быстрее второго, даже несмотря на то, что результаты больших обозначений Oh одинаковы.

Напротив, мы можем рассмотреть алгоритм, который нарушает шифрование RSA. На данный момент считается, что этот процесс, вероятно, O (2 ^ n), где n - количество битов. Рассмотрим новый алгоритм, который работает на n ^ 100 быстрее. Это означает, что мой новый процесс выполняется в O (2 ^ n / n ^ 100). Однако в мире криптографии полиномиальное ускорение по экспоненциальному алгоритму традиционно вообще не рассматривается как теоретическое ускорение. При проверке безопасности предполагается, что злоумышленник может обнаружить одно из этих ускорений и что оно не будет иметь никакого эффекта.

Таким образом, в одном случае мы можем изменить O (n) на O (n) и вызвать его быстрее. При других обстоятельствах мы можем изменить O (2 ^ n) на O (2 ^ n / n ^ 100) и утверждать, что никакого существенного ускорения не было вообще. Вот почему я говорю, что нет единого определения для «более быстрого алгоритма». Это всегда зависит от контекста.


1

A(n)O(f(n))

 0cf< lim supnA(n)f(n)=cf

Now, let us assume we are talking about an arbitrarily increasing function g(n) where lim supng(n)= and let us create the function h(n)=f(n)g(n).

We are given that the run-time of the "improved" algorithm A(n) is in O(h(n)). Suppose that the run-time of the original algorithm A(n) is also in O(h(n)). This can be written as follows.

 0ch< lim supnA(n)h(n)=ch

Using the rules of limits, we can also write:

ch=lim supnA(n)h(n)=lim supnA(n)g(n)f(n)=cflim supng(n)

Since ch<, this can only be true if cf=0.

The contrapositive statement is: If cf0, then A(n)O(h(n)).

In words, A(n) is an "improvement" on A(n) under the additional conditions that A(n)Θ(f(n)) and g(n) is arbitrarily increasing.

Additionally, this should show why the statement that A(n)O(f(n)) is not strong enough to draw a conclusion about whether A(n) is an "improvement." In short, A(n) could already be in O(h(n)).


1
Your limit should be limit superior.
Yuval Filmus

1
@YuvalFilmus Updated
Jared Goguen
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.