Aula 05 - Notação Assintótica
Universidade Federal do Rio Grande do Sul
Instituto de Informática
Departamento de Informática Teórica
Estes slides utilizam conteúdo adaptado da bibliografia da disciplina e também de notas de aula e slides prévios dos professores Bruno Grisci, Rodrigo Machado, André Grahl Pereira, Lucas Nunes Alegre, Marcus Ritt e Luciana Buriol.
Ideia: Suprimir fatores constantes e termos de baixa ordem.
Exemplo: 8n^3 + 50n + 86 cresce como n^3.
Terminologia: O algoritmo tem tempo de execução O(n^3), onde n é o tamanho da entrada.
Problema: O vetor A contém o número t?
P: Qual é o tempo de execução?
P: Quanto espaço é usado?
Problema: O vetor A contém o número t?
P: Qual é o tempo de execução? O(n)
Problema: O vetor A ou o vetor B contém o número t?
P: Qual é o tempo de execução?
Problema: O vetor A ou o vetor B contém o número t?
P: Qual é o tempo de execução? O(n)
Problema: O vetor A e o vetor B contêm um número em comum?
P: Qual é o tempo de execução?
Problema: O vetor A e o vetor B contêm um número em comum?
P: Qual é o tempo de execução? O(n^2)
Problema: O vetor A tem um elemento duplicado?
P: Qual é o tempo de execução?
Problema: O vetor A tem um elemento duplicado?
P: Qual é o tempo de execução? O(n^2)
“Análise de algoritmos usualmente significa: atribuir uma expressão Big O para o tempo de execução. (Claro, Big \Theta seria muito melhor.)”
— Ian Parberry. “Problems on Algorithms”, 1994, p. 59.
Def. Seja T(n) uma função em n=1, 2, 3, \dots (em geral o pior tempo de execução de um algoritmo).
P: Quando T(n) é O(f(n))?
R: Se eventualmente (para n suficientemente grande), T(n) é limitado por cima por f(n) multiplicada por uma constante.
Def. T(n) é O(f(n)) se e somente se existe uma constante \textcolor{red}{c} > 0 e um \textcolor{#2e7d32}{n_0} \geq 0 tal que T(n) \leq \textcolor{red}{c} \cdot f(n) para todo n \geq \textcolor{#2e7d32}{n_0}.
Exemplo: T(n) = 32n^2 + 17n + 1
Obs. \textcolor{red}{c} e \textcolor{#2e7d32}{n_0} não podem depender de n.

T(n) = 3n + 1
T(n) é O(n): \textcolor{red}{c} = 4 e \textcolor{#2e7d32}{n_0} = 1, \textcolor{red}{c} = 3{,}5 e \textcolor{#2e7d32}{n_0} = 2, \dots
T(n) é O(n^2): \textcolor{red}{c} = 6 e \textcolor{#2e7d32}{n_0} = 0, \dots
T(n) é O(n^3), O(n^4), \dots
T(n) não é O(n): https://www.geogebra.org/classic/h2f2scrd
Def. T(n) é O(f(n)) se e somente se existe uma constante \textcolor{red}{c} > 0 e um \textcolor{#2e7d32}{n_0} tal que T(n) \leq \textcolor{red}{c} \cdot f(n) para todo n \geq \textcolor{#2e7d32}{n_0}.
Afirmação. Se T(n) = a_{\textcolor{orange}{k}}n^{\textcolor{orange}{k}}+\dots+a_1n^1+a_0 então T(n) = O(n^{\textcolor{orange}{k}}).
Prova. Escolha \textcolor{#2e7d32}{n_0}=1 e \textcolor{red}{c}=|a_{\textcolor{orange}{k}}|+\dots+|a_1|+|a_0|.
Nós temos que mostrar que \forall n \geq \textcolor{#2e7d32}{n_0}, T(n) \leq \textcolor{red}{c} \cdot n^{\textcolor{orange}{k}}.
T(n) \leq |a_{\textcolor{orange}{k}}|n^{\textcolor{orange}{k}}+\dots+|a_1|n^1+|a_0|.
T(n) \leq |a_{\textcolor{orange}{k}}|n^{\textcolor{orange}{k}}+\dots+|a_1|n^{\textcolor{orange}{k}}+|a_0| n^{\textcolor{orange}{k}}.
T(n) \leq (|a_{\textcolor{orange}{k}}| + \dots + |a_1| + |a_0|) n^{\textcolor{orange}{k}}.
T(n) \leq \textcolor{red}{c} \cdot n^{\textcolor{orange}{k}} \blacksquare
Def. T(n) é O(f(n)) se e somente se existe uma constante \textcolor{red}{c} > 0 e um \textcolor{#2e7d32}{n_0} tal que T(n) \leq \textcolor{red}{c} \cdot f(n) para todo n \geq \textcolor{#2e7d32}{n_0}.
Afirmação. Para todo \textcolor{orange}{k} \geq 1, n^{\textcolor{orange}{k}} não é O(n^{\textcolor{orange}{k}-1}).
Prova. Prova por contradição. Suponha que n^{\textcolor{orange}{k}} = O(n^{\textcolor{orange}{k}-1}).
Então existem \textcolor{red}{c}, \textcolor{#2e7d32}{n_0} tal que n^{\textcolor{orange}{k}} \leq \textcolor{red}{c} \cdot n^{\textcolor{orange}{k}-1}, \forall n \geq \textcolor{#2e7d32}{n_0}.
Mas dividindo ambos os lados por n^{\textcolor{orange}{k}-1}:
\dfrac{n^{\textcolor{orange}{k}}}{n^{\textcolor{orange}{k}-1}} \leq \dfrac{\textcolor{red}{c} \cdot n^{\textcolor{orange}{k}-1}}{n^{\textcolor{orange}{k}-1}}, \forall n \geq \textcolor{#2e7d32}{n_0}
n \leq \textcolor{red}{c}, \forall n \geq \textcolor{#2e7d32}{n_0}.
O que é uma contradição (pois \textcolor{red}{c} é uma constante). \blacksquare
Sinal de Igual: O(f(n)) é um conjunto de funções, mas comumente escrevemos T(n) = O(f(n)) em vez de T(n) \in O(f(n)).
Def. T(n) é \Omega(f(n)) se e somente se existe uma constante \textcolor{red}{c} > 0 e um \textcolor{#2e7d32}{n_0} \geq 0 tal que T(n) \geq \textcolor{red}{c} \cdot f(n) para todo n \geq \textcolor{#2e7d32}{n_0}.

Exemplo: T(n) = 32n^2 + 17n + 1.
Uso: Ordenação por Inserção é \Omega(n).
Def. T(n) é \Theta(f(n)) se e somente se existem constantes \textcolor{red}{c_1}, \textcolor{red}{c_2} > 0 e um \textcolor{#2e7d32}{n_0} \geq 0 tal que \textcolor{red}{c_1} \cdot f(n) \leq T(n) \leq \textcolor{red}{c_2} \cdot f(n) para todo n \geq \textcolor{#2e7d32}{n_0}.

Exemplo: T(n) = 32n^2 + 17n + 1.
Uso: BubbleSort é \Theta(n^2).
Def. T(n) é \Theta(f(n)) se e somente se T(n) = O(f(n)) e T(n) = \Omega(f(n)).

Exemplo: Seja T(n) = \frac{1}{2}n^2 + 3n. Quais dos seguintes é verdadeiro (apresente constantes e n_0)?
Exemplo: Seja T(n) = \frac{1}{2}n^2 + 3n. Quais dos seguintes é verdadeiro (apresente constantes e n_0)?
Além das notações O, \Omega e \Theta, existem duas notações para representar limites estritos.
Essas duas notações, todavia, são raramente encontradas na literatura de computação.
Nos próximos slides, apresentamos a notação o e \omega para completude, porém, não as utilizaremos nesta disciplina.
Def. T(n) é o(f(n)) se e somente se para toda constante \textcolor{red}{c} > 0 existe uma constante \textcolor{#2e7d32}{n_0} > 0 tal que T(n) < \textcolor{red}{c} \cdot f(n) para todo n \geq \textcolor{#2e7d32}{n_0}.
Exemplo: T(n) = 32n^2 + 17n + 1.
Uso: BubbleSort é o(n^3), mas não é o(n^2).
Def. T(n) é \omega(f(n)) se e somente se para toda constante \textcolor{red}{c} > 0 existe uma constante \textcolor{#2e7d32}{n_0} > 0 tal que T(n) > \textcolor{red}{c} \cdot f(n) para todo n \geq \textcolor{#2e7d32}{n_0}.
Exemplo: T(n) = 32n^2 + 17n + 1.
Uso: BubbleSort é \omega(n).
\textcolor{blue}{f}(n) = O(\textcolor{orange}{g}(n)) \iff \lim_{n\to\infty} \dfrac{\textcolor{blue}{f}(n)}{\textcolor{orange}{g}(n)} < \infty
\textcolor{blue}{f}(n) = \Omega(\textcolor{orange}{g}(n)) \iff \lim_{n\to\infty} \dfrac{\textcolor{blue}{f}(n)}{\textcolor{orange}{g}(n)} > 0
\textcolor{blue}{f}(n) = \Theta(\textcolor{orange}{g}(n)) \iff \lim_{n\to\infty} \dfrac{\textcolor{blue}{f}(n)}{\textcolor{orange}{g}(n)} = \textcolor{red}{c} > 0
\textcolor{blue}{f}(n) = o(\textcolor{orange}{g}(n)) \iff \lim_{n\to\infty} \dfrac{\textcolor{blue}{f}(n)}{\textcolor{orange}{g}(n)} = 0
\textcolor{blue}{f}(n) = \omega(\textcolor{orange}{g}(n)) \iff \lim_{n\to\infty} \dfrac{\textcolor{blue}{f}(n)}{\textcolor{orange}{g}(n)} = \infty
“Well, I think I have beat this issue to death, knowing of no other arguments pro or con the introduction of \Theta and \Omega. On the basis of the issues discussed here, I propose that members of SIGACT, and editors of computer science and mathematics journals, adopt the O, \Theta, \Omega notations as defined above, unless a better alternative can be found reasonably soon.”
— “Big Omicron and Big Omega and Big Theta”, SIGACT News, 1976.
Donald Knuth:


Def. (Transitividade): Se \textcolor{blue}{f}(n) = O(\textcolor{orange}{g}(n)) e \textcolor{orange}{g}(n) = O(\textcolor{#0284c7}{h}(n)) então \textcolor{blue}{f}(n) = O(\textcolor{#0284c7}{h}(n)).
Prova. É dado que:
- \textcolor{blue}{f}(n) \leq c' \textcolor{orange}{g}(n) para todo n \geq n_0' e
- \textcolor{orange}{g}(n) \leq c'' \textcolor{#0284c7}{h}(n) para todo n \geq n_0''.
- Considere n_0 = \max(n_0', n_0''), então nós temos que
- \textcolor{blue}{f}(n) \leq c' \textcolor{orange}{g}(n) \leq c' c'' \textcolor{#0284c7}{h}(n).
- Logo, \textcolor{blue}{f}(n) \leq c' c'' \textcolor{#0284c7}{h}(n) e
- \textcolor{blue}{f}(n) = O(\textcolor{#0284c7}{h}(n)). \blacksquare
Def. (Transitividade): Se \textcolor{blue}{f}(n) = \Omega(\textcolor{orange}{g}(n)) e \textcolor{orange}{g}(n) = \Omega(\textcolor{#0284c7}{h}(n)) então \textcolor{blue}{f}(n) = \Omega(\textcolor{#0284c7}{h}(n)).
P: O que podemos concluir?
Se \textcolor{blue}{f}(n) = \Theta(\textcolor{orange}{g}(n)) e \textcolor{orange}{g}(n) = \Theta(\textcolor{#0284c7}{h}(n)) então \textcolor{blue}{f}(n) = \Theta(\textcolor{#0284c7}{h}(n)).
Prova (\textcolor{blue}{f}(n) = O(\textcolor{orange}{g}(n)) \iff \textcolor{orange}{g}(n) = \Omega(\textcolor{blue}{f}(n))):
- \textcolor{blue}{f}(n) = O(\textcolor{orange}{g}(n)) \iff \exists \textcolor{red}{c} > 0, \textcolor{#2e7d32}{n_0} \geq 0 tal que \textcolor{blue}{f}(n) \leq \textcolor{red}{c} \cdot \textcolor{orange}{g}(n) para todo n \geq \textcolor{#2e7d32}{n_0}.
- Dividindo por \textcolor{red}{c}:
- \textcolor{orange}{g}(n) \geq \frac{1}{\textcolor{red}{c}} \cdot \textcolor{blue}{f}(n) para todo n \geq \textcolor{#2e7d32}{n_0}.
- Escolhendo c' = \frac{1}{\textcolor{red}{c}} > 0, temos por definição que \textcolor{orange}{g}(n) = \Omega(\textcolor{blue}{f}(n)). \blacksquare
Def. (Soma de Funções): Se \textcolor{blue}{f}(n) = O(\textcolor{#0284c7}{h}(n)) e \textcolor{orange}{g}(n) = O(\textcolor{#0284c7}{h}(n)) então \textcolor{blue}{f}(n) + \textcolor{orange}{g}(n) = O(\textcolor{#0284c7}{h}(n)).
Prova. É dado que:
- \textcolor{blue}{f}(n) \leq c' \textcolor{#0284c7}{h}(n) para todo n \geq n_0' e
- \textcolor{orange}{g}(n) \leq c'' \textcolor{#0284c7}{h}(n) para todo n \geq n_0''.
- Considere n_0 = \max(n_0', n_0''), então nós temos que
- \textcolor{blue}{f}(n) + \textcolor{orange}{g}(n) \leq c' \textcolor{#0284c7}{h}(n) + c'' \textcolor{#0284c7}{h}(n) = (c' + c'') \textcolor{#0284c7}{h}(n).
- Logo, \textcolor{blue}{f}(n) + \textcolor{orange}{g}(n) = O(\textcolor{#0284c7}{h}(n)). \blacksquare
Def. (Soma de Funções): Seja \textcolor{orange}{k} uma constante, \textcolor{blue}{f}_1(n), \textcolor{blue}{f}_2(n), \dots, \textcolor{blue}{f}_{\textcolor{orange}{k}}(n) e \textcolor{#0284c7}{h}(n) funções tal que \forall i, \textcolor{blue}{f}_i(n) = O(\textcolor{#0284c7}{h}(n)). Então \textcolor{blue}{f}_1(n) + \textcolor{blue}{f}_2(n) + \dots + \textcolor{blue}{f}_{\textcolor{orange}{k}}(n) = O(\textcolor{#0284c7}{h}(n)).
Consequência:
Def. (Soma de Funções): Sejam \textcolor{blue}{f}(n) e \textcolor{orange}{g}(n) duas funções tal que \textcolor{orange}{g}(n) = O(\textcolor{blue}{f}(n)). Então \textcolor{blue}{f}(n) + \textcolor{orange}{g}(n) = \Theta(\textcolor{blue}{f}(n)).
Prova.
- Temos que \textcolor{blue}{f}(n) + \textcolor{orange}{g}(n) \geq \textcolor{blue}{f}(n),
- Logo, \textcolor{blue}{f}(n) + \textcolor{orange}{g}(n) = \Omega(\textcolor{blue}{f}(n)).
- Já que \textcolor{orange}{g}(n) = O(\textcolor{blue}{f}(n)) e \textcolor{blue}{f}(n) = O(\textcolor{blue}{f}(n)), então
- \textcolor{blue}{f}(n) + \textcolor{orange}{g}(n) = O(\textcolor{blue}{f}(n)).
- Logo, \textcolor{blue}{f}(n) + \textcolor{orange}{g}(n) = \Theta(\textcolor{blue}{f}(n)). \blacksquare
Def. f(n) = a_{\textcolor{orange}{k}} n^{\textcolor{orange}{k}} + \dots + a_1 n^1 + a_0 para algum \textcolor{orange}{k} > 0 com a_{\textcolor{orange}{k}} > 0.
Algoritmos Polinomiais:
Def. \log_{\textcolor{blue}{b}} n é o número x tal que \textcolor{blue}{b}^x = n.
Afirmação. Para todo b > 1 e todo \textcolor{orange}{k} > 0, nós temos que \log_{\textcolor{blue}{b}} n = o(n^{\textcolor{orange}{k}}) (portanto \log_{\textcolor{blue}{b}} n \neq \Theta(n^{\textcolor{orange}{k}})).
Prova.
\lim_{n\to\infty} \frac{\log_{\textcolor{blue}{b}} n}{n^{\textcolor{orange}{k}}} = 0
Intuição:
Def. \log_{\textcolor{blue}{b}} n é o número x tal que \textcolor{blue}{b}^x = n.
Obs. A base do logaritmo não importa.
Afirmação. \log_{\textcolor{red}{a}} n = \Theta(\log_{\textcolor{blue}{b}} n).
Prova.
- \log_{\textcolor{red}{a}} n = \dfrac{\log_{\textcolor{blue}{b}} n}{\log_{\textcolor{blue}{b}} \textcolor{red}{a}}
- \log_{\textcolor{red}{a}} n = \dfrac{1}{\log_{\textcolor{blue}{b}} \textcolor{red}{a}} \cdot \log_{\textcolor{blue}{b}} n
- \dfrac{1}{\log_{\textcolor{blue}{b}} \textcolor{red}{a}} é uma constante maior que zero que independe de n. \blacksquare
Def. f(n) = \textcolor{blue}{r}^n com \textcolor{blue}{r} > 1.
Afirmação. Para todo \textcolor{blue}{r} > 1 e todo \textcolor{orange}{k} > 0, nós temos que n^{\textcolor{orange}{k}} = o(\textcolor{blue}{r}^n).
Prova. \lim_{n\to\infty} \frac{n^{\textcolor{orange}{k}}}{\textcolor{blue}{r}^n} = 0
Intuição: O denominador cresce mais rapidamente.
Def. f(n) = \textcolor{blue}{r}^n com \textcolor{blue}{r} > 1.
Obs. A base da exponencial importa.
Afirmação. Para \textcolor{blue}{r} > \textcolor{orange}{s}, \textcolor{blue}{r}^n \neq \Theta(\textcolor{orange}{s}^n).
Prova. Suponha, para obter contradição, que \textcolor{blue}{r}^n = \Theta(\textcolor{orange}{s}^n). Então existem constantes \textcolor{red}{c_1}, \textcolor{red}{c_2} > 0 e n_0 tais que: \textcolor{red}{c_1} \textcolor{orange}{s}^n \leq \textcolor{blue}{r}^n \leq \textcolor{red}{c_2} \textcolor{orange}{s}^n \quad \text{para todo } n \geq n_0.
Em particular, teríamos a cota superior \textcolor{blue}{r}^n \leq \textcolor{red}{c_2} \textcolor{orange}{s}^n, isto é, \left(\dfrac{\textcolor{blue}{r}}{\textcolor{orange}{s}}\right)^n \leq \textcolor{red}{c_2} \quad \text{para todo } n \geq n_0.
Mas como \dfrac{\textcolor{blue}{r}}{\textcolor{orange}{s}} > 1, temos \left(\dfrac{\textcolor{blue}{r}}{\textcolor{orange}{s}}\right)^n \to \infty quando n \to \infty, o que contradiz a existência de tal \textcolor{red}{c_2} independente de n. Logo, \textcolor{blue}{r}^n \notin O(\textcolor{orange}{s}^n) e \textcolor{blue}{r}^n \neq \Theta(\textcolor{orange}{s}^n). \blacksquare
Obs. Fatoriais crescem mais rapidamente que exponenciais de base fixa.
Afirmação. Para todo \textcolor{blue}{r} > 0, \textcolor{blue}{r}^n = o(n!) (então n! \notin O(\textcolor{blue}{r}^n)).
Prova. Para n \geq 2: n! = \prod_{\textcolor{orange}{k}=1}^n \textcolor{orange}{k} \geq \prod_{\textcolor{orange}{k}=\lceil n/2 \rceil + 1}^n \textcolor{orange}{k} \geq \left(\frac{n}{2}\right)^{n/2}.
Logo, 0 \leq \dfrac{\textcolor{blue}{r}^n}{n!} \leq \dfrac{\textcolor{blue}{r}^n}{\left(\frac{n}{2}\right)^{n/2}} = \left(\dfrac{\textcolor{blue}{r}}{\sqrt{n/2}}\right)^n.
Como \textcolor{blue}{r} é constante e \sqrt{n/2} \to \infty, existe n_0 tal que \dfrac{\textcolor{blue}{r}}{\sqrt{n/2}} < 1 para todo n \geq n_0, e então \lim_{n\to\infty} \left(\dfrac{\textcolor{blue}{r}}{\sqrt{n/2}}\right)^n = 0. Portanto, \lim_{n\to\infty} \dfrac{\textcolor{blue}{r}^n}{n!} = 0, isto é, \textcolor{blue}{r}^n = o(n!). \blacksquare
Outros exemplos: deletar elemento de um vetor indexado, pop de uma pilha, \dots
A é um vetor ordenado de tamanho n.
n \;\to\; \frac{n}{2} \;\to\; \frac{n}{4} \;\to\; \frac{n}{8} \;\to\; \dots \;\to\; 1
Quantas divisões? Seja \textcolor{orange}{k} o número de passos. Temos:
\frac{n}{2^{\textcolor{orange}{k}}} = 1 \;\;\;\Rightarrow\;\;\; \textcolor{orange}{k} = \log_2 n.
Outro exemplo: encontrar o máximo de um vetor.
Observações:
MergeSort(A, 1, length(A)).
Nota: depende de estruturas de dados adequadas.
Outros exemplos: InsertionSort, BubbleSort, QuickSort*, encontrar o par de pontos mais próximos por força bruta.
Problema: Dados S_1, S_2, \dots, S_n \subseteq \{1, 2, \dots, n\}, decidir se existe um par (S_i, S_j) disjunto (sem elementos em comum).
Nota: Existem algoritmos que melhoram o tempo de execução O(n^3) para este problema, mas são bastante complexos.

https://en.wikipedia.org/wiki/Travelling_salesman_problem#/media/File:Bruteforce.gif
Encontrar um algoritmo polinomial para o problema do caixeiro-viajante vale 1 milhão de dólares!
?