Vous êtes sur la page 1sur 58

Introduc~o a Algoritmos a

(Vers~o Parcial: 01/03/2001, 10:30h) a Favor n~o distribuir a

Thomas H. Cormen, Charles E. Leiserson, e Ronald L. Rivest

Introduction to Algorithms, MIT Press, c 1990


por Ruy J. Guerra B. de Queiroz

Traduzido do original em ingl^s e

Indice
1 Introduc~o a
1.1 Algoritmos : : : : : : : : : : : : : : : : : : : : : 1.2 Analisando algoritmos : : : : : : : : : : : : : : : 1.3 Desenhando algoritmos : : : : : : : : : : : : : : : 1.3.1 A abordagem divis~o-e-conquista : : : : : a 1.3.2 Analisando algoritmos divis~o-e-conquista a 1.4 Resumo : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 3 7 12 12 14 16

I Fundamentos Matematicos
2 Crescimento de Func~es o 3 Somatorios
4.1 4.2 4.3 4.4

21
25 43

2.1 Notac~o assintotica : : : : : : : : : : : : : : : : : : : : : : : : : : 25 a 2.2 Notac~es padr~o e func~es usuais : : : : : : : : : : : : : : : : : : 33 o a o

3.1 Formulas e propriedades de somatorios : : : : : : : : : : : : : : : 43 3.2 Delimitando somatorios : : : : : : : : : : : : : : : : : : : : : : : 47 O metodo da substituic~o a O metodo da iterac~o : : a O metodo mestre : : : : : Prova do teorema mestre : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

4 Recorr^ncias e

51

51 51 51 51 53 53 53 53 53

5 Conjuntos, Etc.
5.1 5.2 5.3 5.4 5.5 Conjuntos Relac~es : o Func~es : o Grafos : : Arvores :

53

6 Contagem e Probabilidade
6.1 6.2 6.3 6.4 6.5 6.6

Contagem : : : : : : : : : : : : : : : : : Probabilidade : : : : : : : : : : : : : : : Variaveis aleatorias discretas : : : : : : A distribuic~o geometrica e a binomial : a As caudas da distribuic~o binomial : : : a Analise probabil stica : : : : : : : : : : 3

55

55 55 55 55 55 55

INDICE

II Ordenac~o e Estat sticas de Ordem a


7 Heapsort
7.1 7.2 7.3 7.4 7.5
Heaps : : : : : : : : : : : : : : : Mantendo a propriedade de heap Construindo um heap : : : : : : O algoritmo heapsort : : : : : : : Filas de prioridade : : : : : : : :

57
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

: : : : :

: : : : : : : : :

: : : : : : : : : : : : :

: : : : : : : : : : : : :

: : : : : : : : : : : : :

: : : : : : : : : : : : :

61

61 61 61 61 61

8 Quicksort
8.1 8.2 8.3 8.4

Descric~o do quicksort : : : : : : : a Desempenho do quicksort : : : : : Vers~es randomizadas do quicksort o Analise do quicksort : : : : : : : :

63

63 63 63 63

9 Ordenac~o em Tempo Linear a


9.1 9.2 9.3 9.4

Limitantes inferiores para ordenac~o a Ordenac~o por contagem : : : : : : : a Ordenac~o por radix : : : : : : : : : a Ordenac~o por balde : : : : : : : : : a

65

65 65 65 65

10 Medianas e Estat sticas de Ordenac~o a

10.1 M nimo e maximo : : : : : : : : : : : : : : : : : : : : : : : : : : 67 10.2 Selec~o em tempo linear esperado : : : : : : : : : : : : : : : : : : 67 a 10.3 Selec~o em tempo linear no pior-caso : : : : : : : : : : : : : : : : 67 a

67

III Estruturas de Dados


11 Estruturas de Dados Elementares
11.1 11.2 11.3 11.4 Pilhas e las : : : : : : : : : : : : : : : Listas encadeadas : : : : : : : : : : : : Implementando apontadores e objetos Representando arvores com ra zes : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

69
73
73 73 73 73

12 Tabelas de Hash
12.1 12.2 12.3 12.4

Tabelas de endereco-direto : Tabelas de hash : : : : : : : Func~es de hash : : : : : : o Enderecamento aberto : : :

75

75 75 75 75

13 Arvores de Busca Binaria


13.1 13.2 13.3 13.4

O que e uma arvore de busca binaria? : : : : : : : : Consultando uma arvore de busca binaria : : : : : : Inserc~o e remoc~o : : : : : : : : : : : : : : : : : : : a a Arvores de busca binaria constru das aleatoriamente

77

77 77 77 77

INDICE

5 Propriedades de arvores vermelho-preto Rotac~es : : : : : : : : : : : : : : : : : : o Inserc~o : : : : : : : : : : : : : : : : : : a Remoc~o : : : : : : : : : : : : : : : : : : a : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

14 Arvores Vermelho-Preto
14.1 14.2 14.3 14.4

79

79 79 79 79

15 Aumentando Estruturas de Dados

15.1 Estat sticas din^micas de ordem : : : : : : : : : : : : : : : : : : 81 a 15.2 Como aumentar uma estrutura de dados : : : : : : : : : : : : : : 81 15.3 Arvores de intervalo : : : : : : : : : : : : : : : : : : : : : : : : : 81

81

IV Tecnicas Avancadas de Desenho e Analise


16 Programac~o Din^mica a a
16.1 16.2 16.3 16.4 Multiplicac~o de cadeia de matrizes a Elementos de programac~o din^mica a a Maiores subsequ^ncias comuns : : : e Triangulac~o otima de pol gono : : : a : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

83
87
87 87 87 87

17 Algoritmos Gulosos
17.1 17.2 17.3 17.4 17.5

Um problema de selec~o de atividade : : : : : : a Elementos da estrategia gulosa : : : : : : : : : Codigos de Hu man : : : : : : : : : : : : : : : Fundamentos teoricos para os metodos gulosos Um problema de escalonamento de tarefas : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

89

89 89 89 89 89

18 Analise Amortizada
18.1 18.2 18.3 18.4

O metodo agregado : : : : : O metodo da contabilizac~o a O metodo do potencial : : : Tabelas din^micas : : : : : a

91

91 91 91 91

V Estruturas de Dados Avancadas


19 Arvores B

93
97

19.1 De nic~o de arvores B : : : : : : : : : : : : : : : : : : : : : : : : 97 a 19.2 Operac~es basicas sobre arvores B : : : : : : : : : : : : : : : : : 97 o 19.3 Removendo uma chave de uma arvore B : : : : : : : : : : : : : : 97

20 Heaps Binomiais

20.1 Arvores binomiais e heaps binomiais : : : : : : : : : : : : : : : : 99 20.2 Operac~es sobre heaps binomiais : : : : : : : : : : : : : : : : : : 99 o Estrutura dos heaps de Fibonacci : : : : : : : : : Operac~es sobre heaps intercalaveis : : : : : : : : o Decrementando uma chave e removendo um no : Determinando um limitante para o grau maximo : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

99

21 Heaps de Fibonacci
21.1 21.2 21.3 21.4

101
101 101 101 101

INDICE
22.1 22.2 22.3 22.4 Operac~es sobre conjuntos disjuntos : : : : : : : : : : : : : o Representac~o de conjuntos disjuntos em listas encadeadas : a Florestas de conjuntos disjuntos : : : : : : : : : : : : : : : : Analise da uni~o por posto com compress~o de caminho : : a a : : : : : : : : : : : :

22 Estruturas de Dados para Conjuntos Disjuntos

103

103 103 103 103

VI Algoritmos sobre Grafos


23 Algoritmos Elementares sobre Grafos
23.1 23.2 23.3 23.4 23.5 Representac~es de grafos : : : : : o Busca em largura : : : : : : : : : Busca em profundidade : : : : : Ordenac~o topologica : : : : : : a Componentes fortemente conexos : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

105
109
109 109 109 109 109

24 Arvores Geradoras M nimas


25.1 25.2 25.3 25.4

24.1 Fazendo crescer uma arvore geradora m nima : : : : : : : : : : : 111 24.2 Os algoritmos de Kruskal e de Prim : : : : : : : : : : : : : : : : 111 Caminhos mais curtos e relaxac~o : : : : : : : : : : : : : : : : : a O algoritmo de Dijkstra : : : : : : : : : : : : : : : : : : : : : : : O algoritmo de Bellman{Ford : : : : : : : : : : : : : : : : : : : : Caminhos mais curtos de uma unica fonte em grafos direcionados ac clicos : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 25.5 Restric~es de diferenca e caminhos mais curtos : : : : : : : : : : o 26.1 26.2 26.3 26.4 Caminhos mais curtos e multiplicac~o de matrizes : : : : : : : : a O algoritmo de Floyd{Warshall : : : : : : : : : : : : : : : : : : : O algoritmo de Johnson para grafos esparsos : : : : : : : : : : : Um arcabouco geral para resoluc~o de problemas de caminho em a grafos direcionados : : : : : : : : : : : : : : : : : : : : : : : : : : Redes de uxo : : : : : : : : : O metodo de Ford{Fulkerson : Casamento bipartido maximo : Algoritmos de pre- uxo : : : : O algoritmo puxa-para-a-frente : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

111

25 Caminhos Mais Curtos de uma Unica Fonte

113

113 113 113 113 113

26 Caminhos Mais Curtos entre Todos-os-Pares

115

115 115 115 115

27 Fluxo Maximo
27.1 27.2 27.3 27.4 27.5

117

117 117 117 117 117

VII Topicos Selecionados


28 Redes de Ordenac~o a
28.1 28.2 28.3 28.4 28.5 Redes de comparac~o : : : : : : : a O princ pio zero-um : : : : : : : Uma rede de ordenac~o bit^nica a o Uma rede de intercalac~o : : : : a Uma rede de ordenac~o : : : : : a : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

119
123
123 123 123 123 123

INDICE

7 Circuitos combinacionais : Circuitos de adic~o : : : : a Circuitos de multiplicac~o a Circuitos temporizados : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

29 Circuitos Aritmeticos
29.1 29.2 29.3 29.4 30.1 30.2 30.3 30.4 30.5

125

125 125 125 125

30 Algoritmos para Computadores Paralelos

Salto de apontador : : : : : : : : : : : : : : : Algoritmos CRCW versus algoritmos EREW O teorema de Brent e e ci^ncia de trabalho : e Computac~o de pre xo paralela e ciente : : : a Quebra simetrica determin stica : : : : : : : :

127

127 127 127 127 127

31 Operac~es sobre Matrizes o


31.1 31.2 31.3 31.4 31.5 31.6

Propriedades de matrizes : : : : : : : : : : : : : : : : : : : : : : 129 O algoritmo de Strassen para multiplicac~o de matrizes : : : : : 129 a Sistemas numericos algebricos e multiplicac~ode matrizes booleanas129 a Resolvendo sistemas de equac~es lineares : : : : : : : : : : : : : : 129 o Invertendo matrizes : : : : : : : : : : : : : : : : : : : : : : : : : 129 Matrizes positivas-de nitivas simetricas e aproximac~o por m nimos a quadrados : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 129

129

32 Polin^mios e a TRF o

32.1 Representac~o de polin^mios : : : : : : : : : : : : : : : : : : : : 131 a o 32.2 A TDF e a TRF : : : : : : : : : : : : : : : : : : : : : : : : : : : 131 32.3 Implementac~o e ciente da TRF : : : : : : : : : : : : : : : : : : 131 a Noc~es elementares da teoria dos numeros o Maximo divisor comum : : : : : : : : : : Aritmetica modular : : : : : : : : : : : : Resolvendo equac~es lineares modulares : o O teorema do resto chin^s : : : : : : : : : e Pot^ncias de um elemento : : : : : : : : : e O criptossistema de chave publica RSA : Testando a propriedade de ser primo : : : Fatorac~o inteira : : : : : : : : : : : : : : a : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

131

33 Algoritmos da Teoria dos Numeros


33.1 33.2 33.3 33.4 33.5 33.6 33.7 33.8 33.9

133

133 133 133 133 133 133 133 133 133 135 135 135 135 135 137 137 137 137

34 Casamento de Cadeias
34.1 34.2 34.3 34.4 34.5

O algoritmo ing^nuo de casamento-de-cadeias e O algoritmo de Robin{Karp : : : : : : : : : : Casamento de cadeias com aut^matos nitos o O algoritmo de Knuth{Morris{Pratt : : : : : O algoritmo de Boyer{Moore : : : : : : : : :

135

35 Geometria Computacional
35.1 35.2 35.3 35.4

Propriedades de reta-segmento : : : : : : : : : : : : : : : : : : Determinando se um par qualquer de segmentos tem intersec~o a Encontrando a envoltoria convexa : : : : : : : : : : : : : : : : : Encontrando o par de pontos mais proximos : : : : : : : : : : :

137

INDICE

i Tempo polinomial : : : : : : : : Veri cac~o em tempo polinomial a NP-completude e redutibilidade : Provas de NP-completude : : : : Problemas NP-completos : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

36 NP-Completude
36.1 36.2 36.3 36.4 36.5

139

139 139 139 139 139

37 Algoritmos de Aproximac~o a
37.1 37.2 37.3 37.4

O problema da cobertura de vertices : O problema do caixeiro viajante : : : O problema da cobertura de conjuntos O problema do subconjunto-soma : : :

141
141 141 141 141

ii

INDICE

Prefacio
Este livro da uma introduc~o abrangente ao estudo moderno de algoritmos para a computadores. Ele apresenta diversos algoritmos e os trata com uma razoavel profundidade, e ainda assim torna seu desenho e sua analise acess veis a todos os n veis de leitores. Tentamos manter as explanac~es num n vel elementar sem o sacri car a profundidade da abordagem ou o rigor matematico.

INDICE

Cap tulo 1

Introduc~o a
Este cap tulo devera faz^-lo car familiar com a arcabouco que usaremos em e todo o livro para pensar sobre o desenho e a analise de algoritmos. E autocontido, mas inclui varias refer^ncias ao material que sera introduzido na Parte e I. Comecamos com uma discuss~o sobre problemas computacionais em geral e a sobre os algoritmos necessarios para resolv^-los, com o problema da ordenac~o e a como nosso exemplo de trabalho. Introduzimos um \pseudocodigo" que deve ser familiar aos leitores que zeram programac~o de computadores para mostrar a como especi caremos nossos algoritmos. Ordenac~o por inserc~o, um algoritmo a a simples de ordenac~o, serve como um exemplo inicial. Analisamos o tempo de a execuc~o da ordenac~o por inserc~o, introduzindo uma notac~o que focaliza o a a a a \como" aquele tempo cresce com o numero de itens a serem ordenados. Introduzimos tambem a abordagem divis~o-e-conquista ao desenho de algoritmos e a a usamos para desenvolver um algoritmo chamado ordenac~o por intercalac~o. a a Finalizamos com uma comparac~o entre os dois algoritmos de ordenac~o. a a

Informalmente, um algoritmo e qualquer procedimento computacional bem de nido que toma algum valor, ou conjunto de valores, como entrada e produz algum valor, ou conjunto de valores, como sa da. Um algoritmo e portanto uma sequ^ncia de passos computacionais que transforma a entrada na sa da. e Podemos tambem ver um algoritmo como uma ferramenta para resolver um problema computacional bem especi cado. O enunciado do problema especi ca em termos gerais a relac~o entrada/sa da. O algoritmo descreve um a procedimento computacional espec co para se atingir a relac~o entrada/sa da a desejada. Comecamos nosso estudo de algoritmos com um problema de ordenac~o de a uma sequ^ncia de numeros em ordem n~o-decrescente. Esse problema surge e a frequentemente na pratica e prov^ um terreno fertil para se introduzir muitas e tecnicas padr~o de desenho e ferramentas de analise. Aqui esta a forma pela a qual de nimos o problema da ordenac~o: a 3

1.1 Algoritmos

~ CAP TULO 1. INTRODUCAO

trada tal que a01 a02 : : : a0n. Dada uma sequ^ncia de entrada tal como h31; 41; 59; 26; 41; 58i, um algoritmo e de ordenac~o retorna como sequ^ncia de sa da a sequ^ncia h26; 31; 41; 41; 58; 59i. a e e Tal sequ^ncia de entrada e chamada de inst^ncia do problema de ordenac~o. e a a Em geral, uma inst^ncia de um problema consiste de todas as entradas a (satisfazendo quaisquer que sejam as restric~es que sejam impostas no enunciado o do problema) necessarias para computar uma soluc~o do problema. a Ordenac~o e uma operac~o fundamental em ci^ncia da computac~o (muitos a a e a programas a usam como um passo intermediario), e em vista disso um grande numero de bons algoritmos de ordenac~o t^m sido desenvolvidos. Qual algoa e ritmo e melhor para uma dada aplicac~o depende do numero de itens a serem a ordenados, ate que ponto os itens ja est~o de certa maneira ordenados, e o tipo a de dispositivo de memoria a ser usado: memoria principal, disco, ou ta. Um algoritmo e dito correto se, para toda inst^ncia de entrada, ele para com a a sa da correta. Dizemos que um algoritmo correto resolve um dado problema computacional. Um algoritmo incorreto pode ate n~o parar de forma alguma em a algumas inst^ncias de entrada, ou ele pode parar com outra sa da diferente da a resposta desejada. Ao contrario do que se poderia esperar, algoritmos incorretos podem as vezes ser uteis, se sua taxa de erro puder ser controlada. Veremos um exemplo disso no Cap tulo 33 quando estudamos algoritmos para encontrar numeros primos grandes. Comumente, entretanto, estaremos nos concentrando apenas em algoritmos corretos. Um algoritmo pode ser especi cado em ingl^s, como um programa de come putador, ou ate mesmo como um desenho de hardware. O unico requisito e que a especi cac~o deve prover uma descric~o precisa do procedimento computacional a a a ser seguido. Neste livro, descreveremos tipicamente algoritmos como programas escritos em um pseudocodigo que e muito parecido com C, Pascal, ou Algol. Se voc^ e foi apresentado a qualquer dessas linguagens, voc^ deve ter pouca di culdade e em ler nossos algoritmos. O que separa pseudocodigo de codigo \real" e que em pseudocodigo empregamos quaisquer metodos expressivos que sejam o mais claro e conciso poss vel para especi car um dado algoritmo. As vezes, o metodo mais claro e a l ngua natural, portanto n~o se surpreenda se voc^ se deparar a e com uma frase em ingl^s ou uma sentenca imersa numa porc~o de codigo \real". e a Uma outra diferenca entre pseudocodigo e codigo real e que pseudocodigo n~o a e tipicamente voltado para quest~es sobre engenharia de software. Quest~es o o sobre abstrac~o de dados, modularidade, e manuseio de erros s~o frequentemente a a ignoradas de modo a transmitir a ess^ncia do algoritmo de forma mais concisa. e

Entrada: Uma sequ^ncia de n numeros ha1; a2; : : :; ani e Sa da: Uma permutac~o (re-ordenac~o) ha01 ; a02; : : :; a0ni da sequ^ncia de ena a e

para ordenar um pequeno numero de elementos. A ordenac~o por inserc~o a a funciona da maneira que muitas pessoas ordenam as cartas num jogo de baralho. Comecamos com uma m~o esquerda vazia e as cartas na mesa viradas para baixo. a Da retiramos uma carta da mesa a cada vez e a inserimos na posic~o correta a na m~o esquerda. Para achar a posic~o correta para uma determinada carta, a a a

Ordenac~o por inserc~o a a Comecamos com a ordenac~o por inserc~o, que e um algoritmo e ciente a a

1.1. ALGORITMOS

comparamos com cada uma das cartas que ja est~o na m~o, da direita para a a a esquerda, como ilustrado na Figura 1.1. Nosso pseudocodigo para a ordenac~o por inserc~o e apresentado como um a a ~ procedimento chamado Ordena-Insercao, que toma como um par^metro um a vetor A 1::n] contendo uma sequ^ncia de comprimento n que e para ser ordee nada. (No codigo, o numero n de elementos em A e designado por tamanho A].) Os numeros de entrada s~o ordenados no lugar: os numeros s~o rearranjados a a dentro do vetor A, com no maximo um numero constante deles armazenado fora do vetor em qualquer instante de tempo. O vetor de entrada A contem a ~ sequ^ncia de sa da ordenada quando Ordena-Insercao e completado. e 1 2 3 4 5 6 7 8

para j 2 ate tamanho A] faca chave A j]

. Insere A j] na sequ^ncia ordenada A 1::j 1]. e i j 1 enquanto i > 0 and A i] > chave faca A i + 1] A i] i i 1 A i + 1] chave

A Figura 1.2 mostra como esse algoritmo funciona para A = h5; 2; 4; 6; 1; 3i. O ndice j indica a \carta atual" sendo inserida na m~o. Os elementos do vetor a A 1::j 1] constituem a m~o ja ordenada, e os elementos A j + 1::n] correspona dem a pilha de cartas ainda na mesa. O ndice j move da esquerda para a direita atraves do vetor. A cada iterac~o do laco para mais externo, o elemento A j] a e retirado do vetor (linha 2). Ent~o, comecando na posic~o j 1, os elemena a tos s~o sucessivamente deslocados uma posic~o para a direita ate que a posic~o a a a apropriada para A j] seja encontrada (linhas 4{7), ponto no qual ele e inserido (linha 8).

Convenc~es de pseudocodigo o

Usamos as seguintes convenc~es em nosso pseudocodigo. o 1. Um novo paragrafo (deslocamento para a direita) indica uma estrutura de bloco. Por exemplo, o corpo do laco para que comeca na linha 1 consiste das linhas 2{8, e o corpo do laco enquanto que comeca na linha 5 contem as linhas 6{7 mas n~o a linha 8. Nosso estilo via paragrafos aplica-se a tambem a comandos se-ent~o-sen~o. Usando paragrafos ao inves de a a indicadores convencionais de estrutura em bloco, tais como comeco e m, reduz enormemente o excesso de notac~o ao mesmo tempo em preserva, a ou ate melhora, a clareza.1 2. As construc~es de laco enquanto, para, e repita e as construc~es de o o condicionais se, ent~o, e sen~o t^m a mesma interpretac~o que em Pasa a e a cal. 3. O s mbolo \." indica que o restante da linha e um comentario.
1 Em linguagens de programac~o propriamente ditas, e geralmente desaconselhavel usar a paragrafos somente para indicar estruturas em bloco, pois os n veis de paragrafo s~o dif ceis a de determinar quando o codigo e partido em mais de uma pagina.

~ CAP TULO 1. INTRODUCAO


4. Uma atribuic~o multipla da forma i j e atribui a ambas as variaveis a i e j o valor da express~o e; deve ser tratado como equivalente a atribuic~o a a j e seguida pelo comando i j. 5. Variaveis (tais como i, j, e chave) s~o locais ao procedimento dado. N~o a a usaremos variaveis globais sem indicac~o expl cita. a 6. Elementos de vetores s~o acessados especi cando o nome do vetor seguido a do ndice em colchetes. Por exemplo, A i] indica o i-esimo elemento do vetor A. A notac~o \::" e usada para indicar a faixa de variac~o dos a a valores dentro de um vetor. Por conseguinte, A 1::j] indica a subvetor de A consistindo dos elementos A 1]; A 2]; :: :; A j]. 7. Dados compostos s~o tipicamente organizados em objetos, que s~o cona a stitu dos de atributos ou campos. Um campo espec co e acessado usando o nome do campo seguido do nome de seu objeto em colchetes. Por exemplo, tratamos um vetor como um objeto com o atributo tamanho indicando quantos elementos ele contem. Para especi car o numero de elementos em um vetor A, escrevemos tamanho A]. Embora usemos colchetes tanto para indexac~o de vetor quanto para atributos de objetos, normala mente cara claro a partir do contexto qual interpretac~o e pretendida. a Uma variavel representando um vetor ou objeto e tratada como um apontador para os dados representando o vetor ou o objeto. Para todos os campos f de um objeto x, fazendo y x acarreta em f y] = f x]. Alem do mais, se agora zermos f x] 3, ent~o depois disso temos n~o apenas a a f x] = 3, como tambem f y] = 3. Em outras palavras, x e y apontam para (\s~o") o mesmo objeto apos a atribuic~o y x. a a As vezes um apontador n~o fara refer^ncia a objeto algum. Nesse caso, a e lhe damos o valor especial nil. 8. Par^metros s~o passados a um procedimento por valor: o procedimento a a chamado recebe sua propria copia dos par^metros, e se ele atribui um a valor a um par^metro, a mudanca n~o e vista pela rotina que o chamou. a a Quando objetos s~o passados, o apontador para os dados representando o a objeto e copiado, mas os campos do objeto n~o o s~o. Por exemplo, se x e a a um par^metro de um procedimento chamado, a atribuic~o x y dentro a a do procedimento chamado n~o e vis vel ao procedimento que o chamou. a A atribuic~o f x] 3, entretanto, e vis vel. a

Exerc cios 1.1-1


1.1-2

~ Usando a Figura 1.2 como um modelo, ilustre a operac~o de Ordena-Insercao a sobre o vetor A = h31; 41; 59; 26; 41; 58i. ~ Reescreva o procedimento Ordena-Insercao para ordenar em ordem n~oa crescente ao inves de ordem n~o-decrescente. a

1.2. ANALISANDO ALGORITMOS

1.1-3

Considere o problema de busca:

Entrada: Uma sequ^ncia de n numeros A = ha1; a2; : : :; ani e um valor v. e Sa da: Um ndice i tal que v = A i] ou o valor especial nil se v n~o aparece a
em A. Escreva um pseudocodigo para busca linear, que varre a sequ^ncia procurando e por v. Considere o problema de adicionar dois inteiros binarios de n-bits, armazenados em dois vetores de n-elementos A e B. A soma dos dois inteiros deve ser armazenada em forma binaria em um vetor C de (n + 1)-elementos. Enuncie o problema formalmente e escreva o pseudocodigo para adic~o dos dois inteiros. a

1.1-4

1.2 Analisando algoritmos


Analisar um algoritmo tem sido interpretado como prever os recursos que o algoritmo requer. Ocasionalmente, recursos tais como memoria, velocidade de comunicac~o, ou portas logicas s~o de principal import^ncia, porem muito frea a a quentemente e o tempo computacional que desejamos medir. Geralmente, ao analisar varios algoritmos candidatos a resolver um problema, um algoritmo o mais e ciente pode ser facilmente identi cado. Tal analise pode indicar mais que um candidato viavel, mas varios algoritmos inferiores s~o usualmente descartaa dos no processo. Antes que possamos analisar um algoritmo, devemos ter um modelo da tecnologia de implementac~o que sera usada, incluindo um modelo para os recursos a daquela tecnologia e seus custos. Para a maior parte deste livro, assumiremos um modelo de computac~o generico de um-processador, maquina de acesso a rand^mico (RAM), como nossa tecnologia de implementac~o e entenderemos o a que nossos algoritmos ser~o implementados como programas de computador. No a modelo RAM, instruc~es s~o executadas uma apos outras, sem operac~es cono a o correntes. Em cap tulos mais adiante, entretanto, teremos ocasi~o de investigar a modelos para computadores paralelos e hardware digital. Analisar ate mesmo um algoritmo simples pode ser um desa o. As ferramentas matematicas necessarias podem incluir combinatoria discreta, teoria elementar da probabilidade, destreza algebrica, e a habilidade de identi car os termos mais signi cativos numa formula. Devido ao fato de que o comportamento de um algoritmo pode ser diferente para cada entrada poss vel, precisamos de meios de resumir aquele comportamento em formulas simples e facilmente compreens veis. Muito embora selecionamos tipicamente apenas um modelo de maquina para analisar um dado algoritmo, ainda assim nos deparamos com muitas escolhas para decidir como expressar nossa analise. Um objetivo imediato e encontrar um meio de express~o que seja simples de escrever e de manusear, que mostre a as caracter sticas importantes dos requisitos de recurso de um algoritmo, e que omita detalhes entediantes.

~ CAP TULO 1. INTRODUCAO

~ O tempo que leva o procedimento Ordena-Insercao depende da entrada: ordenar mil numeros leva mais tempo que ordenar tr^s numeros. Alem do mais, e ~ Ordena-Insercao pode levar quantidades diferentes de tempo para ordenar duas sequ^ncias de entrada do mesmo tamanho dependendo de o qu~o proximo e a de uma sequ^ncia ordenada elas ja se encontram. Em geral, o tempo tomado e por um algoritmo cresce com o tamanho da entrada, portanto e costume se descrever o tempo de execuc~o de um programa como uma func~o do tamanho a a de sua entrada. Para fazer isso, precisamos de nir mais cuidadosamente os termos \tempo de execuc~o" e \tamanho da entrada". a A melhor noc~o para tamanho da entrada depende do problema sendo esa tudado. Para muitos problemas, tais como ordenac~o ou computac~o de transa a formadas discretas de Fourier, a medida mais natural e o numero de itens na entrada |por exemplo, o tamanho n do vetor a ser ordenado. Para muitos outros problemas, tal como multiplicac~o de dois inteiros, a melhor medida do a tamanho da entrada e o numero total de bits necessarios para representar a entrada em notac~o binaria usual. As vezes, e mais apropriado descrever o a tamanho da entrada com dois numeros ao inves de um. Por exemplo, se a entrada de um algoritmo e um grafo, o tamanho da entrada pode ser descrito pelos numeros de vertices e de arestas no grafo. Indicaremos que medida do tamanho da entrada esta sendo usada com cada problema que estudaremos. O tempo de execuc~o de um algoritmo sobre uma entrada espec ca e o a numero de operac~es primitivas ou \passos" executados. E conveniente de nir o a noc~o de passo de modo que ela seja t~o independente de maquina quanto a a poss vel. Por ora, vamos adotar a seguinte vis~o. Uma quantidade constante de a tempo e necessaria para executar cada linha de nosso pseudocodigo. Uma linha pode levar uma quantidade de tempo diferente do que leva uma outra linha, mas assumiremos que cada execuc~o da i-esima linha leva o tempo ci , onde ci e uma a constante. Esse ponto de vista esta de acordo com o modelo RAM, e tambem re ete como o pseudocodigo seria implementado na maioria dos computadores reais.2 Na discuss~o que se segue, nossa express~o para o tempo de execuc~o de a a a ~ Ordena-Insercao evoluira de uma formula complicada que usa todos os custos ci de cada comando para uma notac~o muito mais simples que e mais concisa a e mais facilmente manuseada. Essa notac~o mais simples tambem tornara mais a facil a tarefa de determinar se um algoritmo e mais e ciente que um outro. ~ Comecamos apresentando o procedimento Ordena-Insercao com o \custo" de tempo de cada comando e o numero de vezes que cada comando e executado. Para cada j = 2; 3; : : :; n, onde n = tamanho A], usamos tj para representar o numero de vezes que o teste do laco enquanto na linha 5 e executado para aquele valor de j. Assumimos que os comentarios n~o s~o comandos executaveis, a a e portanto n~o tomam tempo. a
2 Ha algumas sutilezas aqui. Passos computacionais que especi camos em ingl^s s~o free a quentemente variantes de um procedimento que requer mais que apenas uma quantidade constante de tempo. Por exemplo, mais adiante neste livro podemos dizer \ordene os pontos pela coordenada x," o que, como veremos, leva mais que uma quantidade constante de tempo. Tambem, note que um comando que chama uma subrotina leva tempo constante, embora a subrotina, uma vez invocada, pode levar mais. Isto e, separamos o processo de chamar a subrotina|passando-lhe os par^metros, etc.|do processo de executar a subrotina. a

Analise da ordenac~o por inserc~o a a

1.2. ANALISANDO ALGORITMOS


~ Ordena-Insercao

9
custo numero de vezes

1 para j 2 ate tamanho A] c1 n 2 faca chave A j] c2 n 1 3 . Insira A j] na sequ^ncia e . ordenada A 1::j 1]: 0 n 1 4 i j 1 c4 n n1 P t 5 enquanto i > 0 and A i] > chave c5 Pj =2 j n (t 1) 6 faca A i + 1] A i] c6 Pj =2 j n (t 1) 7 i i 1 c7 j =2 j 8 A i + 1] chave c8 n 1 O tempo de execuc~o do algoritmo e a soma dos tempos de execuc~o para a a cada comando executado; um comando que leva ci passos para executar e e executado n vezes contribuira ci n ao tempo total de execuc~o.3 Para calcular a ~ T(n), o tempo de execuc~o de Ordena-Insercao, somamos os produtos das a colunas custo e numero de vezes, obtendo T(n) = c1n + c2(n 1) + c4(n 1) + c5 +c7
n X j =2 n X j =2

tj + c6

n X j =2

(tj 1)

(tj 1) + c8 (n 1):

Mesmo para entradas de um dado tamanho, o tempo de execuc~o de um a algoritmo pode depender de qual entrada daquele tamanho e dada. Por exemplo, ~ em Ordena-Insercao, o melhor caso ocorre se o vetor ja esta ordenado. Para cada j = 2; 3; : : :; n, encontramos ent~o que A i] chave na linha 5 quando i a tem seu valor inicial de j 1. Por conseguinte, tj = 1 para j = 2; 3; : : :; n, e o tempo de execuc~o do melhor caso e a T(n) = c1n + c2(n 1) + c4(n 1) + c5(n 1) + c8(n 1) = (c1 + c2 + c4 + c5 + c8 )n (c2 + c4 + c5 + c8 ): Esse tempo de execuc~o pode ser expresso como an + b para a e b constantes a que dependem dos custos ci 's dos comandos; trata-se portanto de uma func~o a linear de n. Se o vetor estiver ordenado na direc~o inversa|ou seja, em ordem decrescente| a o pior caso se estabelece. Temos que comparar cada elemento A j] com cada elemento em todo o subvetor ordenado A 1::j 1], e portanto tj = j para j = 2; 3; : : :; n. Observando que
n X j =2

j = n(n2+ 1) 1

e que
n X j =2

(j 1) = n(n2 1)

3 Essa caracter stica n~o necessariamente se veri ca para um recurso como memoria. Um a comando que faz refer^ncia a m palavras de memoria e e executado n vezes n~o necessariae a mente consome mn palavras de memoria no total.

10

~ CAP TULO 1. INTRODUCAO

(faremos uma revis~o de somatorios no Cap tulo 3), encontramos que no pior a ~ caso, o tempo de execuc~o de Ordena-Insercao e a T(n) = c1 n + c2 (n 1) + c4 (n 1) + c5 n(n2+ 1) 1 +c6 n(n2 1) + c7 n(n2 1) + c8 (n 1) = c25 + c26 + c27 n2 + c1 + c2 + c4 + c25 c26 c27 + c8 n (c2 + c4 + c5 + c8): Esse tempo de execuc~o do pior caso pode ser expresso como an2 + bn + c para a a, b e c constantes que novamente dependem dos custos ci 's; trata-se portanto de uma func~o quadratica de n. a Tipicamente, assim como na ordenac~o por inserc~o, o tempo de execuc~o de a a a um algoritmo e xo para uma dada entrada, embora em cap tulos subsequentes veremos alguns algoritmos \randomizados" interessantes cujo comportamento pode variar mesmo para uma dada entrada.

Analise do pior-caso e do caso-medio


Em nossa analise da ordenac~o por inserc~o, olhamos tanto para o melhor caso, a a no qual o vetor de entrada ja estava ordenado, quanto para o pior caso, no qual o vetor de entrada estava ordenado na direc~o inversa. Para o restante deste a livro, entretanto, normalmente nos concentraremos em buscar apenas o tempo de execuc~o no pior caso, isto e, o tempo mais longo de execuc~o para uma a a entrada qualquer de tamanho n. Damos tr^s raz~es para essa orientac~o. e o a O tempo de execuc~o no pior caso de um algoritmo e um limitante superior a para o tempo de execuc~o para qualquer entrada. Conhecendo-o nos da a uma garantia de que o algoritmo nunca levara um tempo mais longo. N~o precisamos fazer advinhac~es ensaiadas sobre o tempo de execuc~o e a o a esperamos com isso que ele nunca chegue a ser muito pior. Para alguns algoritmos, o pior caso ocorre com uma razoavel frequ^ncia. e Por exemplo, ao fazer uma busca num banco de dados por uma porc~o a espec ca de informac~o, o pior caso do algoritmo de busca frequentemente a ocorrera quando a informac~o n~o estiver presente no banco de dados. Em a a algumas aplicac~es de busca, as consultas por informac~o ausente podem o a ser frequentes. O \caso medio" e frequentemente t~o ruim quanto o pior caso. Suponha a que escolhamos aleatoriamente n numeros e apliquemos a ordenac~o por a inserc~o. Quanto tempo leva para determinar onde no subvetor A 1::j 1] a devemos inserir o elemento A j]? Em media, metade dos elementos em A 1::j 1] s~o menores que A j], e metade dos elementos s~o maiores. a a Em media, todavia, temos que veri car metade do subvetor A 1::j 1], portanto tj = j=2. Se calcularmos o tempo de execuc~o resultante no a caso medio, ele vai acabar sendo uma func~o quadratica do tamanho da a entrada, tal qual o tempo de execuc~o no pior caso. a

1.2. ANALISANDO ALGORITMOS

11

no caso medio ou esperado de um algoritmo. Um problema com trabal-

Em alguns casos espec cos, estaremos interessados no tempo de execuc~o a

har com uma analise do caso medio, entretanto, e que pode n~o estar claro o a que constitui uma entrada \media" para um problema espec co. Frequentemente, assumiremos que todas as entradas de um dado tamanho s~o igualmente a provaveis. Na pratica, essa suposic~o pode ser violada, mas um algoritmo rana domizado pode as vezes forcar que ela se veri que.

Ordem de crescimento
Temos usado algumas abstrac~es simpli cadoras para facilitar nossa analise do o ~ procedimento Ordena-Insercao. Primeiro, ignoramos o custo real de cada comando, usando as constantes ci para representar tais custos. Da , observamos que mesmo essas constantes nos d~o mais detalhes do que realmente precisamos: a o tempo de execuc~o no pior caso e an2 + bn + c para algumas constantes a, b e a c que dependem dos custos ci dos comandos. Ignoramos, portanto, n~o apenas a os reais custos dos comandos, mas tambem os custos abstratos ci . Vamos agora fazer mais uma abstrac~o simpli cadora. E a taxa de crescia mento, ou ordem de crescimento que realmente nos interessa. Consideraremos, portanto, apenas o termo de mais alto grau de uma formula (e.g., an2 ), pois os termos de mais baixa ordem s~o relativamente insigni cantes para n a grande. Tambem ignoramos o coe ciente constante do termo de maior grau, pois fatores constantes s~o menos signi cativos que a taxa de crescimento quando a se quer determinar a e ci^ncia computacional para entradas grandes. Por cone seguinte, escrevemos que a ordenac~o por inserc~o, por exemplo, tem um tempo a a de execuc~o no pior caso de (n2 ) (pronuncia-se \teta de n ao quadrado"). Usa aremos a notac~o informalmente neste cap tulo; ela sera de nida precisamente a no Cap tulo 2. Usualmente consideramos um algoritmo como sendo mais e ciente que um outro se seu tempo de execuc~o no pior caso tem uma ordem de crescimento a menor. Essa avaliac~o pode estar errada para entradas pequenas, mas para a entradas su cientemente grandes um algoritmo (n2 ), por exemplo, executara mais rapidamente no pior caso que um algoritmo (n3 ).

Exerc cios 1.2-1

Considere ordenar n numeros armazenados no vetor A primeiro achando o menor elemento de A e colocando-o na primeira posic~o de um outro vetor B. Da a encontre o segundo menor elemento de A e coloque-o na segunda posic~o de B. a Continue dessa maneira para os n elementos de A. Escreva o pseudocodigo para esse algoritmo, que e conhecido como ordenac~o por selec~o. D^ os tempos a a e de execuc~o no pior caso e no melhor caso da ordenac~o por selec~o em notac~o a a a a . Considere a busca linear novamente (veja Exerc cio 1.1-3). Quantos elementos da sequ^ncia de entrada precisam ser veri cados em media, assumindo que o e elemento sendo procurado e igualmente provavel de ser um elemento qualquer

1.2-2

12

~ CAP TULO 1. INTRODUCAO

no vetor? E no pior caso? Quais s~o os tempos de execuc~o da busca linear no a a caso medio e no pior caso em notac~o ? Justi que suas respostas. a

1.2-3

Considere o problema de determinar se uma sequ^ncia arbitraria hx1 ; x2; : : :; xni e de n numeros contem ocorr^ncias repetidas de algum numero. Mostre que isso e pode ser feito em tempo (n lg n), onde lg n representa log2 n. Considere o problema de calcular o valor de um polin^mio em um ponto. o Dados n coe cientes a0 ; a1; : : :; an 1 e um numero real x, desejamos calcular Pn 1 i 2 i=0 ai x . Descreva um algoritmo (n ) simples para esse problema. Descreva um algoritmo (n)-tempo que usa o seguinte metodo (chamado de regra de Horner) para reescrever o polin^mio o
n 1 X i=0

1.2-4

ai xi = ( (an 1x + an 2)x +

+ a1)x + a0:

1.2-5 1.2-6

Expresse a func~o n3 =1000 100n2 100n + 3 em termos da notac~o . a a Como podemos modi car praticamente qualquer algoritmo de forma que ele tenha um bom tempo de execuc~o no melhor caso? a

1.3 Desenhando algoritmos


Ha varias maneiras de se desenhar algoritmos. A ordenac~o por inserc~o usa a a uma abordagem incremental: tendo ordenado o subvetor A 1::j 1], inserimos o elemento A j] no seu lugar apropriado, resultando no subvetor ordenado A 1::j]. Nesta sec~o, examinamos uma abordagem alternativa de desenho de algorita mos, conhecida como \divis~o-e-conquista." Usaremos divis~o-e-conquista para a a desenhar um algoritmo de ordenac~o cujo tempo de execuc~o no pior caso e a a muito menor que o da ordenac~o por inserc~o. Uma vantagem dos algoritmos a a divis~o-e-conquista e que seus tempos de execuc~o s~o facilmente determinados a a a usando-se tecnicas que ser~o introduzidas no Cap tulo 4. a Muitos algoritmos uteis s~o recursivos na sua estrutura: para resolver um a dado problema, eles chamam a si poprios recursivamente uma ou mais vezes para lidar com subproblemas intimamente relacionados. Esses algoritmos tipicamente seguem uma abordagem divis~o-e-conquista: eles quebram o problema em a varios subproblemas que s~o semelhantes ao problema original porem menores a em tamanho, resolvem os subproblemas recursivamente, e a ent~o combinam a essas soluc~es para criar uma soluc~o para o problema original. o a O paradigma divis~o-e-conquista envolve tr^s passos a cada n vel da recurs~o: a e a

1.3.1 A abordagem divis~o-e-conquista a

1.3. DESENHANDO ALGORITMOS

13

Divida o problema em uma certa quantidade de subproblemas. Conquiste os subproblemas resolvendo-os recursivamente. Se os tamanhos do

subproblema s~o pequenos o su ciente, simplesmente resolva os subproba lemas de maneira direta. Combine as soluc~es para os subproblemas na soluc~o para o problema origio a nal. O algoritmo de ordenac~o por intercalac~o (do ingl^s, merge sort ) segue a a e de perto o paradigma divis~o-e-conquista. Intuitivamente, ele opera da seguinte a maneira. Divis~o: Divide a sequ^ncia de n elementos a ser ordenada em duas suba e sequ^ncias de n=2 elementos cada. e Conquista: Ordena as duas subsequ^ncias recursivamente usando a ordenac~o e a por intercalac~o. a Combinac~o: Intercala as duas subsequ^ncias ordenadas para produzir a rea e sposta ordenada. Chamamos a atenc~o para o fato de que a recurs~o \sai de baixo para cima" a a quando a sequ^ncia a ser ordenada tem comprimento 1, caso em que n~o ha e a trabalho a ser feito, pois toda sequ^ncia de comprimento 1 ja esta na ordem. e A operac~o chave do algoritmo de ordenac~o por intercalac~o e a intercalac~o a a a a de duas sequ^ncias ordenadas no passo \combinar." Para realizar a intercalac~o, e a usamos um procedimento auxiliar Intercala(A; p; q; r), onde A e um vetor e p, q, e r s~o ndices numerando elementos do vetor tais que p q < r. O proa cedimento assume que os subvetor A p::q] e A q +1::r] est~o na ordem desejada. a Ele os intercala para formar um unico subvetor ordenada que substitui o vetor corrente A p::r]. Embora deixemos o pseudocodigo como um exerc cio (veja Exerc cio 1.3-2), e facil imaginar um procedimento Intercala que leva (n), onde n = r p+1 e o numero de elementos sendo intercalados. Retornando ao nosso exemplo de jogo de cartas, suponha que tenhamos duas pilhas de cartas viradas para cima sobre uma mesa. Nosso passo basico consiste de escolher a menor das duas cartas no topo das pilhas, removendo-a da pilha (o que exp~e uma nova o carta topo-de-pilha), e colocando essa carta virada para baixo na pilha de sa da. Repetimos esse passo ate que uma pilha de entrada esteja vazia, quando ent~o a simplesmente tomamos a pilha de entrada e a colocamos virada para baixo na pilha de sa da. Computacionalmente, cada passo basico leva tempo constante, pois estamos checando apenas duas cartas topo-de-pilha. Como executamos no maximo n passos basicos, intercalar leva um tempo (n). Podemos agora usar o procedimento Intercala como uma subrotina no al~ goritmo de ordenac~o por intercalac~o. O procedimento Ordena-Intercalac ao(A; p; r) a a ordena os elementos no subvetor A p::r]. Se p r, o subvetor tem no maximo um elemento e esta portanto ja ordenado. Do contrario, o passo de dividir simplesmente calcula um ndice q que particiona A p::r] em dois subvetores: A p::q], contendo dn=2e elementos, e A q + 1::r], contendo bn=2c elementos.4

4 A express~o dxe denota o menor inteiro maior ou igual a x, e bxc denota o maior inteiro a menor ou igual a x. Essas notac~es s~o de nidas no Cap tulo 2. o a

14
~ Ordena-Intercalacao(A; p; r)

~ CAP TULO 1. INTRODUCAO

1 2 3 4 5

se p < r ent~o q b(p + r)=2c a

~ Ordena-Intercalacao(A; p; q) ~ Ordena-Intercalacao(A; q + 1; r) Intercala(A; p; q; r)

Se olharmos a operac~o do procedimento de-baixo-para-cima quando n e uma a pot^ncia de dois, o algoritmo consiste de intercalar de pares de sequ^ncias de e e 1-item para formar sequ^ncias ordenadas de comprimento 2, intercalar pares de e sequ^ncias de comprimento 2 para formar sequ^ncias ordenadas de comprimento e e 4, e assim por diante, ate que sequ^ncias de comprimento n=2 sejam intercaladas e para formar a sequ^ncia ordenada nal de comprimento n. A Figura 1.3 ilustra e esse processo. Quando um algoritmo contem uma chamada recursiva para si proprio, seu tempo de execuc~o pode frequentemente ser descrito por uma equac~o de a a recorr^ncia ou recorr^ncia, que descreve o tempo total de execuc~o soe e a bre um problema de tamanho n em termos do tempo de execuc~o sobre ena tradas menores. Podemos ent~o usar ferramentas matematicas para resolver a a recorr^ncia e estabelecer limitantes sobre o desempenho do algoritmo. e Uma recorr^ncia para o tempo de execuc~o de um algoritmo divis~o-ee a a conquista e baseada em tr^s passos do paradigma basico. Como ja foi dito e anteriormente, supomos que T(n) seja o tempo de execuc~o sobre um problema a de tamanho n. Se o tamanho do problema e su cientemente pequeno, digamos n c para alguma constante c, a soluc~o imediata leva tempo constante, que a escrevemos (1). Suponha que dividimos o problema em a subproblemas, cada um dos quais 1=b do tamanho do problema original. Se levamos um tempo D(n) para dividir o problema em subproblemas e um tempo C(n) para combinar as soluc~es para os subproblemas na soluc~o para o problema original, obtemos a o a recorr^ncia e (n) se n c; T(n) = aT (n=b) + D(n) + C(n) caso contrario: No Cap tulo 4, veremos como resolver recorr^ncias dessa forma. e

~ Ordena-Intercalacao(A; 1; tamanho A]), onde novamente tamanho A] = n.

Para ordenar toda a sequ^ncia A = hA 1]; A 2]; : ::; A n]i, fazemos uma chamada e

1.3.2 Analisando algoritmos divis~o-e-conquista a

Analise da ordenac~o por intercalac~o a a


~ Embora o pseudocodigo para Ordena-Intercalacao funcione corretamente quando o numero de elementos n~o e par, nossa analise baseada em recorr^ncia a e ca simpli cada se assumimos que o tamanho do problema original e uma pot^ncia de dois. Cada passo de dividir produz ent~o duas subsequ^ncias de e a e tamanho exatamente n=2. No Cap tulo 4, veremos que essa suposic~o n~o afeta a a a ordem de crescimento da soluc~o da recorr^ncia. a e

1.3. DESENHANDO ALGORITMOS

15

Raciocinamos da seguinte maneira de modo a arranjar a recorr^ncia para e T(n), o tempo de execuc~o no pior caso da ordenac~o por intercalac~o sobre n a a a numeros. A ordenac~o por intercalac~o sobre apenas um elemento leva tempo a a constante. Quando temos n > 1 elementos, quebramos o tempo de execuc~o da a seguinte maneira. Divis~o: O passo de dividir simplesmente calcula o meio do subvetor, que leva a tempo constante. Portanto, D(n) = (1). Conquista: Resolvemos recursivamente dois subproblemas, cada um de tamanho n=2, que contribui 2T (n=2) para o tempo de execuc~o. a Combinac~o: Ja observamos que o procedimento Intercala sobre um suba vetor de n elementos leva tempo (n), da C(n) = (n). Quando adicionamos as func~es D(n) e C(n) a analise da ordenac~o por o a intercalac~o, estamos adicionando uma func~o que e (n) e uma func~o que e a a a (1). Essa soma e uma func~o linear de n, ou seja, (n). Adicionando-a ao a termo 2T (n=2) do passo \conquistar" resulta na recorr^ncia para o pior caso da e ordenac~o por intercalac~o: a a (1) se n = 1; T(n) = 2T(n=2) + (n) se n > 1: No Cap tulo 4, mostraremos que T(n) e (n lg n), onde lg n representa log2 n. Para entradas su cientemente grandes, a ordenac~o por intercalac~o, com seu a a tempo de execuc~o (n lg n), supera em desempenho a ordenac~o por inserc~o, a a a cujo tempo de execuc~o e (n2 ), no pior caso. a

Usando a Figura 1.3 como um modelo, ilustre a operac~o da ordenac~o por a a intercalac~o sobre o vetor A = h3; 41; 52; 26;38;57;9;49i. a

Exerc cios 1.3-1


1.3-2

Escreva o pseudocodigo para Intercala(A; p; q; r). Use induc~o matematica para mostrar que a soluc~o da recorr^ncia a a e se n = 2; T(n) = 2 2T(n=2) + n se n = 2k ; k > 1 e T(n) = n lg n.

1.3-3

1.3-4

A ordenac~o por inserc~o pode ser expressa como um procedimento recursivo a a da seguinte maneira. De modo a ordenar A 1::n], ordenamos recursivamente A 1::n 1] e ent~o inserimos A n] no vetor ordenado A 1::n 1]. Escreva uma a recorr^ncia para o tempo de execuc~o dessa vers~o recursiva da ordenac~o por e a a a inserc~o. a

16

~ CAP TULO 1. INTRODUCAO

Voltando ao problema da busca (veja o Exerc cio 1.1-3), observe que se a sequ^ncia A esta ordenada, podemos checar o ponto medio da sequ^ncia contra e e v e eliminar metade da sequ^ncia de considerac~es posteriores. Busca binaria e o e um algoritmo que repete esse procedimento, dividindo pela metade o tamanho da porc~o remanescente da sequ^ncia a cada vez. Escreva um pseudocodigo, ita e erativo ou recursivo, para busca binaria. Argumente que o tempo de execuc~o a da busca binaria no pior caso e (lg n).
~ Observe que o laco enquanto das linhas 5{7 do procedimento Ordena-Insercao na Sec~o 1.1 usa busca linear para varrer (de-tras-para-frente) o subvetor ora denado A 1::j 1]. Podemos usar a busca binaria (veja Exerc cio 1.3-5) para melhorar o tempo de execuc~o total no-pior-caso da ordenac~o por inserc~o para a a a (n lg n).

1.3-5

1.3-6

1.3-7

? Descreva um algoritmo de tempo (n lg n) que, dado um conjunto S de n numeros reais e um outro numero real x, determina se existem ou n~o dois a elementos em S cuja soma seja exatamente x.

1.4 Resumo
Um bom algoritmo e como uma faca amolada|ele faz exatamente o que deve fazer com uma quantidade m nima de esforco aplicado. Usando o algoritmo errado para resolver um problema e como tentar cortar um pedaco de carne com uma chave de fenda: voc^ pode ate conseguir um resultado diger vel, mas e despendera consideravelmente mais esforco que o necessario, e o resultado n~o a deve ser esteticamente agradavel. Algoritmos concebidos para resolver o mesmo problema frequentemente diferem dramaticamente em e ci^ncia. Essas diferencas podem ser muito mais signi cae tivas que a diferenca entre um computador pessoal e um supercomputador. Como exemplo, vamos confrontar um supercomputador rodando ordenac~o por a inserc~o contra um pequeno computador pessoal rodando ordenac~o por intera a calac~o. Suponha que o supercomputador executa 100 milh~es de instruc~es a o o por segundo, enquanto que o computador pessoal executa apenas um milh~o de a instruc~es por segundo. Para tornar a diferenca ainda mais dramatica, suponha o que o melhor programador do mundo escreve o codigo da ordenac~o por inserc~o a a em linguagem de maquina para o supercomputador, e que o codigo resultante requeira 2n2 instruc~es de supercomputador para ordenar n numeros. A oro denac~o por intercalac~o, por outro lado, e programada para o computador a a pessoal por um programador medio usando uma linguagem de alto n vel com um compilador ine ciente, com codigo resultante levando 50n lg n instruc~es do o computador pessoal. Para ordenar um milh~o de numeros, o supercomputador a leva 2 (106)2 instruc~es = 20:000 segundos 5; 56 horas; o 108 instruc~es/segundo o

1.4. RESUMO
enquanto que o computador pessoal leva

17

50 106 lg 106 instruc~es 1:000 segundos 16; 67 minutos: o 106 instruc~es/segundo o Usando um algoritmo cujo tempo de execuc~o tem uma ordem mais baixa de a crescimento, mesmo com um compilador pobre, o computador pessoal roda 20 vezes mais rapido que o supercomputador! Esse exemplo mostra que algoritmos, tal qual hardware de computador, s~o a tecnologia. O desempenho total de um sistema depende de se escolher algoritmos e cientes tanto quanto de se escolher hardware rapido. Assim como avancos rapidos est~o sendo feitos em outras tecnologias de computadores, eles a est~o sendo feitos em algoritmos tambem. a

Exerc cios 1.4-1

Suponha que estejamos comparando implementac~es da ordenac~o por inserc~o o a a e da ordenac~o por interacalac~o na mesma maquina. Para entradas de tamanho a a n, a ordenac~o por inserc~o roda em 8n2 passos, enquanto que a ordenac~o por a a a intercalac~o roda em 64n lg n passos. Para quais valores de n a ordenac~o a a por inserc~o bate a ordenac~o por intercalac~o? Como se poderia reescrever a a a o pseudocodigo da ordenac~o por intercalac~o de modo a torna-la ainda mais a a rapida para entradas pequenas? Qual e o menor valor de n tal que um algoritmo cujo tempo de execuc~o e a 100n2 rode mais rapido que um algoritmo cujo tempo de execuc~o e 2n na a mesma maquina?

1.4-2

Problemas
1-1 Comparac~o de tempos de execuc~o a a
Para cada func~o f(n) e tempo t na tabela seguinte, determine o maior tamanho a n de um problema que pode ser resolvido em tempo t, assumindo que o algoritmo para resolver o problema leva f(n) microssegundos. 1 1 1 1 1 1 1 segundo minuto hora dia m^s ano seculo e lg n pn n n lg n n2 n3 2n n!

18

~ CAP TULO 1. INTRODUCAO

1-2 Ordenac~o por inserc~o para vetores pequenos na ordenac~o a a a por intercalac~o a
Embora a ordenac~o intercalac~o rode em (n lg n) de tempo no-pior-caso e a a a ordenac~o por inserc~o rode em (n2 ) de tempo no-pior-caso, os fatores a a constantes na ordenac~o por inserc~o a tornam mais rapida para n pequeno. a a Portanto, faz sentido usar a ordenac~o por inserc~o dentro da ordenac~o por a a a intercalac~o quando os subproblemas se tornam su cientemente pequenos. Cona sidere uma modi cac~o da ordenac~o por intercalac~o na qual n=k sublistas de a a a comprimento k s~o ordenadas usando a ordenac~o por inserc~o e ent~o intera a a a caladas usando o mecanismo padr~o de intercalac~o, onde k e um valor a ser a a determinado. a. Mostre que as n=k sublistas, cada uma de comprimento k, podem ser ordenadas pela ordenac~o por inserc~o em (nk) de tempo no-pior-caso. a a b. Mostre que as sublistas podem ser intercaladas em (n lg(n=k)) de tempo no-pior-caso. c. Dado que o algoritmo modi cado roda em (nk + n lg(n=k)) de tempo nopior-caso, qual e o maior valor assintotico (notac ao ) de k como uma func~o de n para o qual o algoritmo modi cado tem o mesmo tempo de a execuc~o assintotico que a ordenac~o por intercalac~o padr~o? a a a a d. Como k deve ser escolhido na pratica? Seja A 1::n] um vetor de n numeros distintos. Se i < j e A i] > A j], ent~o o a par (i; j) e chamado de uma invers~o de A. a a. Liste as cinco invers~es do vetor h2; 3; 8; 6; 1i. o b. Que vetor com elementos do conjunto f1; 2; : : :; ng tem o maximo de invers~es? Quantas? o c. Qual e a relac~o entre o tempo de execuc~o da ordenac~o por inserc~o e o a a a a numero de invers~es no vetor de entrada? Justi que sua resposta. o d. D^ um algoritmo que determina o numero de invers~es em qualquer pere o mutac~o sobre n elementos em (n lg n) de tempo no-pior-caso. (Suga est~o : Modi que a ordenac~o por intercalac~o.) a a a

1-3 Invers~es o

Notas do cap tulo


Existem muitos textos excelentes sobre o topico geral de algoritmos, incluindo os de Aho, Hopcroft, e Ullman 4, 5], Baase 14], Brassard e Bratley 33], Horowitz e Sahni 105], Knuth 121, 122, 123], Manber 142], Mehlhorn 144, 145, 146], Purdom e Brown 164], Reingold, Nievergelt, e Deo 167], Sedgewick 175], e Wilf 201]. Alguns dos aspectos mais praticos do desenho de algoritmos s~o a discutidos por Bentley 24, 25] e Gonnet 90]. Em 1968, Knuth publicou o primeiro de tr^s volumes com o t tulo geral e A Arte de Programac~o de Computadores 121, 122, 123]. O primeiro volume a

1.4. RESUMO

19

introduziu o estudo moderno de algoritmos de computadores com um foco sobre a analise do tempo de execuc~o, e a serie completa permanece como uma a refer^ncia envolvente e valorosa para muitos dos topicos apresentados aqui. See gundo Knuth, a palavra \algoritmo" e derivada do nome \al-Khow^rizm^," um a matematico persa do seculo nono. Aho, Hopcroft, e Ullman 4] advogaram a analise assintotica de algoritmos como um meio de comparar desempenho relativo. Eles tambem popularizaram o uso de relac~es de recorr^ncia para descrever os tempos de execuc~o de algoo e a ritmos recursivos. Knuth 123] prov^ um tratamento enciclopedico de muitos algoritmos de e ordenac~o. Sua comparac~o de algoritmos de ordenac~o (pagina 381) inclui a a a analises exatas de contagem-de-passos, como aquela realizada aqui para a ordenac~o por inserc~o. A discuss~o de Knuth da ordenac~o por inserc~o engloba a a a a a diversas variac~es do algoritmo. A mais importante delas e o algoritmo de o Shell, introduzido por D. L. Shell, que usa a ordenac~o por inserc~o sobre suba a sequ^ncias periodicas da entrada para produzir um algoritmo de ordenac~o mais e a rapido. Ordenac~o por intercalac~o tambem e descrita por Knuth. Ele relembra que a a um intercalador mec^nico capaz de intercalar duas pilhas de cart~es perfurados a o em uma unica leitura foi inventado em 1938. J. von Neumann, um dos pioneiros da ci^ncia da computac~o, parece ter escrito um programa para ordenac~o por e a a intercalac~o no computador EDVAC em 1945. a

20

~ CAP TULO 1. INTRODUCAO

Parte I

Fundamentos Matematicos

21

Introduc~o a
A analise de algoritmos frequentemente nos exige lancar m~o de um corpo de a ferramentas matematicas. Algumas dessas ferramentas s~o t~o simples quanto a a algebra de curso secundario, mas outras, tais como resoluc~o de recorr^ncias, a e podem ser novas para voc^. Esta parte do livro e um comp^ndio dos metodos e e e ferramentas que usaremos para analisar algoritmos. Esta organizada sobretudo para servir de refer^ncia, com um sabor tutorial para alguns topicos. e Sugerimos que voc^ n~o tente digerir toda essa matematica de uma so vez. e a D^ uma olhada rapida nos cap tulos desta parte para ver qual material eles e cont^m. Voc^ pode ent~o passar diretamente aos cap tulos que se concentram e e a em algoritmos. A medida que voc^ vai lendo aqueles cap tulos, entretanto, e volte a esta parte sempre que voc^ precisar de um melhor entendimento das e ferramentas utilizadas nas analises matematicas. Nesse ponto, contudo, voc^ vai e querer estudar cada um desses cap tulo na sua totalidade, de modo a adquirir um conhecimento fundamental rme nas tecnicas matematicas. O Cap tulo 2 de ne precisamente varias notac~es matematicas, um exemplo o da qual e a notac~o que voc^ encontrou no Cap tulo 1. O restante do Cap tulo a e 2 e sobretudo uma apresentac~o de notac~o matematica. Seu proposito e mais a a no sentido de assegurar que seu uso da notac~o combine com aquele usado neste a livro do que ensina-lo(a) novos conceitos matematicos. O Cap tulo 3 oferece metodos para calcular e encontrar limitantes para somatorios, que ocorrem frequentemente na analise de algoritmos. Muitas das formulas neste cap tulo podem ser encontradas em qualquer texto de calculo, mas voc^ vai achar conveniente ter esses metodos compilados em um so lugar. e Metodos para resolver recorr^ncias, que usamos para analisar a ordenac~o e a por intercalac~o no Cap tulo 1 e que veremos muitas vezes novamente, s~o dados a a no Cap tulo 4. Uma tecnica poderosa e o \metodo mestre," que pode ser usado para resolver recorr^ncias que surgem de algoritmos divis~o-e-conquista. Muito e a do Cap tulo 4 e dedicado a demonstrar a corretude do metodo mestre, embora que essa prova possa ser deixada para depois sem preju zo. O Cap tulo 5 contem de nic~es basicas e notac~es para conjuntos, relac~es, o o o func~es, grafos, e arvores. Esse cap tulo tambem da algumas propriedades o basicas de tais objetos matematicos. Esse material e essencial para um entendimento deste texto mas pode ser seguramente saltado se voc^ ja fez um e curso de matematica discreta. O Cap tulo 6 comeca com os princ pios elementares de contagem: permutac~es, combinac~es, e coisas do g^nero. O restante do cap tulo contem o o e de nic~es e propriedades de probabilidade basica. A maioria dos algoritmos o neste livro n~o requer probabilidade para sua analise, e portanto voc^ pode facila e mente omitir as ultimas sec~es do cap tulo numa primeira leitura, ate mesmo o 23

24 nem sequer passar uma vista nelas. Mais tarde, quando voc^ encontrar uma e analise probabil stica que deseja entender melhor, voc^ vai achar o Cap tulo 6 e bem organizado para servir de refer^ncia. e

Cap tulo 2

Crescimento de Func~es o
A ordem de crescimento do tempo de execuc~o de um algoritmo, de nida no a Cap tulo 1, da uma caracterizac~o simples da e ci^ncia do algoritmo e tambem a e nos permite comparar o desempenho relativo de algoritmos alternativos. Uma vez que o tamanho da entrada n chega a ser su cientemente grande, a ordenac~o a por intercalac~o, com seu tempo de execuc~o no-pior-caso de (n lg n), bate a a a ordenac~o por inserc~o, cujo tempo de execuc~o no-pior-caso e de (n2 ). Emba a a ora possamos as vezes determinar o tempo de execuc~o exato de um algoritmo, a tal qual zemos para a ordenac~o por inserc~o no Cap tulo 1, a precis~o exa a a tra usualmente n~o vale o esforco de calcula-la. Para entradas su cientemente a grandes, as constantes multiplicativas e os termos de baixa ordem de um tempo de execuc~o exato s~o dominados pelos efeitos do tamanho da entrada propriaa a mente dito. Quando olhamos para tamanhos de entrada su cientemente grandes a ponto de fazer com que somente a ordem de crescimento do tempo de execuc~o seja a relevante, estamos estudando a e ci^ncia assintotica de algoritmos. Isto e, ese tamos preocupados com o quanto o tempo de execuc~o de um algoritmo cresce a com o tamanho da entrada no limite , a medida que a entrada cresce sem fronteiras. Usualmente, um algoritmo que e assintoticamente mais e ciente sera a melhor escolha para todos os casos exceto para entradas muito pequenas. Este cap tulo estuda varios metodos padr~o para simpli car a analise assintotica a de algoritmos. A proxima sec~o comeca de nindo diversos tipos de \notac~o a a assintotica," das quais ja vimos um exemplo em notac~o . Varias convenc~es a o de notac~o usadas em todo este livro s~o ent~o apresentadas, e nalmente rea a a visamos o comportamento de func~es que comumente surgem na analise de o algoritmos.

2.1 Notac~o assintotica a


As notac~es que usamos para descrever o tempo de execuc~o assintotico de um o a algoritmo s~o de nidas em termos de func~es cujos dom nios s~o o conjunto a o a dos numeros naturais N = f0; 1; 2; : ::g. Tais notac~es s~o convenientes para o a descrever a func~o de tempo de execuc~o no-pior-caso T(n), que e usualmente a a 25

26

~ CAP TULO 2. CRESCIMENTO DE FUNCOES

de nida apenas sobre tamanhos de entrada inteiros. E as vezes conveniente, no entanto, abusar de notac~o assintotica de uma variedade de maneiras. Por a exemplo, a notac~o e facilmente estendida para o dom nio dos numeros reais a ou, alternativamente, restrita a um subconjunto dos numeros naturais. E importante, entretanto, entender o signi cado exato da notac~o de tal forma que a quando ela for abusada, ela n~o seja mal usada . Esta sec~o introduz alguns a a abusos comuns. No Cap tulo 1, achamos que o tempo de execuc~o no-pior-caso da ordenac~o a a por inserc~o e T (n) = (n2 ). Vamos de nir o que essa notac~o signi ca. Para a a uma dada func~o g(n), designamos por (g(n)) o conjunto de func~es a o (g(n)) = ff(n) : existem constantes positivas c1 ; c2; e n0 tal que 0 c1g(n) f(n) c2 g(n) para todo n n0g: Uma func~o f(n) pertence ao conjunto (g(n)) se existem constantes positia vas c1 e c2 tal que f(n) pode ser \imprensada" entre c1 g(n) e c2g(n), para n su cientemente grande. Embora (g(n)) seja um conjunto, escrevemos \f(n) = (g(n))" para indicar que f(n) e um membro de (g(n)), ou \f(n) 2 (g(n))." Esse abuso da igualdade para designar pertin^ncia a conjunto pode a princ pio e parecer confuso, mas veremos mais adiante nesta sec~o que ele tem suas vantaa gens. A Figura 2.1(a) da uma ilustrac~o intuitiva de func~es f(n) e g(n), onde a o f(n) = (g(n)). Para todos os valores de n a direita de n0, o valor de f(n) e igual ou maior que c1 g(n) e igual ou maior que c2 g(n). Em outras palavras, para todo n n0, a func~o f(n) e igual a g(n) dentro de um fator constante. a Dizemos que g(n) e um limitante assintoticamente justo para f(n). A de nic~o de (g(n)) requer que todo membro de (g(n)) seja assintotia camente n~o-negativo, ou seja, que f(n) seja n~o-negativo sempre que n for a a su cientemente grande. Consequentemente, a func~o g(n) propriamente dita a deve ser assintoticamente n~o-negativa. Essa suposic~o se veri ca tambem para a a as outras notac~es assintoticas de nidas neste cap tulo. o No Cap tulo 1, introduzimos uma noc~o informal da notac~o que implia a cava em jogar fora termos de baixa ordem e ignorar os coe cientes do termo de alta ordem. Vamos justi car brevemente essa intuic~o usando a de nic~o fora a mal para mostrar que 1 n2 3n = (n2 ). Para fazer isso, temos que determinar 2 constantes positivas c1 ; c2, e n0 tais que c1 n2 1 n2 3n c2 n2 2 para todo n n0. Dividindo por n2 da 1 3 c1 2 n c2. A inequac~o da direita pode ser satisfeita para qualquer valor de n 1 esa colhendo c2 1=2. Igualmente, a inequac~o da esquerda pode ser satisfeita a para qualquer valor de n 7 escolhendo c1 1=14. Da , escolhendo c1 = 1=14, 1 c2 = 1=2, e n0 = 7, podemos veri car que 2 n2 3n = (n2 ). Certamente,

Notac~o a

~ 2.1. NOTACAO ASSINTOTICA

27

outras escolhas para as constantes existem, mas o que importa e que alguma escolha exista. Observe que essas constantes dependem da func~o 2 n2 3n; uma a 1 2 ) usualmente pediria constantes diferentes. func~o diferente pertencente a (n a Podemos tambem usar a de nic~o formal para veri car que 6n3 6= (n2 ). a Suponha para efeito de contradic~o que c2 e n0 existem tal que 6n3 c2 n2 a para todo n n0. Mas ent~o n c2 =6, o que n~o e poss vel acontecer para n a a arbitrariamente grande, pois c2 e constante. Intuitivamente, os termos de mais baixa ordem de uma func~o assintota icamente positiva podem ser ignorados ao se determinar limitantes assintoticamente justos porque eles s~o insigni cantes para n grande. Uma frac~o a a minuscula do termo de mais alta ordem e su ciente para dominar os termos de mais baixa ordem. Por conseguinte, colocando c1 como um valor que seja um pouco menor que o coe ciente do termo de mais alta ordem e colocando c2 como um valor que seja um pouco maior permite que as desigualdades na de nic~o da notac~o sejam satisfeitas. O coe ciente do termo de mais alta a a ordem pode igualmente ser ignorado, pois ele apenas modi ca c1 e c2 por um fator constante igual ao coe ciente. Como exemplo, considere uma func~o quadratica qualquer f(n) = an2 + a bn + c, onde a, b, e c s~o constantes e a > 0. Jogando fora os termos de a mais baixa ordem e ignorando as constantes da f(n) = (n2 ). Formalmente, para mostrar a mesma coisa, tomamos as constantes c1 = a=4, c2 = 7a=4, p e n0 = 2 max((jbj=a); (jcj=a)). O leitor pode veri car que 0 c1 n2 an2 + bn + c c2n2 para todo n n0 . Em geral, para qualquer polin^mio o P a p(n) = d=0 ai ni , onde os ai s~o constantes e ad > 0, temos p(n) = (nd ) (veja i Problema 2-1). Como qualquer constante e um polin^mio de grau 0, podemos expressar o qualquer func~o constante como (n0 ), ou (1). Essa ultima notac~o e um pea a queno abuso, entretanto, porque n~o esta claro qual variavel tende ao in nito.1 a Frequentemente usaremos a notac~o (1) para indicar uma constante ou uma a func~o constante com respeito a alguma variavel. a A notac~o limita assintoticamente uma func~o por cima e por baixo. Quando a a temos apenas um limitante assintotico superior, usamos a notac~o O. Para a uma dada func~o g(n), denotamos por O(g(n)) o conjunto de func~es a o O(g(n)) = ff(n) : existem constantes positivas c; e n0 tal que 0 f(n) cg(n) para todo n n0g: Usamos notac~o O para dar um limitante superior sobre uma func~o, para a a dentro de um fator constante. A Figura 2.1(b) mostra a intuic~o por tras da a notac~o O. Para todos os valores de n a direita de n0, o valor de uma func~o a a f(n) esta no grafo de g(n) ou abaixo dele. Para indicar que uma func~o f(n) e um membro de O(g(n)), escrevemos a f(n) = O(g(n)). Observe que f(n) = (g(n)) implica que f(n) = O(g(n)), pois a notac~o e uma noc~o mais forte que a notac~o O. Escrita sob o ponto de a a a
1 O problema real e que nossa notac~o usual para func~es n~o distingue func~es de seus a o a o valores. No -calculo, os par^metros para uma func~o s~o claramente especi cados: a func~o a a a a n2 poderia ser escrita n:n2 , ou mesmo r:r2. Adotar uma notac~o rigorosa, entretanto, a complicaria manipulac~es algebricas, e portanto optamos por tolerar o abuso. o

Notac~o O a

28

~ CAP TULO 2. CRESCIMENTO DE FUNCOES

vista de teoria dos conjuntos, temos (g(n)) O(g(n)). Por conseguinte, nossa prova de que qualquer func~o quadratica an2 + bn + c, onde a > 0, pertence a a (n2 ) tambem mostra que qualquer func~o quadratica pertence a O(n2 ). O a que pode ser mais surpreendente e que qualquer func~o linear an + b pertence a a O(n2), que e facilmente veri cado tomando-se c = a + jbj e n0 = 1. Alguns leitores que tenham visto antes a notac~o O podem achar estranho a que tenhamos que escrever, por exemplo, n = O(n2). Na literatura, a notac~o a O e as vezes usada informalmente para descrever limitantes assintoticamente justos, isto e, o que de nimos usando a notac~o . Neste livro, entretanto, a quando escrevemos f(n) = O(g(n)), estamos meramente reivindicando que algum multiplo constante de g(n) e um limitante assintotico superior para f(n), sem qualquer reivindicac~o sobre o qu~o justo como limitante superior ele e. a a Distinguir limitantes assintoticos superiores de limitantes assintoticamente justos tem se tornado padr~o na literatura sobre algoritmos. a Usando a notac~o O, podemos frequentemente descrever o tempo de exa ecuc~o de um algoritmo meramente inspecionando a estrutura geral do algoa ritmo. Por exemplo, a estrutura de laco duplamente aninhado do algoritmo de ordenac~o por inserc~o do Cap tulo 1 imediatamente da um limitante superior a a de O(n2 ) sobre o tempo de execuc~o no-pior-caso: o custo do laco interno e a limitado por cima por O(1) (constante), os ndices i e j s~o ambos no maximo a n, e o laco interno e executado no maximo uma vez para cada um dos n2 pares de valores para i e j. Como a notac~o O descreve um limitante superior, quando a usamos para coa tar o tempo de execuc~o de um algoritmo no-pior-caso, por implicac~o tambem a a cotamos o tempo de execuc~o do algoritmo para entradas arbitrarias. Por cona seguinte, o limitante O(n2) para o tempo de execuc~o da ordenac~o por inserc~o a a a no-pior-caso tambem se aplicaa seu tempo de execuc~o para toda entrada. O a limitante (n2 ) para o tempo de execuc~o da ordenac~o por inserc~o no-piora a a caso, entretanto, n~o implica em um limitante (n2 ) para o tempo de execuc~o a a da ordenac~o por inserc~o para toda entrada. Por exemplo, vimos no Cap tulo a a 1 que quando a entrada ja esta ordenada, a ordenac~o por inserc~o roda num a a tempo (n). Tecnicamente, e um abuso dizer que o tempo de execuc~o da ordenac~o a a por inserc~o e O(n2), pois para um dado n, o tempo real de execuc~o depende a a da entrada espec ca de tamanho n. Isto e, o tempo de execuc~o n~o e bem a a uma func~o de n. O que queremos dizer quando a rmamos que \o tempo de a execuc~o e O(n2 )" e que o tempo de execuc~o no-pior-caso (que e uma func~o a a a de n) e O(n2), ou equivalentemente, independentemente da entrada espec ca de tamanho n seja escolhida para cada valor de n, o tempo de execuc~o para a aquele conjunto de entradas e O(n2).

Notac~o a

Assim como a notac~o O prov^ um limitante assintotico superior para uma a e func~o, a notac~o prov^ um limitante assintotico inferior . Para uma a a e dada func~o g(n), designamos por (g(n)) o conjunto de func~es a o (g(n)) = ff(n) : existem constantes positivas c; e n0 tal que 0 cg(n) f(n) para todo n n0 g:

~ 2.1. NOTACAO ASSINTOTICA

29

A intuic~o por tras da notac~o e mostrada na Figura 2.1(c). Para todos a a os valores n a direita de n0, o valor de f(n) esta sobre o grafo de g(n) ou acima. A partir das de nic~es das notac~es assintoticas que vimos ate agora, e facil o o demonstrar o seguinte teorema importante (veja Exerc cio 2.1-5).

Teorema 2.1

Para quaisquer duas func~es f(n) e g(n), f(n) = (g(n)) se e somente se o f(n) = O(g(n)) e f(n) = (g(n)).

Como exemplo da aplicac~o desse teorema, nossa demonstrac~o de que a a an2 + bn + c = (n2 ) para quaisquer constantes a, b e c, onde a > 0, imediatamente implica que an2 + bn + c = (n2 ) e que an2 + bn + c = O(n2). Na pratica, ao inves de usar o Teorema 2.1 para obter limitantes assintoticos superior e inferior a partir de limitantes assintoticos justos, como zemos para esse exemplo, normalmente usamos o teorema para provar limitantes assintoticos justos a partir dos limitantes assintoticos superior e inferior. Como a notac~o descreve um limitante inferior, quando a usamos para a estabelecer um limitante para o tempo de execuc~o de um algoritmo no-melhora caso, por implicac~o tambem estabelecemos um limitante para o tempo de exa ecuc~o do algoritmo para entradas arbitrarias. Por exemplo, o tempo de exa ecuc~o da ordenac~o por inserc~o no-melhor-caso e (n), o que implica que o a a a tempo de execuc~o da ordenac~o por inserc~o e (n). a a a O tempo de execuc~o da ordenac~o por inserc~o esta portanto entre (n) a a a e O(n2), pois ele se situa em algum lugar entre uma func~o linear de n e uma a func~o quadratica de n. Alem do mais, esses limitantes s~o assintoticamente a a t~o justos quanto poss vel: por exemplo, o tempo de execuc~o da ordenac~o a a a por inserc~o n~o e (n2), pois a ordenac~o por inserc~o roda num tempo (n) a a a a quando a entrada ja esta ordenada. N~o e contraditorio, entretanto, dizer que o a tempo de execuc~o da ordenac~o por inserc~o no-pior-caso e (n2), pois exist a a a uma entrada que faz com que o algoritmo leve um tempo (n2). Quando dizemos que o tempo de execuc~o (sem adjetivo ou complemento) de um algoritmo a e (g(n)), queremos dizer que independentemente de qual entrada espec ca de tamanho n seja escolhida para cada valor de n, o tempo de execuc~o para a aquele conjunto de entradas e no m nimo uma constante vezes g(n), para n su cientemente grande. Ja vimos como a notac~o assintotica pode ser usada em formulas matematicas. a Por exemplo, ao introduzir a notac~o O, escrevemos \n = O(n2 )." Poder amos a tambem escrever 2n2 + 3n + 1 = 2n2 + (n). Como devemos interpretar tais formulas? Quando a notac~o assintotica esta sozinha no lado direito de uma equac~o, a a como em n = O(n2 ), ja de nimos que o sinal de igualdade signi ca pertin^ncia e a um conjunto: n 2 O(n2 ). Em geral, no entanto, quando a notac~o assintotica a aparece em uma formula, a interpretamos como representando alguma func~o a an^nima que n~o cuidamos em nomear. Por exemplo, a formula 2n2 + 3n + 1 = o a 2n2 + (n) signi ca que 2n2 + 3n + 1 = 2n2 + f(n), onde f(n) a alguma func~o a no conjunto (n). Nesse caso, f(n) = 3n + 1, que e de fato (n).

Notac~o assintotica em equac~es a o

30

~ CAP TULO 2. CRESCIMENTO DE FUNCOES

Usando a notac~o assintotica dessa maneira pode ajudar a eliminar detalhes a inessenciais e notac~o desnecessaria em uma equac~o. Por exemplo, no Cap tulo a a 1 expressamos o tempo de execuc~o da ordenac~o por intercalac~o no-pior-caso a a a como a recorr^ncia e T(n) = 2T(n=2) + (n). Se estamos interessados apenas no comportamento assintotico de T (n), n~o a ha raz~o para especi car exatamente todos os termos de baixa ordem; ele s~o a a todos entendidos como sendo inclu dos na func~o an^nima denotada pelo termo a o (n). O numero de func~es an^nimas em uma express~o e entendido como sendo o o a igual ao numero de vezes que uma notac~o assintotica aparece. Por exemplo, a na express~o a
n X i=1

O(i),

existe apenas uma unica func~o an^nima (uma func~o de i). Essa express~o a o a a n~o e portanto a mesma que O(1) +O(2) +: : :+O(n), que n~o tem exatamente a a uma interpretac~o limpa. a Em alguns casos, a notac~o assintotica aparece no lado esquerdo de uma a equac~o, tal qual em a 2n2 + (n) = (n2 ). Interpretamos tais equac~es usando a seguinte regra: Independentemente de o
como as func~es an^nimas seja escolhidas no lado esquerdo do sinal de igualo o dade, existe uma maneira de escolher as func~es an^nimas do lado direito do o o sinal de igualdade de modo a tornar a equac~o valida . Por conseguinte, o signi a cado de nosso exemplo e que para qualquer func~o f(n) 2 (n), existe alguma a

func~o g(n) 2 (n2 ) tal que 2n2 +f(n) = g(n) para todo n. Em outras palavras, a o lado direito de uma equac~o prov^ um n vel mais grosseiro de detalhe que o a e lado esquerdo.

Uma boa quantidade de tais relacionamentos podem ser encadeados, tal como em 2n2 + 3n + 1 = 2n2 + (n) = (n2 ): Podemos interpretar cada equac~o separadamente pela regra acima. A primeira a equac~o diz que existe alguma func~o f(n) 2 (n) tal que 2n2 + 3n + 1 = a a 2n2 + f(n) para todo n. A segunda equac~o diz que para qualquer func~o a a g(n) 2 (n) (tal qual a f(n) ja mencionada), existe alguma func~o h(n) 2 (n2 ) a tal que 2n2 +g(n) = h(n) para todo n. Note que essa interpretac~o implica que a 2n2 + 3n + 1 = (n2 ), que e o que o encadeamento de equac~es intuitivamente o nos da.

~ 2.1. NOTACAO ASSINTOTICA

31

O limitante assintotico superior fornecido pela notac~o O pode ou n~o ser assa a intoticamente justo. O limitante 2n2 = O(n2 ) e assintoticamente justo, mas o limitante 2n = O(n2) n~o o e. Usamos a notac~o o para designar um limitante a a superior que n~o e assintoticamente justo. Formalmente de nimos o(g(n)) (\pea queno `o' de g de n") como o conjunto o(g(n)) = ff(n) : para qualquer constante positiva c > 0; existe uma constante n0 > 0 tal que 0 f(n) cg(n) para todo n n0g: Por exemplo, 2n = o(n2 ), porem 2n2 6= o(n2 ). As de nic~es da notac~o O e da notac~o o s~o semelhantes. A principal o a a a diferenca e que em f(n) = O(g(n)), o limitante 0 f(n) cg(n) se veri ca para alguma constante c > 0, porem em f(n) = o(g(n)), o limitante 0 f(n) cg(n) se veri ca para todas as constantes c > 0. Intuitivamente, na notac~o o a func~o a a f(n) torna-se insigni cante em relac~o a g(n) a medida que n se aproxima do a in nito; isto e, lim f(n) = 0. n!1 g(n) Alguns autores usam esse limite como uma de nic~o da notac~o o; a de nic~o a a a neste livro tambem restringe as func~es an^nimas as assintoticamente n~oo o a negativas.

Notac~o o a

Notac~o ! a

Por analogia, a notac~o ! esta para a notac~o assim como a notac~o o esta a a a para a notac~o O. Usamos a notac~o ! para designar um limitante inferior que a a n~o e assintoticamente justo. Uma maneira de de n -lo e atraves de a f(n) 2 !(g(n)) se e somente se g(n) 2 o(f(n)). Formalmente, entretanto, de nimos !(g(n)) (\pequeno omega de g de n") como sendo o conjunto !(g(n)) = ff(n) : para qualquer constante positiva c > 0; existe uma constante n0 > 0 tal que 0 cg(n) f(n) para todo n n0 g: Por exemplo, n2 =2 = !(n), porem n2=2 6= !(n2 ). A relac~o f(n) = !(g(n)) a implica que lim f(n) = 1, n!1 g(n) se o limite existe. Isto e, f(n) torna-se arbitrariamente grande em relac~o a a g(n) a medida que n se aproxima de in nito.

Comparac~o de func~es a o

Muitas das propriedades relacionais dos numeros reais aplicam-se tambem a comparac~es assintoticas. Para o que segue, assuma que f(n) e g(n) s~o assino a

32 toticamente positivas.

~ CAP TULO 2. CRESCIMENTO DE FUNCOES


f(n) = (g(n)) f(n) = O(g(n)) f(n) = (g(n)) f(n) = o(g(n)) f(n) = !(g(n)) e e e e e g(n) = (h(n)) g(n) = O(h(n)) g(n) = (h(n)) g(n) = o(h(n)) g(n) = !(h(n)) implica implica implica implica implica f(n) = (h(n)); f(n) = O(h(n)); f(n) = (h(n)); f(n) = o(h(n)); f(n) = !(h(n)):

Transitividade:

Re exividade: Simetria:

f(n) = (f(n)); f(n) = O(f(n)); f(n) = (f(n)): f(n) = (g(n)) se e somente se g(n) = (f(n)):

f(n) = O(g(n)) se e somente se g(n) = (f(n)); f(n) = o(g(n)) se e somente se g(n) = !(f(n)): Devido ao fato de que essas propriedades se veri cam para notac~es assintoticas, o pode-se fazer uma analogia entre a comparac~o assintotica de duas func~es f e a o g e a comparac~o de dois numeros reais a e b: a f(n) = O(g(n)) a b; f(n) = (g(n)) a b; f(n) = (g(n)) a = b; f(n) = o(g(n)) a < b; f(n) = !(g(n)) a > b: Uma propriedade dos numeros reais, no entanto, n~o se transporta para a a notac~o assintotica: a

Simetria Transposta:

Tricotomia: Para dois numeros reais quaisquer a e b, exatamente uma das


seguintes condic~es deve se veri car: a < b, a = b, ou a > b. o Embora quaisquer dois numeros reais possam ser comparados, nem todas as func~es s~o assintoticamente comparaveis. Isto e, para duas func~es f(n) e o a o g(n), pode ser o caso que nem f(n) = O(g(n)) nem f(n) = (g(n)) se veri que. Por exemplo, as func~es n e n1+sin n n~o podem ser comparadas usando notac~o o a a assintotica, pois o valor do expoente em n1+sin n oscila entre 0 e 2, tomando todos os valores no intervalo.

Exerc cios 2.1-1


2.1-2

Sejam f(n) e g(n) func~es assintoticamente n~o-negativas. Usando a de nic~o o a a basica da notac~o , demonstre que max(f(n); g(n)) = (f(n) + g(n)). a Mostre que para quaisquer constantes reais a e b, onde b > 0, (n + a)b = (nb ). (2.2)

~ ~ ~ 2.2. NOTACOES PADRAO E FUNCOES USUAIS

33

2.1-3 2.1-4

Explique por que o enunciado \O tempo de execuc~o do algoritmo A e pelo a menos O(n2 )," n~o tem conteudo. a 2n+1 = O(2n)? 22n = O(2n)?

2.1-5 2.1-6

Demonstre o Teorema 2.1. Demonstre que o tempo de execuc~o de um algoritmo e (g(n)) se e somente a se seu tempo de execuc~o no-pior-caso e O(g(n)) e seu tempo de execuc~o noa a melhor-caso e (g(n)).

2.1-7 2.1-8

Demonstre que o(g(n)) \ !(g(n)) e o conjunto vazio. Podemos estender nossa notac~o para o caso de dois par^metros n e m que a a podem chegar a um valor in nito independentemente e a taxas diferentes. Para uma dada func~o g(n; m), designamos por O(g(n; m)) o conjunto de func~es a o O(g(n; m)) = ff(n; m) : existem constantes positivas c; n0; e m0 tais que 0 f(n; m) cg(n; m) para todo n n0 e m m0 g: D^ as de nic~es correspondentes para (g(n; m)) e (g(n; m)). e o

2.2 Notac~es padr~o e func~es usuais o a o


Esta sec~o rev^ algumas func~es e notac~es matematicas padr~o e explora as a e o o a relac~es entre elas. Ilustra tambem o uso das notac~es assintoticas. o o Uma func~o f(n) e monotonicamente crescente se m n implica f(m) a f(n). Semelhantemente, ela e monotonicamente decrescente se m n implica f(m) f(n). Uma func~o f(n) e estritamente crescente se m < n a implica f(m) < f(n) e estritamente decrescente se m > n implica f(m) > f(n). Para qualquer numero real x, designamos o maior inteiro menor ou igual a x por bxc (leia \o piso de x") e o menor inteiro maior ou igual a x por dxe (leia \o teto de x"). Para todo real x, x 1 < bxc x

Monotonicidade

Pisos e tetos

dxe < x + 1.

34 Para qualquer inteiro n,

~ CAP TULO 2. CRESCIMENTO DE FUNCOES

dn=2e + bn=2c = n,
e para qualquer inteiro n e inteiros a 6= 0 e b 6= 0,

ddn=ae=be = dn=abe bbn=ac=bc = bn=abc


As func~es de piso e teto s~o monotonicamente crescentes. o a

(2.3) (2.4)

Polin^mios o
d X i=0

Dado um inteiro positivo d, um polin^mio em n de grau d e uma func~o o a p(n) da forma ai ni ,

p(n) =

onde as constantes a0; a1; : : :; ad s~o os coe cientes do polin^mio e ad 6= 0. a o Um polin^mio e assintoticamente positivo se e somente se ad > 0. Para um o polin^mio assintoticamente positivo p(n) de grau d, temos p(n) = (nd ). Para o qualquer constante real a 0, a func~o na e monotonicamente crescente, e para a qualquer constante real a 0, a func~o na e monotonicamente decrescente. a Dizemos que uma func~o f(n) e polinomialmente limitada se f(n) = nO(1) , a o que e equivalente a dizer que f(n) = O(nk ) para alguma constante k (veja Exerc cio 2.2-2). Para todos os reais a 6= 0, m, e n, temos as seguintes igualdades: a0 = 1; a1 = a; a 1 = 1=a; m )n = amn ; (a (am )n = (an )m ; am an = am+n : Para todo n e todo a 1, a func~o an e monotonicamente crescente em n. a Quando conveniente, assumiremos que 00 = 1. As taxas de crescimento de polin^mios e exponenciais podem ser relacionadas o pelo seguinte fato. Para todas as constantes reais a e b tais que a > 1,
b lim n n!1 an

Exponenciais

= 0,

(2.5)

do qual podemos concluir que nb = o(an ).

~ ~ ~ 2.2. NOTACOES PADRAO E FUNCOES USUAIS

35

Por conseguinte, qualquer func~o exponencial cresce mais rapido que qualquer a polin^mio. o Usando e para designar 2; 71828 : : :, a base da func~o de logaritmo natural, a temos que para todo real x,
X i 2 3 ex = 1 + x + x + x + : : : = x , (2.6) 2! 3! i! i=0 onde \!" denota a func~o fatorial de nida mais adiante nesta sec~o. Para todo a a real x, temos a desigualdade

ex 1 + x, onde a igualdade se veri ca apenas quando x = 0. Quando jxj a aproximac~o a 1 + x ex 1 + x + x2 . Quando x ! 0, a aproximac~o de ex por 1 + x e bastante boa: a ex = 1 + x + (x2 ).

(2.7) 1, temos (2.8)

(Nessa equac~o, a notac~o assintotica e usada para descrever o comportamento a a no limite a medida que x ! 0 ao inves de x ! 1.) Temos que para todo x, x n lim 1 + n = ex . n!1 Usaremos as seguintes notac~es: o lg n = log2 n (logaritmo binario); ln n = loge n (logaritmo natural); lgk n = (lg n)k (exponenciac~o); a lg lg n = lg(lg n) (composic~o): a Uma convenc~o notacional importante que adotaremos e que func~es logar tmicas a o ser~o aplicadas apenas ao termo seguinte na formula , de tal forma que lg n + k a signi cara (lg n) + k e n~o lg(n + k). Para n > 0 e b > 1, a func~o logb n e a a estritamente crescente. Para todos os reais a > 0, b > 0, c > 0, e n a = blogb a ; logc (ab) = logc a + logc b; logb an = n logb a; logb a = logc a ; (2.9) logc b logb(1=a) = logb a; 1 logb a = log b ; a alogb n = nlogb a :

Logaritmos

36

~ CAP TULO 2. CRESCIMENTO DE FUNCOES

Como a mudanca de base de um logaritmo de uma constante para outra apenas muda o valor do logaritmo por um fator constante, usaremos frequentemente a notac~o \lg n" quando n~o queremos dar import^ncia a fatores cona a a stantes, como por exemplo na notac~o O. Cientistas da computac~o acham o 2 a a a base mais natural para logaritmos porque muitos algoritmos e estruturas de dados envolvem dividir um problema em duas partes. Ha uma expans~o simples em serie para ln(1 + x) quando jxj < 1: a 3 4 5 2 ln(1 + x) = x x + x x + x : : : . 2 3 4 5 Temos tambem as seguintes desigualdades para x > 1: x (2.10) 1 + x ln(1 + x) x, onde a igualdade se veri ca apenas para x = 0. Dizemos que uma func~o f(n) e polilogaritmicamente limitada se f(n) = a lgO(1) n. Podemos relacionar o crescimento de polin^mios e polilogaritmos subo stituindo n por lg n e a por 2a na equac~o (2.5), resultando em a
b b lim lg lgn = nlim lg an = 0: n n!1 2a !1 n Desse limite, podemos concluir que

lgb n = o(na ) para qualquer constante a > 0. Por conseguinte, qualquer func~o polinomial a positiva cresce mais rapido que qualquer func~o polilogar tmica. a

Fatoriais
A notac~o n! (leia \n fatorial") e de nida para inteiros n 0 da seguinte forma a n! = 1 (n 1)! se n = 0; n se n > 0: Por conseguinte, n! = 1 2 3 n. Um limitante superior fraco para a func~o fatorial e n! nn, pois cada um a dos n termos no produto fatorial e no maximo n. A aproximac~o de Stirling , a n p 1 n! = 2 n n 1+ n , (2.11) e onde e e a base do logaritmo natural, nos da um limitante superior mais justo, e tambem um limitante inferior. Usando a aproximac~o de Stirling, pode-se a demonstrar que n! = o(nn); n! = !(2n); lg(n!) = (n lg n): Os seguintes limitantes tambem se veri cam para todo n:

~ ~ ~ 2.2. NOTACOES PADRAO E FUNCOES USUAIS

37 (2.12)

n n+(1=12n) p n! 2 n n 2 n n e e

Usamos a notac~o lg n (leia \log asterisco de n") para designar o logaritmo a iterado, que e de nido como segue. Suponha que a func~o lg(i) n seja de nida a recursivamente para inteiros n~o-negativos i da seguinte forma a 8 se i = 0; < n lg(i) n = : lg(lg(i 1) n) se i > 0 e lg(i 1) n > 0; inde nido se i > 0 e lg(i 1) n 0 ou lg(i 1) n for inde nido: Assegure-se de distinguir lg(i) n (a func~o logaritmo aplicada i vezes em cadeia, a comecando com o argumento n) de lgi n (o logaritmo de n elevado a i-esima pot^ncia). A func~o logaritmo iterado e de nida como e a lg n = min i 0 : lg(i) n 1 . O logaritmo iterado e uma func~o que cresce muito lentamente: a lg 2 = 1; lg 4 = 2; lg 16 = 3; lg 65336 = 4; lg (265336) = 5: Como o numero de atomos no universo observavel esta estimado em cerca de 1080, que e muito menos que 265336, raramente encontramos um valor de n tal que lg n > 5.
n o

A func~o logaritmo iterado a

Numeros de Fibonacci Os numeros de Fibonacci s~o de nidos pela seguinte recorr^ncia: a e


F0 = 0; F1 = 1; (2.13) Fi = Fi 1 + Fi 2 para i 2: Por conseguinte, cada numero de Fibonacci e a soma dos dois numeros anteriores, resultando na sequ^ncia e 0; 1; 1; 2; 3;5;8; 13; 21; 34; 55; ::: . Os numeros de Fibonacci est~o relacionados com a raz~o dourada a a seu conjugado ^, que s~o dados pela seguintes formulas: a = = ^ = = 1+ 5 2 1; 61803:::; p 1 5 2 0; 61803:::: e ao

(2.14)

38

~ CAP TULO 2. CRESCIMENTO DE FUNCOES

Especi camente, temos i ^i (2.15) Fi = p , 5 que podep demonstrado por induc~o (Exerc cio 2.2-7). Como j ^j < 1, temos ser p a que j ^ij= 5 < 1= 5 < 1=2, de modo que o i-esimo numero de Fibonacci Fi e p igual a i = 5 arredondado para o inteiro mais proximo. Por conseguinte, os numeros de Fibonacci crescem exponencialmente.

Mostre que se f(n) e g(n) s~o func~es monotonicamente crescentes, ent~o tambem a o a o s~o as func~es f(n) + g(n) e f(g(n)), e se f(n) e g(n) s~o alem disso n~oa o a a negativas, ent~o f(n) g(n) e monotonicamente crescente. a Use a de nic~o da notac~o O para mostrar que T(n) = nO(1) se e somente se a a existe uma constante k > 0 tal que T (n) = O(nk ).

Exerc cios 2.2-1

2.2-2

2.2-3

Demonstre a equac~o (2.9). a

2.2-4

Demonstre que lg(n!) = (n lg n) e que n! = o(nn ). mente limitada?

2.2-5 ? A func~o dlg ne! e polinomialmente limitada? A func~o dlg lg ne! e polinomiala a

2.2-6 ? 2.2-7

Qual das duas e assintoticamente maior: lg(lg n) ou lg (lg n)? Prove por p ao que o i-esimo numero de Fibonacci satisfaz a igualdade Fi = induc~ a ( i ^i )= 5, onde e a raz~o de ouro e ^ seu conjugado.

2.2-8

Demonstre que para i 0, o (i + 2)-esimo numero de Fibonacci satisfaz Fi+2 i.

Problemas
Seja

2-1 Comportamento assintotico de polin^mios o

~ ~ ~ 2.2. NOTACOES PADRAO E FUNCOES USUAIS


p(n) =
d X i=0 ad > 0, um polin^mio em n, e suponha que o

39

aini ,

onde k seja uma constante. Use as de nic~es das notac~es assintoticas para provar as seguintes propriedades. o o

a. Se k d, ent~o p(n) = O(nk ). a b. Se k d, ent~o p(n) = (nk ). a c. Se k = d, ent~o p(n) = (nk ). a d. Se k > d, ent~o p(n) = o(nk ). a e. Se k < d, ent~o p(n) = !(nk ). a
Indique, para cada par de express~es (A; B) na tabela abaixo, se A e O, o, , o !, ou de B. Assuma que k 1, > 0, e c > 1 s~o constantes. Sua resposta a deve no formato da tabela com \sim" ou \n~o" escrito em cada quadradinho. a O o ! A B a. lgk n n b. pk n cn sin n c. n n d. 2n 2n=2 lg m e. n mlg n f. lg(n!) lg(nn)

2-2 Crescimentos assintoticos relativos

2-3 Ordenando por taxas de crescimento assintotico a. Estabeleca uma hierarquia entre as seguintes func~es por ordem de crescio
mento; isto e, encontre um arranjo g1 ; g2; : : :; g30 das func~es satisfazendo o g1 = (g2 ), g2 = (g3 ), : : :, g29 = (g30 ). Particione sua lista em classes de equival^ncia tais que f(n) e g(n) estejam na mesma classe se e somente e se f(n) = (g(n)). lg(lg nn)

n!n (lg n)! 2lg n ( 2)lg n n2 2n 3 3 n lg lg(n!) 22 n1= lg n 2 n nlg lg n ln lnn lg n n 2 ln n p 1 n 2lg n (lg n)lg n en 4lg n (n + 1)! lg+1 p n 2n n lg n 22n lg (lg n) 2 2 lg n b. D^ um exemplo de uma unica func~o n~o-negativa f(n) tal que para todas e a a as func~es gi(n) na parte (a), f(n) nem seja O(gi(n)) nem (gi (n)). o Sejam f(n) e g(n) func~es assintoticamente positivas. Prove ou d^ um contrao e exemplo para cada uma das seguintes conjecturas.

2-4 Propriedades das notac~es assintoticas o

40

~ CAP TULO 2. CRESCIMENTO DE FUNCOES

a. f(n) = O(g(n)) implica g(n) = O(f(n)). b. f(n) + g(n) = (min(f(n); g(n))). c. f(n) = O(g(n)) implica lg(f(n)) = O(lg(g(n))), onde lg(g(n)) > 0 e f(n) 1
para todo n su cientemente grande. d. f(n) = O(g(n)) implica 2f (n) = O(2g(n). e. f(n) = O((f(n))2 ). f. f(n) = O(g(n)) implica g(n) = (f(n)). g. f(n) = (f(n=2)). h. f(n) + o(f(n)) = (f(n)).

Alguns autores de nem de uma maneira um pouco diferente da que de nimos; vamos usar 1 (leia \^mega in nito") para essa de nic~o alternativa. Dizemos o a que f(n) = 1 (g(n)) se existe uma constante positiva c tal que f(n) cg(n) 0 para um numero in nito de inteiros n. a. Mostre que para quaisquer duas func~es f(n) e g(n) que sejam assintoticao mente n~o-negativas, ou f(n) = O(g(n)) ou f(n) = 1 (g(n)) ou ambos, a enquanto que isso n~o e verdade se usarmos no lugar de 1 . a b. Descreva as poss veis vantagens e desvantagens de se usar 1 ao inves de para caracterizar os tempos de execuc~o de programas. a Alguns autores tambem de nem O de uma maneira um pouco diferente; vamos usar O0 para a de nic~o alternativa. Dizemos que f(n) = O0 (g(n)) se e somente a se jf(n)j = O(g(n)). c. O que acontece com cada uma das direc~es do \se e somente se" no Teorema o 2.1 segundo essa nova de nic~o? a ~ Alguns autores de nem O (leia \oh-suave") para signi car O com fatores logar tmicos ignorados: ~ O(g(n)) = ff(n) : existem constantes positivas c; k; e n0 tais que 0 f(n) cg(n) lgk n para todo n n0 g; d. De na ~ e ~ . Demonstre o analogo correspondente do Teorema 2.1.

2-5 Variac~es sobre O e o

2-6 Func~es iteradas o

O operador de iterac~o \ " usado na func~o lg pode ser aplicado a func~es a a o monotonicamente crescentes sobre os reais. Para uma func~o f satisfazendo a f(n) < n, de nimos a func~o f (i) recursivamente para inteiros n~o-negativos a a por f (i) (n) = f(f (i 1) (n)) se i > 0; n se i = 0:

~ ~ ~ 2.2. NOTACOES PADRAO E FUNCOES USUAIS


Para uma dada constante c 2 R, de nimos a func~o iterada fc por a fc (n) = minfi 0 : f (i) (n) cg,

41

que n~o precisa estar bem de nida em todos os casos. Em outras palavras, a a quantidade fc (n) e o numero de aplicac~es iteradas da func~o f necessarias o a para reduzir seu argumento para c ou menos. Para cada uma das seguintes func~es f(n) e constantes c, d^ um limitante o e t~o justo quanto poss vel para fc (n). a fc f(n) c a. lg n 1 b. n 1 0 c. n=2 1 d. n=2 2 e . pn 2 f . pn 1 g. n1=3 2 h. n= lg n 2

Notas do cap tulo


Knuth 121] recupera a origem da notac~o O a partir de um texto em teoria a dos numeros de autoria de P. Bachmann em 1892. A notac~o o foi inventada a por E. Landau em 1909 para sua discuss~o da distribuic~o dos numeros primos. a a As notac~es e foram advogadas por Knuth 124] para corrigir a pratica o popular, porem tecnicamente desajeitada, na literatura de se usar a notac~o a O para ambos os limitantes superior e inferior. Muitas pessoas continuam a usar a notac~o O onde a notac~o e tecnicamente mais precisa. Maiores a a discuss~es sobre a historia e o desenvolvimento das notac~es assintoticas podem o o ser encontradas em Knuth 121,124] e Brassard e Bratley 33]. Nem todos os autores de nem as notac~es assintoticas da mesma maneira, o embora as diversas de nic~es est~o de acordo na maioria das situac~es. Algumas o a o das de nic~es alternativas abrangem func~es que n~o s~o assintoticamente n~oo o a a a negativas, desde que seus valores absolutos sejam apropriadamente limitados. Outras propriedades das func~es matematicas elementares podem ser encono tradas em qualquer refer^ncia matematica boa, tal como Abramowitz e Stegun e 1] ou Beyer 27], ou num livro de calculo, como por exemplo Apostol 12] ou Thomas e Finney 192]. Knuth 121] contem uma riqueza de material sobre matematica discreta tal qual utilizada em ci^ncia da computac~o. e a

42

~ CAP TULO 2. CRESCIMENTO DE FUNCOES

Cap tulo 3

Somatorios
Quando um algoritmo contem instruc~es iterativas de controle tais como um o laco while ou for, seu tempo de execuc~o pode ser expresso como a soma dos a tempos gastos em cada execuc~o do corpo do laco. Por exemplo, encontramos a na Sec~o 1.2 que a j-esima iterac~o da ordenac~o por inserc~o levou tempo proa a a a porcional a j no pior caso. Somando o tempo gasto em cada iterac~o, obtivemos a o somatorio (ou serie)
n X j =2

j.

O calculo esse somatorio resultou num limitante de (n2 ) sobre o tempo de execuc~o no-pior-caso do algoritmo. Esse exemplo indica a import^ncia geral a a de entender como manipular e encontrar limitantes para somatorios. (Como veremos no cap tulo 4, somatorios tambem aparecem quando usamos certos metodos de resolver recorr^ncias.) e A Sec~o 3.1 lista varias formulas basicas envolvendo somatorios. A Sec~o 3.2 a a oferece tecnicas uteis para se encontrar limitantes para somatorios. As formulas na Sec~o 3.1 s~o dadas sem demonstrac~o, embora demonstrac~es para algumas a a a o delas sejam apresentadas na Sec~o 3.2 para ilustrar os metodos daquela sec~o. a a A maior parte das outras demonstrac~es podem ser encontradas em qualquer o texto de calculo.

3.1 Formulas e propriedades de somatorios


Dada uma sequ^ncia a1 ; a2; : : : de numeros, a soma nita a1 +a2 + +an pode e ser escrita
n X k=1

ak .

Se n = 0, o valor do somatorio e de nido como sendo 0. Se n n~o e um ina teiro, assumimos que o limite superior e bnc. Da mesma forma, se a soma comeca com k = x, onde x n~o e um inteiro, assumimos que o valor inicial a 43

44

CAP TULO 3. SOMATORIOS

para o somatorio e bxc. (Geralmente, colocaremos pisos e tetos explicitamente.) O valor de uma serie nita e sempre bem de nido, e seus termos podem ser adicionados em qualquer ordem. Dada uma sequ^ncia a1 ; a2; : : : de numeros, a serie in nita a1 +a2 + pode e ser escrita
1 X
k=1

ak ,
n X k=1

que e interpretada de modo a signi car lim n!1 ak . Se o limite n~o existe, a serie diverge; do contrario, ela converge. Os tera mos de uma serie convergente nem sempre podem ser adicionados em qualquer ordem. Podemos, entretanto, rearrumar os termos de uma serie absolutamente convergente, isto e, uma serie P1 ak para a qual a serie P1 jak j k=1 k=1 tambem converge.

Linearidade
Para qualquer numero real c e quaisquer sequ^ncias nitas a1; a2 ; : : :; an e e b1; b2; : : :; bn,
n X k=1

(cak + bk ) = c

n X k=1

ak +

n X k=1

bk .

A propriedade da linearidade tambem e obedecida por series in nitas convergentes. A propriedade da linearidade pode ser explorada na manipulac~o de soa matorios que incorporam notac~o assintotica. Por exemplo, a
n X k=1

(f(k)) =

n X

Nessa equac~o, a notac~o no lado esquerdo aplica-se a variavel k, porem a a no lado direito, aplica-se a n. Tais manipulac~es podem tambem ser aplicadas o a series in nitas convergentes.

k=1

f(k) :

Series aritmeticas
O somatorio
n X k=1

k = 1+2+

+ n,

itmetica e tem o valor

que apareceu quando analisamos a ordenac~o por inserc~o, e uma serie ara a

3.1. FORMULAS E PROPRIEDADES DE SOMATORIOS


n X

45 (3:1) (3:2)

1 k = 2 n(n + 1) k=1 = (n2): Para um numero real x 6= 1, o somatorio


n X k=0 n X

Series geometricas
xk = 1 + x + x2 +
n+1

+ xn

e uma serie geometrica ou exponencial e tem o valor

xk = x x 1 1 : (3.3) k=0 Quando o somatorio e in nito e jxj < 1, temos a serie geometrica in nita decrescente
1 X
k=0

xk = 1 1 x .

(3.4)

Serie harm^nica o

Para inteiros positivos n, o n-esimo numero harm^nico e o 1 1 1 1 Hn = 1 + 2 + 3 + 4 + + n n X1 = k=1 k = ln n + O(1):

(3:5)

Series integraveis e series diferenciaveis


1 X

Formulas adicionais podem ser obtidas por integrac~o ou por derivac~o das a a formulas acima. Por exemplo, derivando ambos os lados da serie geometrica in nita (3.4) e multiplicando por x, obtemos kxk = (1 x x)2 : k=0 (3.6)

Para qualquer sequ^ncia a0; a1; : : :; an, e


n X k=1

Series telescopicas

(ak ak 1) = an a0 ;

(3.7)

pois cada um dos termos a1; a2; : : :; an 1 e adicionado exatamente uma vez e subtra do exatamente uma vez. Dizemos que a soma e telescopica. Da mesma maneira,

46
n 1 X k=0

CAP TULO 3. SOMATORIOS


(ak ak+1 ) = a0 an .

Como um exemplo de uma soma telescopica, considere a serie

n 1 X

1 k(k + 1) . k=1 Dado que podemos reescrever cada termo para 1 1 1 k(k + 1) = k k + 1 , obtemos
n 1 X n 1 1 X 1 = k=1 k(k + 1) k=1 k 1 = 1 n:

1 k+1

Produtorios
O produto nito a1a2
n Y k=1

an pode ser escrito da forma

ak .

Se n = 0, o valor do produto e de nido como sendo 1. Podemos converter uma formula com um produtorio para uma formula com um somatorio usando a seguinte identidade lg
n X k=1
!

ak =

n X k=1

lg ak .

Exerc cios
3.1-1
P Encontre uma formula simples para n=1(2k 1). k

3.1-2 ? 3.1-3 ? 3.1-4 ?

P o Mostre que n=1 1=(2k 1) = ln(pn) + O(1) manipulando a serie harm^nica. k P Mostre que 1 (k 1)=2k = 0. k=0 P Calcule o somatorio 1 (2k + 1)x2k. k=1

3.2. DELIMITANDO SOMATORIOS

47

P Use anpropriedade da linearidade dos somatorios para demonstrar que n=1 O(fk (n)) = k P O( k=1 fk (n)).

3.1-5

3.1-6

P P Demonstre que 1 (f(k)) = ( 1 f(k)). k=1 k=1

3.1-7

Q Calcule o produtorio n=1 2 4k . k

3.1-8 ?

Q Calcule o produtorio n=2 (1 1=k2). k

3.2 Delimitando somatorios


Existem varias tecnicas para delimitar os somatorios que descrevem os tempos de execuc~o de algoritmos. Aqui est~o algumas dos metodos mais frequentea a mente utilizados. O metodo mais basica de se calcular uma serie e usar a induc~o matematica. P a Como exemplo, vamos demonstrar que a serie aritmetica m=1 k resulta em k 1 n(n + 1). Podemos facilmente veri car isso para n = 1, portanto podemos 2 fazer a suposic~o indutiva de que se veri ca para n + 1. Temos a
n+1 X k=1

Induc~o matematica a

k =

n X

1 = 2 n(n + 1) + (n + 1) 1 = 2 (n + 1)(n + 2): N~o e preciso adivinhar o valor exato de um somatorio de modo a usar a a induc~o matematica. A induc~o pode ser usada tambem para estabelecer um a a P limitante. Como exemplo, vamos demonstrar que a seriengeometrica n=1 3k k P e O(3n). Mais especi camente, vamos demonstrar que k=1 3k c3n para alP guma constante c. Para a condic~o inicial n = 0, temos que 0 =0 3k = 1 c 1 a k desde que c 1. Assumindo que o limitante se veri ca para n, vamos demonstrar que ele se veri ca para n + 1. Temos 3k + 3n+1 k=0 n+1 k=0 c3n + 3 1 = 3 + 1 c3n+1 c c3n+1 desde que (1=3 + 1=c) 1 ou, equivalentemente, c Pn k n k=0 3 = O(3 ), como quer amos demonstrar. 3k =
n+1 X n X

k=1

k + (n + 1)

3=2. Por conseguinte,

48

CAP TULO 3. SOMATORIOS

Temos que ser cuidadosos quando usamos notac~o assintotica para estabelea cernlimitantes por induc~o. Considere a seguinte demonstrac~o falaciosa de que a a P P k = O(n). Certamente, 1 =1 k = O(1). Assumindo o limitante para n, k=1 k agora o demonstramos para n + 1: k = k + (n + 1) k=1 k=1 = O(n) + (n + 1) ( errado! = O(n + 1): O furo no argumento e que a \constante" escondida pelo \O-grande" cresce com n e por conseguinte n~o e constante. N~o mostramos que a mesma cona a stante funciona para todo n.
n+1 X n X

Delimitando os termos

Algumas vezes, um bom limitante superior para uma serie pode ser obtido delimitando-se cada termo da serie, e frequentemente basta usar o maior termo para delimitar os outros. Por exemplo, um limitante superior rapido para a serie aritmetica (3.1) e
n X

n X

= n: P Em geral, para uma serie n=1 ak , se zermos amax = max1 k n ak , ent~o a k ak namax :

k=1

n X

k=1 2

k=1

A tecnica de delimitar cada termo em uma serie pelo maior termo e um metodo fraco quando a serie pode na verdade ser delimitado por uma serie P geometrica. Dada a serie n=0 ak , suponha que ak+1=ak r para todo k 0, k onde r > 1 e uma constante. A soma pode ser delimitada por uma serie geometrica decrescente in nita, pois ak a0 rk , e por conseguinte
n X k=0

ak

1 X

rk = a0 1 1 r : PP Podemos aplicar esse metodo para delimitar o somatorio k=1(k=3k ). O primeiro termo e 1=3, e a proporc~o entre termos consecutivos e a (k + 1)=3k+1 = 1 k + 1 3 k k=3k 2 3 para todo k 1. Por conseguinte, cada termo e delimitado por cima por = a0
k=0

k=01

a0 r k

3.2. DELIMITANDO SOMATORIOS


(1=3)(2=3)k , de modo que
1 X

49

2 k k=1 3 3 = 1 1 12=3 3 = 1: Um furo comum na aplicac~o desse metodo e mostrar que a proporc~o entre a a termos consecutivos e menor que 1 e ent~o assumir que o somatorio e delimitado a por uma serie geometrica. Um exemplo e a serie harm^nica in nita, que diverge o pois k 3k k=1
n X1 = nlim k !1k=1 k=1 k = nlim (lg n) !1 = 1: A raz~o entre o (k+1)-esimo e o k-esimo termos nessa serie e k=(k+1) < 1, mas a a serie n~o e delimitada por uma serie geometrica decrescente. Para delimitar a uma serie por uma serie geometrica, deve-se mostrar que a raz~o e bem distante a de 1; isto e, deve haver um r 1, que e uma constante , tal que a raz~o entre a todos os pares de termos consecutivos nunca passa de r. Na serie harm^nica, o nenhum r como esse existe porque a raz~o ca arbitrariamente proxima de 1. a

1 X1

1 X1

Partindo somatorios