Помогите рассчитать Big O - PullRequest
2 голосов
/ 23 сентября 2011

Я пытаюсь получить правильный Big-O следующего фрагмента кода:

s = 0
for x in seq:
  for y in seq:
    s += x*y
  for z in seq:
    for w in seq:
      s += x-w

Согласно книге, из которой я получил этот пример (Алгоритмы Python), они объясняют это так:

Z-цикл выполняется для линейного числа итераций и содержит линейный цикл, поэтому общая сложность здесь квадратичная, или Θ (n 2 ).Y-петля явно Θ (n).Это означает, что блок кода внутри x-цикла равен Θ (n + n 2 ).Весь этот блок выполняется для каждого цикла цикла x, который выполняется n раз.Мы используем наше правило умножения и получаем Θ (n (n + n 2 )) = Θ (n 2 + n 3 ) = Θ (n 3 ), то есть куб.

Чего я не понимаю, так это: как O (n (n + n 2 )) может стать O (п 3 )?Математика верна?

Ответы [ 4 ]

8 голосов
/ 23 сентября 2011

Математика здесь делается следующим образом.Когда вы говорите O (n (n + n 2 )), это эквивалентно выражению O (n 2 + n 3 ), просто распределяя n по всемупроизведение.

Причина, по которой O (n 2 + n 3 ) = O (n 3 ) следует из формального определенияобозначение big-O, которое выглядит следующим образом:

Функция f (n) = O (g (n)), если существуют константы n 0 и c такие, что длялюбой n ≥ n 0 , | f (n) |≤ c | g (n) |.

Неофициально это говорит о том, что, когда n становится произвольно большим, f (n) сверху ограничивается постоянным кратным g (n).

Чтобы формально доказать, что n 2 + n 3 есть O (n 3 ), рассмотрим любое n ≥ 1. Тогда мы получим это

n 2 + n 3 ≤ n 3 + n 3 = 2n 3

Итак, имеем n 2 + n 3 = O (n 3 ), с n 0 = 1 и c = 2. Следовательно, имеем, что

O (n (n + n 2 )) = O (n 2 + n 3 ) = O (n 3 ).

Чтобы быть по-настоящему формальным, нам нужно показать, что если f (n)= O (g (n)) и g (n) = O (h (n)), тогда f (n) = O (h (n)).Давайте пройдемся по доказательству этого.Если f (n) = O (g (n)), существуют константы n 0 и c такие, что для n ≥ n 0 , | f (n) |≤ c | g (n) |.Аналогично, поскольку g (n) = O (h (n)), существуют константы n ' 0 , c', такие что для n ≥ n ' 0 , g (n)≤ c '| h (n) |.Таким образом, это означает, что для любого n ≥ max (c, c ') мы имеем, что

| f (n) |≤ c | g (n) |≤ c | c'h (n) |= cxc '| h (n) |

И так f (n) = O (h (n)).

Чтобы быть немного более точным - в случаеПо описанному здесь алгоритму авторы говорят, что время выполнения равно is (n 3 ), что является более сильным результатом, чем утверждение, что время выполнения равно O (n 3 ).Θ нотация обозначает жесткую асимптотическую границу, означающую, что время выполнения растет с той же скоростью, что и n 3 , а не только потому, что оно ограничено сверху некоторым кратным n 3 .Чтобы доказать это, вам также необходимо показать, что n 3 равно O (n 2 + n 3 ).Я оставлю это в качестве упражнения для читателя.: -)

В более общем случае, если у вас есть любой полином порядка k, этот полином равен O (n k ), используя аналогичный аргумент.Чтобы увидеть это, пусть P (n) = ∑ i = 0 k (a i n i ).Тогда для любого n ≥ 1 имеем

i = 0 k (a i n i ) ≤ ∑ i = 0 k (a i n k ) = (∑ i = 0 k (a i )) n k

, поэтому P (n) = O (n k ).

Надеюсь, это поможет!

7 голосов
/ 23 сентября 2011
O(n(n+n^2)) = O(n^2 + n^3)

Поскольку термин n^3 доминирует над термином n^2, термин n^2 пренебрежимо мал и поэтому равен O(n^3).

6 голосов
/ 23 сентября 2011

n (n + n 2 ) == n 2 + n 3

Обозначение Big-O заботится только о доминирующем члене, когда n обращается в бесконечность, поэтому весь алгоритм рассматривается как Θ (n 3 ).

1 голос
/ 23 сентября 2011

цикл y можно обесценить из-за цикла z (O (n) + O (n ^ 2) -> O (n ^ 2)) Забудьте арифметику. Затем у вас останется три вложенных цикла, которые повторяются по всей длине 'seq', поэтому это O (n ^ 3)

...