Какому определению асимптотической скорости роста мы должны учить?

35

Когда мы следуем за стандартные учебники, или традиции, большинство из нас учат следующее определение большого Ах обозначений в первые несколько лекций класса алгоритмов:

f=O(g) iff (c>0)(n00)(nn0)(f(n)cg(n)).
Возможно, мы даже приведем весь список со всеми его квантификаторами:
  1. f=o(g) iff (c>0)(n00)(nn0)(f(n)cg(n))
  2. f=O(g) iff (c>0)(n00)(nn0)(f(n)cg(n))
  3. f=Θ(g) iff (c>0)(d>0)(n00)(nn0)(dg(n)f(n)cg(n))
  4. f=Ω(g) iff (d>0)(n00)(nn0)(f(n)dg(n))
  5. f=ω(g) iff (d>0)(n00)(nn0)(f(n)dg(n)) .

Однако, так как с этими определениями не так легко работать, когда дело доходит до доказательства даже простых вещей, таких как , большинство из нас быстро двигатьсячтобы ввести «трюк предела»:5nlog4n+nlogn=o(n10/9)

  1. если lim n f ( n ) / g ( n ) существует и равен 0 ,f=o(g)limnf(n)/g(n)0
  2. если lim n f ( n ) / g ( n ) существует и не равен + ,f=O(g)limnf(n)/g(n)+
  3. если lim n f ( n ) / g ( n ) существует и не равен ни 0, ни + ,f=Θ(g)limnf(n)/g(n)0+
  4. если lim n f ( n ) / g ( n ) существует и не равен 0 ,f=Ω(g)limnf(n)/g(n)0
  5. если lim n f ( n ) / g ( n ) существует и равен + .f=ω(g)limnf(n)/g(n)+

Мой вопрос:

Будет ли большой потерей обучение класса алгоритмов для студентов принять предельные условия в качестве определений , O , Θ , Ω и ω ? Это то, чем мы все в конечном итоге пользуемся, и мне кажется совершенно ясным, что пропуск определений квантификаторов облегчает жизнь всем.oOΘΩω

Мне было бы интересно узнать, не сталкивались ли вы с каким-нибудь убедительным естественным случаем, когда на самом деле требуются стандартные определения , и если нет, то есть ли у вас убедительный аргумент, чтобы сохранить стандартные определения c , n 0 в любом случае.c,n0c,n0

slimton
источник
1
Тег должен действительно «обучать», но я не смог найти связанный тег, и мне не разрешено создавать новые теги.
Слитон
1
Это в основном поглощает квантификаторы в эпсилон-дельта-определение пределов. Единственное, что меня беспокоит, - это то, что многие студенты CS не проходили анализ, и поэтому их понимание в основном механическое. Для того, чтобы позволить им быстро рассчитать, однако, это не просто.
Пер Вогсен
6
Обратите внимание, что ваши два определения O () не эквивалентны (одно и то же предупреждение относится к Θ () и Ω ()). Рассмотрим случай, когда f (n) = 2n для четного n и f (n) = 1 для нечетного n. Является ли f (n) = O (n)? Я предпочитаю использовать limsup вместо lim, чтобы я мог сказать f (n) = Θ (n) в этом случае (хотя ни одно из ваших определений не позволяет этого). Но это может быть моим личным предпочтением (и даже нестандартной практикой), и я никогда не преподавал в классе.
Цуёси Ито
2
@Tsuyoshi: я думал, что смысл «уловки предела» заключается в том, что это было достаточным, но не обязательным условием для . (Для o ( ) это также необходимо.) У контрпримера колебательной функции нет предела. O()o()
Андрас Саламон
1
Разве вы не должны заменить символ на в каждом определении и свойстве? Я нашел использование = очень тревожным, как студент. ==
Джереми

Ответы:

13

Я предпочитаю преподавать оригинальное определение с квантификаторами.

ИМО, люди, как правило, испытывают затруднения в понимании формул и определений с более чем двумя чередованием кванторов напрямую Введение новых квантификаторов может прояснить, что означает это определение. Здесь последние два квантификатора просто означают «для всех достаточно больших n», введение такого рода количественной оценки может помочь.

Рисунки, которые я рисую для объяснения этих концепций, лучше соответствуют версиям квантификатора.

Я думаю, что упрощение предела полезно для студентов-инженеров, которые заинтересованы только в вычислении скорости роста, но не будут такими же полезными для студентов-информатиков. Фактически, использование этого упрощения может принести больше вреда, чем пользы.

Эта идея аналогична предложению использовать правила вычисления производных (полиномов, возведения в степень, ..., правила цепочки, ...) вместо определения его эпсилон-дельта, что, по-моему, не очень хорошая идея.

Кава
источник
Возможное доминирование понятие также полезно: тогда и только тогда \ esits м п > т е ( п ) < г ( п ) . Теперь F O ( г ) тогда и только тогда существует с > 0 - й е ( х ) « с г ( х ) . f(x)g(x)\esitsmn>mf(n)<g(n)fO(g)c>0f(x)cg(x)
Каве
9

Изменить: Основная редакция в редакции 3.

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

Существуют естественные примеры, когда «предельная уловка», как написано, не может быть применена. Например, предположим, что вы реализуете «вектор переменной длины» (например, vector <T> в C ++), используя массив фиксированной длины с удвоением размера (то есть каждый раз, когда вы собираетесь превысить размер массива, вы перераспределить массив в два раза больше, чем сейчас, и скопировать все элементы). Размер S ( n ) массива, когда мы храним n элементов в векторе, является наименьшей степенью 2, большей или равной n . Мы хотим сказать, что S ( n ) = O ( n ), но использование «предельного трюка», как написано в определении, не позволит нам сделать это, потому что S ( n) / n плотно колеблется в диапазоне [1,2). То же самое относится к Ω () и Θ ().

В качестве отдельного вопроса, когда мы используем эти обозначения для описания сложности алгоритма, я думаю, что ваше определение Ω () иногда неудобно (хотя я предполагаю, что это определение является общим). Удобнее определить, что f ( n ) = Ω ( g ( n )) тогда и только тогда, когда limsup f ( n ) / g ( n )> 0. Это связано с тем, что некоторые задачи тривиальны для бесконечного числа значений n ( например, проблема идеальной обработки на графе с нечетным числом n вершин). То же самое относится к Θ () и ω ().

Поэтому лично я считаю, что следующие определения наиболее удобно использовать для описания сложности алгоритма: для функций f , g : ℕ → ℝ > 0 ,

  • f ( n ) = o ( g ( n )) тогда и только тогда, когда limsup f ( n ) / g ( n ) = 0. (Это эквивалентно lim f ( n ) / g ( n ) = 0.)
  • f ( n ) = O ( g ( n )) тогда и только тогда, когда limsup f ( n ) / g ( n ) <∞.
  • f ( n ) = Θ ( g ( n )) тогда и только тогда, когда 0 <limsup f ( n ) / g ( n ) <∞.
  • f ( n ) = Ω ( g ( n )) тогда и только тогда, когда limsup f ( n ) / g ( n )> 0. (Это эквивалентно тому, что f ( n ) не является o ( g ( n )).)
  • f ( n ) = ω ( g ( n )) тогда и только тогда, когда limsup f ( n ) / g ( n ) = ∞. (Это эквивалентно тому, что f ( n ) не является O ( g ( n )).)

или эквивалентно,

  • f ( n ) = o ( g ( n )) тогда и только тогда, когда для каждого c > 0, для достаточно большого n , f ( n ) ≤ cg ( n ).
  • f ( n ) = O ( g ( n )) тогда и только тогда, когда для некоторого c > 0, для достаточно большого n , f ( n ) ≤ cg ( n ).
  • f ( n ) = Θ ( g ( n )) тогда и только тогда, когда f ( n ) = O ( g ( n )) и f ( n ) = Ω ( g ( n )).
  • f ( n ) = Ω ( g ( n )) тогда и только тогда, когда для некоторого d > 0, для бесконечного числа n , f ( n ) ≥ dg ( n ).
  • f ( n ) = ω ( g ( n )) тогда и только тогда, когда для каждого d > 0, для бесконечно многих n , f ( n ) ≥ dg ( n ).

Но я не знаю, является ли это обычной практикой или нет. Также я не знаю, подходит ли оно для обучения. Проблема в том, что мы иногда хотим определить Ω () вместо liminf (как вы делали в первом определении). Например, когда мы говорим «Вероятность ошибки этого рандомизированного алгоритма составляет 2 -Ω ( n ) », мы не имеем в виду, что вероятность ошибки экспоненциально мала только для бесконечного числа n !

Цуёси Ито
источник
Я также использую определения limsup, но для студентов, которые не видели limsup (почти все), я все равно должен расшириться до явных квантификаторов.
Джефф
@JeffE: Я согласен, что большинство учеников не видели limsup, поэтому, если мы используем определения limsup, мы должны вместо этого использовать квантификаторы в классе.
Цуёси Ито
2
Проблема с версиями квантификаторов заключается в том, что их трудно запомнить и визуализировать. Я предпочитаю потому что это можно описать как «высший предел». Возможное объяснение: «Это похоже на l i m , за исключением того, что l i m работает только тогда, когда последовательность сходится. Если последовательность не сходится, например, потому что алгоритм колеблется между очень быстрым для некоторых n и медленным для других n , тогда мы берем самый высокий предел ». limsuplimlimnn
Генрих Апфельмус
На самом деле, есть ли естественные примеры для алгоритмов, где время работы колеблется?
Генрих Апфельмус
2
@ Heinrich: Я уже упоминал время работы алгоритма, чтобы найти идеальное соответствие графа по n вершинам, но считается ли это естественным примером? Я добавил еще один пример, где время работы не колеблется, а f (n) / g (n) колеблется. Пример говорит о сложности пространства, но временная сложность того же примера имеет то же свойство.
Цуёси Ито
8

Использование лимитов немного сбивает с толку, поскольку (1) это более сложное понятие (2), которое не очень хорошо отражает f = O (g) (как мы можем видеть в обсуждении выше). Я обычно говорю о функциях от натуральных (строго положительных) чисел до натуральных чисел (которых достаточно для времени выполнения), пропускаю мелочи, а затем определение является кратким и подходящим для старшеклассников 1-го курса:

Dfn: f = O (g), если для некоторого C для всех n имеем f (n) <= C * g (n)

Ноам
источник
1
Во-первых, мне не понравилось это определение, потому что указание «всех n» скрывает важный факт, что нотация O () заботится только о поведении функций для больших n. Однако, независимо от того, какое определение мы выберем, я думаю, что мы должны объяснить этот факт вместе с определением. Думая таким образом, формулировка этого простого определения кажется довольно хорошей.
Цуёси Ито
f(n)=n for all n, g(n)=0 for all n up to N0, and g(n)=f(n)+1 otherwise, then f=O(g) but this definition fails to capture this relationship. So one has to add some handwaving about functions that are well-behaved in some sense.
András Salamon
2
The point of talking about functions whose range is the Natural numbers (not including 0) is exactly not to fall into problems with g(n)=0.
Noam
1
@Warren Victor Shoup in his book on Computational Number Theory uses the notation len(a) instead of loga in running time analysis, which I found neat.
Srivatsan Narayanan
1
@Warren (continued) This is how he explains it: "In expressing the running times of algorithms in terms of an input a, we generally prefer to write len(a) rather than loga. One reason is esthetic: writing len(a) stresses the fact that the running time is a function of the bit length of a. Another reason is technical: for big-O estimates involving functions on an arbitrary domain, the appropriate inequalities should hold throughout the domain, and for this reason, it is very inconvenient to use functions, like log, which vanish or are undefined on some input."
Srivatsan Narayanan
5

When I took basic courses, we were given the c,n0 thing as definition and the other stuff as theorem.

I think the first one is more natural for many people that think discrete rather than continuous, that is most computer scientists (in my experience). It also fits the way we usually talk about those things better: "There is a polynomial function of degree 3 that is an upper bound for this f up to a constant factor."

Edit: You can get even closer to this way of speaking if you use this definition: fO(g):⇔c,d>0n0:f(n)cg(n)+d (Note that d=f(n0) connects this definition with the one usually given)

The limit stuff is pretty useful for calculating complexity classes, that is with pen and paper.

In any case, I think it is very useful for students to learn that there is a wealth of (hopefully) equivalent definitions. They should be able to realize that and pick out differences in case of nonequivalent definitions.

Raphael
источник
4

Having studied these concepts only a few years ago, they were not the hardest ones to grasp for my class (as opposed to concepts like induction, or contra positives). Limits and limsups are only more "intuitive" for those familiar with calculus in my opinion. But students with such a math grounding will have set-theoretic background anyway, so that they can process discrete qualifiers.

Also, more importantly, remember that ultimately your students will go on (hopefully) to read other cs theory textbooks, and perhaps even research papers one day. As such, it is better for them to be comfortable with standard notation in the field, even if it was not ideally conceived initially. There is no harm giving them alternate definitions as well, once they've assimilated the standard ones.

Amir
источник
3

For an interesting take on the issue, look at Don Knuth's nicely written letter "Calculus via O notation". He advocates the reverse view that calculus should be taught via the 'A', 'O' and 'o' notations.

Note: He uses the "A" notation as a preliminary step in defining the standard "O" notation. A quantity x is A of y (i.e., x=A(y)), if |x|y. In particular, it makes sense to say 100 is A(200).

Srivatsan Narayanan
источник
1
  1. Tsuyoshi Ito's definitions don't look quite right. For little-omega and big-omega the definitions should use liminf, not limsup. The definition of big-theta needs both a lower-bound on liminf and an upper-bound on limsup.

  2. One definition of f(n)=O(g(n)) is that there exists another function f'(n) >= f(n) such that lim f'(n)/g(n) < infinity.

  3. Why are newbies allowed to post answers but not make comments?

Warren Schudy
источник
1
As for item 1, I mean limsup in all cases, and the reason is explained in the second paragraph of my answer.
Tsuyoshi Ito
it's a spam blocking mechanism unfortunately.
Suresh Venkat
Aso, you can use latex in your answers.
Suresh Venkat
1

First, I try to develop in students some intuition, before showing equations.

  • "Merge-sort vs Insertion-Sort" is good starting point.

Then, later... I try to show both ways. Students, that relies more on intuition prefer

f=O(g) iff (c>0)(n00)(nn0)(f(n)cg(n)).
while those who relies more on math, equasions, algebra etc. , they prefer "limn" definitions.

Another aspect is that, it heavily depends on concrete studies' program. IMHO depending on previous subjects one of definitions will be more suitable - while IMHO still it is good idea to show both and accept both types of solutions.

Grzegorz Wierzowiecki
источник