Professional Documents
Culture Documents
discussions, stats, and author profiles for this publication at: https://www.researchgate.net/publication/267785292
Anlise de Algoritmos
Chapter July 2009
CITATIONS
READS
71
1 author:
Paulo Feofiloff
University of So Paulo
13 PUBLICATIONS 52 CITATIONS
SEE PROFILE
All content following this page was uploaded by Paulo Feofiloff on 25 November 2014.
The user has requested enhancement of the downloaded file. All in-text references underlined in blue
are linked to publications on ResearchGate, letting you access and read them immediately.
Minicurso de
Anlise de Algoritmos
http://www.ime.usp.br/~pf/livrinho-AA/
Paulo Feofiloff
Departamento de Cincia da Computao
Instituto de Matemtica e Estatstica
Universidade de So Paulo
2 de janeiro de 2013
FEOFILOFF
Sumrio
1
Introduo
1.1
Problemas e instncias . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2
1.3
1.4
Convenes de notao . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
13
2.1
Notao O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2
Notao mega . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3
Notao Teta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.4
Soluo de recorrncias
17
3.1
Exemplo 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.2
Exemplo 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3
Exemplo 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.4
Exemplo 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.5
Teorema mestre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Ordenao de vetor
25
4.1
Algoritmo Mergesort . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2
Diviso e conquista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
27
5.1
O problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
5.2
Primeiro algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
5.3
5.4
5.5
FEOFILOFF
O problema da maioria
33
6.1
O problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
6.2
Um algoritmo linear . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
37
7.1
O problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
7.2
O algoritmo usual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
7.3
Diviso e conquista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
7.4
Algoritmo de Karatsuba . . . . . . . . . . . . . . . . . . . . . . . . . . 40
7.5
Detalhes de implementao . . . . . . . . . . . . . . . . . . . . . . . . 41
7.6
Diviso e conquista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Escalonamento de intervalos
43
8.1
O problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
8.2
8.3
As linhas de um pargrafo
47
9.1
O problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
9.2
9.3
51
10.1 O problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
10.2 A estrutura recursiva do problema . . . . . . . . . . . . . . . . . . . . 51
10.3 Algoritmo de programao dinmica . . . . . . . . . . . . . . . . . . . 52
10.4 Instncias especiais do problema da mochila . . . . . . . . . . . . . . 54
11 Mochila de valor quase mximo
55
11.1 O problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
11.2 Algoritmo de aproximao . . . . . . . . . . . . . . . . . . . . . . . . . 55
11.3 Observaes sobre algoritmos de aproximao . . . . . . . . . . . . . 57
12 A cobertura de um grafo
59
12.1 Grafos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
12.2 O problema da cobertura . . . . . . . . . . . . . . . . . . . . . . . . . . 59
12.3 Um algoritmo de aproximao . . . . . . . . . . . . . . . . . . . . . . 60
12.4 Comentrios sobre o mtodo primal-dual . . . . . . . . . . . . . . . . 62
12.5 Instncias especiais do problema . . . . . . . . . . . . . . . . . . . . . 62
ANLISE DE ALGORITMOS
63
13.1 O problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
13.2 Algoritmo probabilstico . . . . . . . . . . . . . . . . . . . . . . . . . . 64
13.3 Comentrios sobre algoritmos probabilsticos . . . . . . . . . . . . . . 66
14 Busca em largura num grafo
67
71
74
Bibliografia
77
ndice remissivo
79
FEOFILOFF
Prefcio
A Anlise de Algoritmos (veja o verbete Analysis of Algorithms na Wikipedia) uma
disciplina bem-estabelecida, coberta por um bom nmero de excelentes livros (a maioria em ingls). Este livrinho faz uma modesta introduo ao assunto. Depois de tratar
brevemente de alguns pr-requisitos (como notao assinttica e resoluo de recorrncias), o texto analisa alguns algoritmos clssicos, discute sua eficincia, e chama a ateno para as estratgias (diviso e conquista, programao dinmica, mtodo primaldual) que levaram sua concepo.
Este livrinho uma verso corrigida do minicurso que ministrei nas JAI (Jornadas
de Atualizao em Informtica) de 2009 da SBC (Sociedade Brasileira de Computao),
ocorridas em Bento Gonalves, RS, em julho de 2009. O minicurso foi publicado no
livro organizado por Andr P. L. F. de Carvalho e Tomasz Kowaltowski [5].
O texto deve muito a Cristina Gomes Fernandes e Jos Coelho de Pina Jr., ambos
do Departamento de Cincia da Computao do Instituto de Matemtica e Estatstica
da USP, que contriburam com material, ideias e valiosas sugestes.
FEOFILOFF
Captulo 1
Introduo
A Anlise de Algoritmos1 estuda certos problemas computacionais recorrentes, ou seja,
problemas que aparecem, sob diversos disfarces, em uma grande variedade de aplicaes e de contextos. A anlise de um algoritmo para um dado problema trata de
1. provar que o algoritmo est correto e
2. estimar o tempo que a execuo do algoritmo consome.
(A estimativa do espao de memria usado pelo algoritmo tambm importante em
muitos casos.) Dados dois algoritmos para um mesmo problema, a anlise permite
decidir qual dos dois mais eficiente.
Pode-se dizer que a Anlise de Algoritmos uma disciplina de engenharia, pois
ela procura prever o comportamento de um algoritmo antes que ele seja efetivamente
implementado e colocado em produo.
Num nvel mais abstrato, a anlise de algoritmos procura identificar aspectos estruturais comuns a algoritmos diferentes e estudar paradigmas de projeto de algoritmos
(como a diviso e conquista, a programao dinmica, o mtodo primal-dual, etc.)
Este texto uma breve introduo Anlise de Algoritmos, baseada nos excelentes
livros de Cormen, Leiserson, Rivest e Stein [3], de Brassard e Bratley [2], de Bentley [1],
de Kleinberg e Tardos [10] e de Manber [14].
No restante desta introduo, faremos uma rpida reviso de conceitos bsicos e
fixaremos a notao e a terminologia empregadas no texto.
1.1
Problemas e instncias
10
FEOFILOFF
1.2
ANLISE DE ALGORITMOS
1.3
11
Usaremos a excelente notao do livro de Cormen et al. [3] para descrever algoritmos.
12
FEOFILOFF
P ISO D E L OG (n)
1 se n = 1
2
ento devolva 0
3
seno devolva P ISO D E L OG (bn/2c) + 1
Prova da correo do algoritmo: Se n = 1, evidente que o algoritmo devolve o
valor correto de blg nc. Agora tome n 2 e seja k o nmero blg nc. Queremos mostrar
que o algoritmo devolve k.
Como 2k n < 2k+1 , temos 2k1 n/2 < 2k . Como 2k1 um nmero natural,
temos 2k1 bn/2c < 2k e portanto blgbn/2cc = k 1. Como bn/2c < n, podemos
supor, por hiptese de induo, que o valor da expresso P ISO D E L OG (bn/2c) k 1.
Portanto, o algoritmo devolve k 1 + 1 = k, como queramos provar.
1.4
N
N>
R
R
R>
dxe
Convenes de notao
Para concluir esta introduo, estabelecemos algumas convenes de notao. Denotaremos por N o conjunto {0, 1, 2, 3, . . .} dos nmeros naturais (que coincide com o dos
inteiros no negativos). O conjunto N {0} ser denotado por N> . O conjunto dos
nmeros reais ser denotado por R. O conjunto dos reais no negativos e o dos reais
estritamente positivos sero denotados por R e por R> respectivamente.
Como j dissemos acima, o piso de um nmero x em R o nico nmero i em N
tal que i x < i + 1. O teto de x o nico nmero j em N tal que j 1 < x j. O piso
e o teto de x so denotados por bxc e dxe respectivamente.
Denotaremos por lg n o logaritmo de um nmero n na base 2. Portanto, lg n =
log2 n.
Captulo 2
2.1
Notao O
14
FEOFILOFF
em N> . Para todo n > 10c temos n2 /10 = n n/10 > 10c n/10 = cn. Logo, no
verdade que n2 /10 cn para todo n suficientemente grande.
Exemplo 5: 2n est em O(2n ). De fato, 2n 2n para todo n 1, como provaremos
por induo em n. Prova: Se n = 1, a afirmao verdadeira pois 2 1 = 21 . Agora
tome n 2 e suponha, a ttulo de hiptese de induo, que 2(n 1) 2n1 . Ento
2n 2(n + n 2) = 2(n 1) + 2(n 1) 2n1 + 2n1 = 2n , como queramos
demonstrar.
A seguinte regra da soma til: se F e F 0 esto ambas em O(G) ento F + F 0
tambm est em O(G). Eis uma prova da regra. Por hiptese, existem nmeros c
e n0 tais que F (n) cG(n) para todo n n0 . Analogamente, existem c0 e n00 tais
que F 0 (n) c0 G(n) para todo n n00 . Ento, para todo n max(n0 , n00 ), tem-se
F (n) + F 0 (n) (c + c0 )G(n).
Exemplo 6: Como 2n3 e 100n esto ambas em O(n3 ), a funo 2n3 + 100n tambm
est em O(n3 ).
Nossa definio da notao O foi formulada para funes de N em R , mas ela pode
ser estendida, da maneira bvia, a funes que no esto definidas ou so negativas
para valores pequenos do argumento.
Exemplo 7: Embora n2 100n no esteja em R quando n < 100, podemos dizer
que n2 100n O(n2 ), pois n2 100n n2 para todo n 100.
Exemplo 8: Embora lg n no esteja definida quando n = 0, podemos dizer que lg n
est em O(n). De fato, se tomarmos o logaritmo da desigualdade n 2n do Exemplo 5,
veremos que lg n n para todo n 1.
Exemplo 9: n lg n est em O(n2 ). Segue imediatamente do Exemplo 8.
Exerccios
2.1 Critique a afirmao n2 100n est em O(n2 ) para todo n 100.
2.2 Mostre que lg n est em O(n0.5 ).
2.2
Notao mega
15
ANLISE DE ALGORITMOS
n2
Exemplo 13: 100n no est em (n2 ). Tome qualquer c em N> . Para todo n >
100c, tem-se 100 < 1c n e portanto 100n < 1c n2 .
Exemplo 14: n no (2n ). Basta mostrar que para qualquer c em N> tem-se
n < 1c 2n para todo n suficientemente grande. Como todo c menor que alguma potncia de 2, basta mostrar que, para qualquer k em N> , tem-se n 2k 2n para todo n
suficientemente grande. Especificamente, mostraremos que n 2nk para todo n 2k.
A prova por induo em n. Se n = 2k, temos k 2k1 conforme o Exemplo 5
com k no papel de n, e portanto n = 2k 2 2k1 = 2k = 22kk = 2nk . Agora tome
n 2k + 1 e suponha, a ttulo de hiptese de induo, que n 1 2n1k . Ento
n n + n 2 = n 1 + n 1 = 2 (n 1) 2 2n1k = 2nk , como queramos
demonstrar.
Exerccios
2.3 Mostre que 2n1 est em (2n ).
2.4 Mostre que lg n no (n).
2.3
Notao Teta
Dizemos que F est em (G) se F est em O(G) e tambm em (G), ou seja, se existem
c e c0 em N> tais que
1
G(n) F (n) c0 G(n)
c
para todo n suficientemente grande. Se F est em (G), diremos que F proporcional
a G, ainda que isto seja um tanto incorreto.
Exemplo 15: Para qualquer a em R> e qualquer b em R, a funo an2 + bn est
em (n2 ).
Exerccio
2.5 Mostre que n(n + 1)/2 e n(n 1)/2 esto em (n2 ).
2.4
16
FEOFILOFF
Exerccio
2.6 Suponha que dois algoritmos, A e B, resolvem um mesmo problema. Suponha que o tamanho das instncias do problema medido por um parmetro n. Em quais dos seguintes
casos podemos afirmar que A mais rpido que B? Caso 1: A consome tempo O(lg n) no
pior caso e B consome tempo O(n3 ) no pior caso. Caso 2: A consome O(n2 lg n) unidades de tempo no pior caso e B consome (n2 ) unidades de tempo no pior caso. Caso 3:
No pior caso, A consome O(n2 ) unidades de tempo e B consome (n2 lg n) unidades de
tempo.
Captulo 3
Soluo de recorrncias
A habilidade de resolver recorrncias importante para a anlise do consumo de tempo
de algoritmos recursivos. Uma recorrncia uma frmula que define uma funo,
digamos F , em termos dela mesma. Mais precisamente, define F (n) em termos de
F (n 1), F (n 2), F (n 3), etc.
Uma soluo de uma recorrncia uma frmula que exprime F (n) diretamente em
termos de n. Para as aplicaes anlise de algoritmos, uma frmula exata para F (n)
no necessria: basta mostrar que F est em (G) para alguma funo G definida
explicitamente em termos de n.
3.1
Exemplo 1
(3.1)
para todo n 2. Eis alguns valores da funo: F (2) = 3, F (3) = 7, F (4) = 15. fcil
desenrolar a recorrncia:
F (n) = 2F (n 1) + 1
= 2(2F (n 2) + 1) + 1
= 4F (n 2) + 3
=
= 2j F (n j) + 2j 1
= 2n1 F (1) + 2n1 1 .
Conclumos assim que
F (n) = 2n 1
(3.2)
para todo n 1. (No temos informaes sobre o valor de F (0).) Portanto, F est
em (2n ).
17
18
FEOFILOFF
Exerccios
3.1 Confira a frmula (3.2) por induo em n.
3.2 Sejam a, b e n0 trs nmeros naturais e suponha que F (n0 ) = a e F (n) = 2F (n 1) + b
para todo n > n0 . Mostre que F est em (2n ).
3.2
Exemplo 2
(3.3)
para todo n 2. Suponha ainda que F (1) = 1. Teremos, em particular, F (2) = F (1) +
2 = 3 e F (3) = F (2) + 3 = 6.
A recorrncia pode ser facilmente desenrolada: F (n) = F (n1) + n = F (n2) +
(n1)+n = = F (1)+2+3+ +(n1)+n = 1+2+3+ +(n1)+n. Conclumos
assim que
F (n) = 12 (n2 + n)
(3.4)
para todo n 1. (No temos informaes sobre o valor de F (0).) Portanto, F est
em (n2 ).
Recorrncias semelhantes. O valor de F (1) tem pouca influncia sobre o resultado. Se tivssemos F (1) = 10, por exemplo, a frmula (3.4) seria substituda por
F (n) = 21 (n2 + n) + 9, e esta funo tambm est em (n2 ).
O ponto a partir do qual (3.3) comea a valer tambm tem pouca influncia sobre a
soluo da recorrncia. Se (3.3) valesse apenas a partir de n = 5, por exemplo, teramos
F (n) = 21 (n2 + n) + F (4) 10 no lugar de (3.4), e esta funo tambm est em (n2 ).
Exerccios
3.3 Confira (3.4) por induo em n.
3.4 Suponha que F satisfaz a recorrncia F (n) = F (n 1) + 3n + 2 para n = 2, 3, 4, . . . Mostre
que se F (1) = 1 ento F (n) = 3n2 /2 + 7n/2 4 para todo n 2. Conclua que F est
em (n2 ).
3.5 Sejam a, b e c trs nmeros naturais e suponha que F satisfaz as seguintes condies:
F (n0 ) = a e F (n) = F (n 1) + bn + c para todo n > n0 . Mostre que F est em (n2 ).
3.6 Suponha que F (n) = F (n 1) + 7 para n = 2, 3, 4, . . . Mostre que se F (1) = 1 ento
F (n) = 7n 6 para todo n 1. Conclua que F est em (n).
3.3
Exemplo 3
Seja F uma funo que leva N em R> . Suponha que F satisfaz a recorrncia
F (n) = 2F (bn/2c) + n
(3.5)
19
ANLISE DE ALGORITMOS
para todo n 2. (No faz sentido trocar bn/2c por n/2 pois n/2 no est em N
quando n mpar.) Suponha ainda que F (1) = 1 (e portanto F (2) = 4, F (3) = 5, etc.)
mais fcil entender (3.5) quando n uma potncia de 2, pois nesse caso bn/2c se
reduz a n/2. Se n = 2j , temos
F (2j ) = 2F (2j1 ) + 2j
= 22 F (2j2 ) + 21 2j1 + 2j
= 23 F (2j3 ) + 22 2j2 + 21 2j1 + 2j
= 2j F (20 ) + 2j1 21 + + 22 2j2 + 21 2j1 + 20 2j
= 2j 20 + 2j1 21 + + 22 2j2 + 21 2j1 + 20 2j
= (j + 1)2j
= j2j + 2j .
(3.6)
Para ter certeza, podemos conferir esta frmula por induo em j. Se j = 1, temos
F (2j ) = 4 = (j + 1)2j . Agora tome j 2. De acordo com (3.5), F (2j ) = 2F (2j1 ) + 2j .
Por hiptese de induo, F (2j1 ) = 2j1 j. Logo, F (2j ) = 2 2j1 j + 2j = 2j j + 2j , como
queramos mostrar.
Como 2j = n, a expresso (3.6) pode ser reescrita assim:
F (n) = n lg n + n
(3.7)
quando n potncia de 2. Embora esta frmula s se aplique s potncias de 2, podemos us-la para obter cotas superior e inferior vlidas para todo n suficientemente
grande. O primeiro passo nessa direo verificar que F crescente, ou seja, que
F (n) < F (n + 1)
(3.8)
20
FEOFILOFF
para todo n 2. Tome o nico j em N tal que 2j n < 2j+1 . Em virtude de (3.8)
e (3.6), temos F (n) F (2j ) = (j + 1)2j = 21 (j + 1)2j+1 . Como lg n < j + 1, temos
1
j+1 > 1 n lg n.
2 (j + 1)2
2
De (3.9) e (3.10), conclumos que F est em (n lg n).
Recorrncias semelhantes. O ponto n0 a partir do qual a recorrncia (3.5) comea
a valer, bem como os valores de F (1), F (2), . . . , F (n0 1), tm pouca influncia sobre a soluo da recorrncia: quaisquer que sejam esses valores iniciais, F estar em
(n lg n). Se (3.5) vale apenas para n 3, por exemplo, teremos n lg n + F (2)2
n no
2
lugar de (3.7).
A parcela n na expresso 2F (bn/2c)+n tambm pode ser ligeiramente alterada sem
que F saia de (n lg n). Assim, quaisquer que sejam c > 0 e d, se F (n) = 2F (bn/2c) +
cn + d ento F est em (n lg n).
Finalmente, podemos trocar 2F (bn/2c) por 2F (dn/2e) ou at mesmo por
F (bn/2c) + F (dn/2e) sem que F saia de (n lg n).
Mas o fator 2 que multiplica F (bn/2c) crtico: se este fator for alterado, a funo
F deixar de pertencer a (n lg n).
Exerccios
3.7 Suponha que um funo F de N em R> satisfaz a recorrncia F (n) = F (bn/2c) + 1 para
todo n 2. Mostre que F est em (lg n).
3.8 Seja F uma funo de N em R> tal que F (n) = 2F (bn/2c) + 1 para todo n 2. Mostre que
F est em (n).
3.9 Seja F um funo de N em R> tal que F (n) = 4F (bn/2c) + n quando n 2. Mostre que
F est em (n2 ). Sugesto: mostre que 41 n2 F (n) 8n2 para todo n suficientemente
grande.
3.4
Exemplo 4
(3.11)
para todo n 2. Suponha ainda que F (1) = 1. Para comear a entender o comportamento de F , considere os valores de n que so potncias de 2. Quando n = 2j , temos
F (2j ) = 3F (2j1 ) + 2j
= 32 F (2j2 ) + 31 2j1 + 2j
= 33 F (2j3 ) + 32 2j2 + 31 2j1 + 2j
= 3j F (20 ) + 3j1 21 + + 32 2j2 + 31 2j1 + 30 2j
= 3j 20 + 3j1 21 + + 32 2j2 + 31 2j1 + 30 2j
21
ANLISE DE ALGORITMOS
(3/2)j+1 1
3/2 1
= 2j+1 (3/2)j+1 1
= 3j+1 2j+1 .
(3.12)
Observe que 3j = (2lg 3 )j = (2j )lg 3 = nlg 3 . (A ttulo de curiosidade, lg 3 fica entre 1.584
e 1.585.) Portanto, a frmula (3.12) pode ser reescrita assim:
F (n) = 3nlg 3 2n
para toda potncia n de 2. Embora esta frmula s valha para as potncias de 2, podemos us-la para obter cotas superior e inferior vlidas para todo n suficientemente
grande. A primeira providncia nessa direo certificar-se de que F crescente:
F (n) < F (n + 1)
para todo n 1. A prova anloga de (3.8). Agora estamos em condies de calcular
uma boa cota superior para F :
F (n) 9nlg 3
(3.13)
para todo n 1. Tome j em N tal que 2j n < 2j+1 . Como F crescente, (3.12) garante
que F (n) < F (2j+1 ) = 3j+2 2j+2 3j+2 = 9 (2j )lg 3 9nlg 3 , como queramos
mostrar. Tambm podemos calcular uma boa cota inferior:
F (n) 31 nlg 3
(3.14)
para todo n 1. Tome j em N tal que 2j n < 2j+1 . Como F crescente, (3.12) garante
que F (n) F (2j ) = 3j+1 2j+1 = 3j + 2 3j 2 2j 3j = 13 3j+1 = 13 (2j+1 )lg 3 > 31 nlg 3 ,
como queramos demonstrar.
As relaes (3.13) e (3.14) mostram que F est em (nlg 3 ).
Recorrncias semelhantes. Se (3.11) valesse apenas quando n n0 , a funo F
continuaria em (nlg 3 ) quaisquer que fossem os valores de F (bn0 /2c), F (bn0 /2c + 1),
. . . , F (n0 1).
Alm disso, F continuar em (nlg 3 ) se (3.11) for substituda por F (n) =
3F (bn/2c) + cn + d, quaisquer que sejam c > 0 e d. Tambm continuar em (nlg 3 ) se
3F (bn/2c) for trocado por 2F (bn/2c) + F (dn/2e) ou at mesmo por 2F (bn/2c) +
F (dn/2e + 1).
Exerccio
3.10 Confira a formula (3.12) por induo em j.
22
3.5
FEOFILOFF
Teorema mestre
(nk
(nk ).
lg n),
(3.16)
(3.17)
(3.18)
(Recorrncias como (3.15) aparecem na anlise de algoritmos baseados na estratgia da diviso e conquista: dada uma instncia de tamanho n, divida a instncia em a
partes de tamanho n/2, resolva essas subinstncias, e combine as solues em tempo
limitado por cnk .)
Generalizao. O teorema pode ser generalizado como segue. Sejam a 1, b 2,
k 0 e n0 1 nmeros em N e seja c um nmero em R> . Seja F uma funo de N
em R> tal que
n
F (n) = a F
+ cnk
(3.19)
b
para n = n0 b1 , n0 b2 , n0 b3 , . . . Suponha ainda que F assintoticamente no decrescente.
Nessas condies,
se lg a/ lg b > k ento F est em (nlg a/ lg b ),
se lg a/ lg b = k ento F est em
(nk
(nk ).
lg n),
(3.20)
(3.21)
(3.22)
A prova deste teorema pode ser encontrada na Seo 4.7 do livro de Brassard e
Bratley [2] e na Seo 4.4 do livro de Cormen et al. [3].
Exemplo A. Seja c um nmero em R> e seja F uma funo de N em R> tal que
F (n) = F (bn/2c) + 2F (dn/2e) + cn para todo n 2. Nessas condies, F no decrescente e portanto (3.16) garante que F est em (nlg 3 ). (Compare com o resultado da
Seo 3.4.)
Exemplo B. Sejam a e k nmeros em N tais que a > 2k e seja c um nmero em R> .
Seja F uma funo de N em R> tal que F (n) = aF bn/2c + cnk para todo n 1.
Nessas condies, F no decrescente e portanto (3.16) garante que F est em (nlg a ).
ANLISE DE ALGORITMOS
23
Notas bibliogrficas
Este captulo foi baseada na Seo 4.7 do livro de Brassard e Bratley [2]. Veja tambm o
verbete Master theorem na Wikipedia.
24
FEOFILOFF
Captulo 4
Ordenao de vetor
Um vetor A[p . . r] crescente se A[p] A[p + 1] A[r]. A tarefa de colocar
um vetor em ordem crescente um dos problemas computacionais mais conhecidos e
bem-estudados.
Problema da Ordenao: Rearranjar um vetor A[p . . r] em ordem crescente.
4.1
Algoritmo Mergesort
25
26
FEOFILOFF
p
111
333
555
555
777
q+1
888
222
r
444
777
999
999
Consumo de tempo. Seja T (n) o tempo que o algoritmo consome, no pior caso,
para processar uma instncia de tamanho n. Ento
T (n) = T (dn/2e) + T (bn/2c) + n .
As parcelas T (d n2 e) e T (b n2 c) correspondem s linhas 3 e 4. A parcela n representa o
consumo de tempo da linha 5, uma vez que o algoritmo I NTERCALA pode ser implementado de maneira a consumir tempo proporcional a n. (Veja o Exerccio 4.1 abaixo.)
Como vimos nas Sees 3.3 e 3.5, a funo T est em
(n lg n) .
O consumo de tempo do algoritmo no melhor caso tambm est em (n lg n).
Exerccio
4.1 Descreva em pseudocdigo o algoritmo I NTERCALA mencionado acima. Mostre que o
consumo de tempo do algoritmo (n).
4.2
Diviso e conquista
O algoritmo M ERGE S ORT emprega a estratgia da diviso e conquista: a instncia original do problema dividida em duas instncias menores, essas instncias so resolvidas
recursivamente, e as solues so combinadas para produzir uma soluo da instncia
original.
O segredo do sucesso est no fato de que o processo de diviso (que est na linha 2,
nesse caso) e o processo da combinao (que acontece na linha 5) consomem pouco
tempo.
A estratgia da diviso e conquista rende algoritmos eficientes para muitos problemas. Veremos exemplos nos captulos seguintes.
Captulo 5
5.1
O problema
20
30
15
10
30
20
30
30
1
Teria sido mais limpo e natural aceitar segmentos vazios. Mas a discusso fica ligeiramente mais
simples se nos limitarmos aos segmentos no vazios.
27
28
5.2
FEOFILOFF
Primeiro algoritmo
(r q + 1) = n + (n 1) + + 3 + 2 =
2
1
2 (n
+ n 2) .
q=p
Portanto, o consumo de tempo est em (n2 ), tanto no pior quanto no melhor caso.
O algoritmo ineficiente porque a soma de cada segmento recalculada muitas vezes. Por exemplo, a soma de A[10 . . r] refeita durante o clculo das somas de A[9 . . r],
A[8 . . r], etc. O algoritmo da prxima seo procura remediar esta ineficincia.
Exerccios
5.1 Modifique o algoritmo S OLIDEZ I de modo que ele devolva um par (i, k) de ndices tal que
a soma A[i] + + A[k] a solidez de A[p . . r].
5.2 Escreva um algoritmo anlogo a S OLIDEZ I para tratar da variante do problema que admite
segmentos vazios. Nessa variante, um segmento A[i . . k] vazio se i = k + 1. A soma de
um segmento vazio 0.
29
ANLISE DE ALGORITMOS
5.3
Nosso segundo algoritmo usa a estratgia da diviso e conquista (veja a Seo 4.2),
que consiste em dividir a instncia dada ao meio, resolver cada uma das metades e
finalmente juntar as duas solues. O algoritmo devolve a solidez do vetor A[p . . r]
supondo p r:
S OLIDEZ II (A, p, r)
1 se p = r
2
ento devolva A[p]
3
seno q b(p + r)/2c
4
x0 S OLIDEZ II (A, p, q)
5
x00 S OLIDEZ II (A, q + 1, r)
6
y 0 s A[q]
7
para i q 1 decrescendo at p faa
8
s A[i] + s
9
se s > y 0 ento y 0 s
10
y 00 s A[q + 1]
11
para j q + 2 at r faa
12
s s + A[j]
13
se s > y 00 ento y 00 s
14
x max (x0 , y 0 + y 00 , x00 )
15
devolva x
O algoritmo est correto. Seja n := r p + 1 o nmero de elementos do vetor
A[p . . r]. Se n = 1, claro que a resposta do algoritmo est correta. Suponha agora que
n 2. Depois da linha 4, por hiptese de induo, x0 a solidez de A[p . . q]. Depois da
linha 5, x00 a solidez de A[q+1 . . r]. Depois do bloco de linhas 6-13, y 0 + y 00 a maior
soma da forma A[i] + + A[j] com i q < j. (Veja o Exerccio 5.3.)
Em suma, y 0 + y 00 cuida dos segmentos que contm A[q] e A[q+1], enquanto x0 e x00
cuidam de todos os demais segmentos. Conclumos assim que o nmero x calculado
na linha 14 a solidez de A[p . . r].
p
20
30
15
q
10
q+1
30
20
30
r
30
30
FEOFILOFF
Exerccio
5.3 Prove que depois do bloco de linhas 6-13 do algoritmo S OLIDEZ II, y 0 + y 00 a maior soma
dentre todas as que tm a forma A[i] + + A[j] com i q < j.
5.4
Nosso terceiro algoritmo usa a tcnica da programao dinmica, que consiste em armazenar os resultados de clculos intermedirios numa tabela para evitar que eles sejam repetidos.
Mas a tcnica no pode ser aplicada diretamente ao nosso problema. Ser preciso
tratar do seguinte problema auxiliar, que restringe a ateno aos segmentos terminais
do vetor: dado um vetor A[p . . r], encontrar a maior soma da forma
A[i] + + A[r] ,
com p i r. Para facilitar a discusso, diremos que a maior soma desta forma
a firmeza do vetor A[p . . r]. A solidez do vetor o mximo das firmezas de A[p . . r],
A[p . . r1], A[p . . r2], etc.
A firmeza do vetor tem uma propriedade recursiva que a solidez no tem. Suponha
que A[i]+ +A[r] a firmeza de A[p . . r]. Se i r1 ento A[i]+ +A[r1] a firmeza
de A[p . . r1]. (De fato, se A[p . . r1] tivesse firmeza maior ento existiria h r 1 tal
que A[h] + + A[r1] > A[i] + + A[r1] e portanto teramos A[h] + + A[r] >
A[i] + + A[r], o que impossvel.)
Se denotarmos a firmeza de A[p . . q] por F [q], podemos resumir a propriedade recursiva por meio de uma recorrncia: para qualquer vetor A[p . . r],
F [r] = max F [r1] + A[r] , A[r] .
(5.1)
Em outras palavras, F [r] = F [r 1] + A[r] e menos que F [r 1] seja negativo, caso em
que F [r] = A[r].
A recorrncia (5.1) serve de base para o seguinte algoritmo, que calcula a solidez
de A[p . . r] supondo p r:
31
ANLISE DE ALGORITMOS
(5.2)
para j = q1, q2, . . . , p+1, p. Logo, no incio da linha 6, o fato (5.2) vale para j = p,
p + 1, . . . , r.
O bloco de linhas 6-8 escolhe a maior das firmezas. Portanto, no fim do algoritmo,
x a solidez de A[p . . r].
Consumo de tempo. O algoritmo consome tempo proporcional ao nmero de
elementos n := r p + 1 do vetor. O consumo de tempo do algoritmo est em
(n)
e o algoritmo , portanto, linear.
p
20
30
15
10
30
20
30
r
30
20
10
15
35
15
15
30
Exerccios
5.4 Os dois processos iterativos de S OLIDEZ III podem ser fundidos num s, evitando-se assim
o uso do vetor F [p . . r]. Uma varivel f pode fazer o papel de um elemento genrico do
vetor F . Implemente essa ideia.
5.5 Suponha dada uma matriz A[1 . . n, 1 . . n] de nmeros inteiros (nem todos no negativos).
Encontrar uma submatriz quadrada de A que tenha soma mxima. (Veja o livro de Bentley [1, p.84].)
32
FEOFILOFF
5.5
Notas bibliogrficas
Este captulo foi baseado no livro de Bentley [1].
Aqui, a palavra programao no tem relao direta com programao de computadores. Ela significa
planejamento e refere-se construo da tabela que armazena os resultados intermedirios usados para
calcular a soluo do problema.
Captulo 6
O problema da maioria
Imagine uma eleio com muitos candidatos e muitos eleitores. Como possvel determinar, em tempo proporcional ao nmero de eleitores, se algum dos candidatos obteve
a maioria1 dos votos?
6.1
O problema
33
34
FEOFILOFF
44
33
11
22
33
22
22
33
22
22
22
22
6.2
Um algoritmo linear
35
ANLISE DE ALGORITMOS
10
11
12
13
14
15
16
c0
para m 1 at n faa
se A[m] = x
ento c c + 1
se c > n/2
ento devolva x
seno devolva 1
36
FEOFILOFF
Notas bibliogrficas
Este captulo foi baseado nos livros de Bentley [1] e Manber [14].
Captulo 7
7.1
O problema
Usaremos notao decimal para representar nmeros naturais. (Poderamos igualmente bem usar notao binria, ou notao base 232 , por exemplo.) Diremos que um
dgito qualquer nmero menor que 10. Diremos que um nmero natural u tem n
dgitos1 se u < 10n . Com esta conveno, podemos nos restringir, sem perder generalidade, ao caso em que os dois multiplicandos tm o mesmo nmero de dgitos:
Problema da Multiplicao: Dados nmeros naturais u e v com n dgitos cada,
calcular o produto u v.
Voc deve imaginar que cada nmero natural representado por um vetor de dgitos. Mas nossa discusso ser conduzida num nvel de abstrao alto, sem manipulao
explcita desse vetor. (Veja a Seo 7.5.)
7.2
O algoritmo usual
37
38
FEOFILOFF
dgitos cada. O algoritmo tem dois passos. O primeiro passo calcula todos os n produtos de u por um dgito de v (cada um desses produtos tem n + 1 dgitos). O segundo
passo do algoritmo desloca para a esquerda, de um nmero apropriado de casas, cada
um dos n produtos obtidos no primeiro passo e soma os n nmeros resultantes. O
produto u v tem 2n dgitos.
O primeiro passo do algoritmo consome tempo proporcional a n2 . O segundo passo
tambm consome tempo proporcional a n2 . Assim, o consumo de tempo do algoritmo
usual de multiplicao est em (n2 ).
9999
7777
A
B
69993
69993
69993
69993
C
D
E
F
77762223
Figura 7.1: Algoritmo usual de multiplicao de dois nmeros naturais. Aqui estamos multiplicando 9999 por 7777 para obter o produto 77762223. A linha C o
resultado da multiplicao da linha A pelo dgito menos significativo da linha B. As
linhas D, E e F so definidas de maneira semelhante. A linha G o resultado da soma
das linhas C a F.
Exerccio
7.1 Descreva o algoritmo usual de adio em pseudocdigo. O algoritmo deve receber nmeros u e v com n dgitos cada e devolver a soma u + v.
7.2 Descreva algoritmo usual de multiplicao em pseudocdigo. O algoritmo deve receber
nmeros u e v com n dgitos cada e devolver o produto u v.
7.3
Diviso e conquista
Sejam u e v dois nmeros com n dgitos cada. Suponha, por enquanto, que n par. Seja
p o nmero formado pelos n/2 primeiros dgitos de u e seja q o nmero formado pelos
n/2 ltimos dgitos de u. Assim,
u = p 10n/2 + q .
Defina r e s analogamente para v, de modo que v = r 10n/2 + s. Teremos ento
u v = p r 10n + (p s + q r) 10n/2 + q s .
(7.1)
Esta expresso reduz a multiplicao de dois nmeros com n dgitos cada a quatro
multiplicaes (a saber, p por r, p por s, q por r e q por s) de nmeros com n/2 dgitos
ANLISE DE ALGORITMOS
39
cada.2
Se n for uma potncia de 2, o truque pode ser aplicado recursivamente a cada uma
das quatro multiplicaes menores. O resultado o seguinte algoritmo recursivo, que
recebe nmeros naturais u e v com n dgitos cada e devolve o produto u v:
R ASCUNHO (u, v, n)
1 se n = 1
2
ento devolva u v
3
seno m n/2
4
p bu/10m c
5
q u mod 10m
6
r bv/10m c
7
s v mod 10m
8
pr R ASCUNHO (p, r, m)
9
qs R ASCUNHO (q, s, m)
10
ps R ASCUNHO (p, s, m)
11
qr R ASCUNHO (q, r, m)
12
x pr 102m + (ps + qr ) 10m + qs
13
devolva x
O algoritmo est correto. claro que o algoritmo produz o resultado correto
se n = 1. Suponha agora que n 2. Como m < n, podemos supor, por hiptese
de induo, que a linha 8 produz o resultado correto, ou seja, que pr = p r. Analogamente, podemos supor que qs = q s, ps = p s e qr = q r no incio da linha 12. A
linha 12 no faz mais que implementar (7.1). Portanto, x = u v.
Consumo de tempo. As linhas 4 a 7 envolvem apenas o deslocamento de casas
decimais, podendo portanto ser executadas em no mais que n unidades de tempo. As
multiplicaes por 102m e 10m na linha 12 tambm consomem no mximo n unidades
de tempo, pois podem ser executadas com um mero deslocamento de casas decimais.
As adies na linha 12 consomem tempo proporcional ao nmero de dgitos de x, igual
a 2n.
Portanto, se denotarmos por T (n) o consumo de tempo do algoritmo no pior caso,
teremos
T (n) = 4 T (n/2) + n .
(7.2)
As quatro parcelas T (n/2) se referem s linhas 8 a 11 e a parcela n se refere ao consumo
das demais linhas. Segue da que T est em (n2 ), como j vimos no Exerccio 3.9.
Assim, o algoritmo R ASCUNHO no mais eficiente que o algoritmo usual de multiplicao.
2
Minha calculadora de bolso no capaz de exibir/armazenar nmeros que tenham mais que n dgitos. Para calcular o produto de dois nmeros com n dgitos cada, posso recorrer equao (7.1): uso a
mquina para calcular os quatro produtos e depois uso lpis e papel para fazer as trs adies.
40
FEOFILOFF
99998888
77776666
u
v
9999
p
q
r
s
8888
7777
6666
77762223
59247408
135775310
pr
qs
ps + qr
7777580112347408
7.4
Algoritmo de Karatsuba
Para tornar o algoritmo da seo anterior muito mais rpido, basta observar que os trs
nmeros de que precisamos do lado direito de (7.1) a saber, p r, (p s + q r) e q s
podem ser obtidos com apenas trs multiplicaes. De fato,
ps+qr = yprqs,
sendo y = (p + q) (r + s). Assim, a equao (7.1) pode ser substituda por
u v = p r 10n + (y p r q s) 10n/2 + q s .
(7.3)
( bem verdade que (7.3) envolve duas adies e duas subtraes adicionais, mas essas
operaes consomem muito menos tempo que as multiplicaes.) Se n no par, basta
trocar n/2 por dn/2e: teremos u = p 10dn/2e + q e v = r 10dn/2e + s e portanto
u v = p r 102dn/2e + (y p r q s) 10dn/2e + q s .
Segue da o seguinte algoritmo de Karatsuba, que recebe nmeros naturais u e v com
n dgitos cada e devolve o produto u v:
K ARATSUBA (u, v, n)
1 se n 3
2
ento devolva u v
3
seno m dn/2e
4
p bu/10m c
5
q u mod 10m
6
r bv/10m c
7
s v mod 10m
8
pr K ARATSUBA (p, r, m)
9
qs K ARATSUBA (q, s, m)
10
y K ARATSUBA (p + q, r + s, m+1)
11
x pr 102m + (y pr qs) 10m + qs
12
devolva x
41
ANLISE DE ALGORITMOS
(7.4)
As duas parcelas T (dn/2e) e a parcela T (dn/2e + 1) se referem s linhas 8, 9 e 10 respectivamente. A parcela n representa o consumo de tempo das demais linhas.
Como sugerimos na Seo 3.5, a funo T est na mesma classe assinttica que a
funo T 0 que satisfaz a recorrncia T 0 (n) = 3T 0 (bn/2c) + n. De acordo com a Seo 3.4,
T 0 est em (nlg 3 ). Portanto
T est em (nlg 3 ) .
(7.5)
Como lg 3 < 1.6, o algoritmo K ARATSUBA mais rpido que o algoritmo usual. (Ob
serve que nlg 3 apenas um pouco maior que n n.) Mas, em virtude da constante
multiplicativa escondida sob a notao , esta superioridade s se manifesta quando
n maior que algumas centenas.
999988888
077766666
u
v
5925807408
pr
qs
07769223
98887
67443
6669235941
735659310
077765801856807408
p+q
r+s
y
y pr qs
x
Figura 7.3: Multiplicao de u por v calculada pelo algoritmo K ARATSUBA. O resultado da operao x. Se u e v tivessem n dgitos cada, pr e qs teriam n + 1 dgitos cada,
y teria n + 2 (mais precisamente, s n + 1) dgitos e x teria 2n dgitos.
7.5
Detalhes de implementao
Para implementar os algoritmos que discutimos acima, preciso representar cada nmero por um vetor de dgitos, ou seja, um vetor U [1 . . n] cujos componentes pertencem
ao conjunto {0, 1, . . . , 9}. Um tal vetor representa o nmero natural U [n] 10n1 +
U [n1] 10n2 + + U [2] 10 + U [1].
O algoritmo K ARATSUBA recebe os vetores U [1 . . n] e V [1 . . n] que representam u e
v respectivamente e devolve o vetor X[1 . . 2n] que representa x. Nas linhas 4 e 5, p
representado por U [m+1 . . n] e q representado por U [1 . . m]. A implementao das
42
FEOFILOFF
7.6
Diviso e conquista
Notas bibliogrficas
Este captulo foi baseada na Seo 7.1 do livro de Brassard e Bratley [2]. O assunto
tambm discutido nos livros de Knuth [11], Dasgupta, Papadimitriou e Vazirani [4] e
Kleinberg e Tardos [10].
O algoritmo K ARATSUBA foi publicado em 1962 pelos matemticos russos Anatolii
Karatsuba e Yurii Ofman. Veja o verbetes Multiplication algorithm e Karatsuba algorithm
na Wikipedia.
Captulo 8
Escalonamento de intervalos
Imagine que vrios eventos querem usar um certo centro de convenes. Cada evento
gostaria de usar o centro durante o intervalo de tempo que comea numa data a e
termina numa data b. Dois eventos so considerados compatveis se os seus intervalos
de tempo so disjuntos. Cada evento tem um certo valor e a administrao do centro
precisa selecionar um conjunto de eventos mutuamente compatveis que tenha o maior
valor total possvel.
8.1
O problema
Um algoritmo guloso constri uma soluo escolhendo, a cada passo, o objeto mais saboroso de
acordo com algum critrio estabelecido a priori.
43
44
FEOFILOFF
Exerccio
8.1 Coloque os intervalos em ordem decrescente de valor, ou seja, suponha que v1 v2
vn . Agora considere o seguinte algoritmo. A m-sima iterao do algoritmo comea
com um subconjunto vivel S de {1, . . . , m1}. Se S {m} for vivel, comece nova iterao
com S {m} no lugar de S. Seno, comece nova iterao sem alterar S. Mostre que este
algoritmo guloso. no resolve o problema.
8.2
(8.1)
Exerccio
8.2 Escreva um algoritmo recursivo baseado em (8.2). Mostre que o consumo de tempo do
algoritmo no pior caso est em (2n ). (Sugesto: Considere um conjunto com n intervalos
compatveis dois a dois, todos com valor 1. Mostre que o tempo T (n) que o algoritmo
consome para processar o conjunto satisfaz a recorrncia T (n) = T (n 1) + T (n 1) + 1.)
8.3
Para tirar bom proveito da recorrncia (8.2), preciso recorrer tcnica da programao
dinmica (veja a Seo 5.5), que consiste em guardar as solues das subinstncias
ANLISE DE ALGORITMOS
45
numa tabela medida que elas forem sendo resolvidas. Com isso, cada subinstncia
ser resolvida uma s vez.
O seguinte algoritmo recebe n intervalos que satisfazem (8.1) e devolve o valor de
um svvm de {1, . . . , n}:
I NTERVALOS C OMPATVEIS (a1 , . . . , an , b1 , . . . , bn , v1 , . . . , vn )
1 X[0] 0
2 para m 1 at n faa
3
j m1
4
enquanto j 1 e bj am faa
5
j j1
6
se X[m 1] > X[j] + vm
7
ento X[m] X[m 1]
8
seno X[m] X[j] + vm
9 devolva X[n]
(No difcil extrair da tabela X um svvm de {1, . . . , n}.)
O algoritmo est correto. Na linha 2, imediatamente antes da comparao de m
com n,
X[m1] o valor de um svvm de {1, . . . , m1},
X[m2] o valor de um svvm de {1, . . . , m2}, . . . ,
X[1] o valor de um svvm de {1}.
Este invariante certamente vale no incio da primeira iterao, quando m = 1. Suponha agora que ele vale no incio de uma iterao qualquer. Para mostrar que continua
valendo no incio da iterao seguinte, observe que, no comeo da linha 6, {1, . . . , j}
o conjunto dos intervalos compatveis com m. Assim, o valor atribudo a X[m] nas
linhas 7 e 8 est de acordo com a recorrncia (8.2) e portanto X[m] o valor de um
svvm de {1, . . . , m}.
Na ltima passagem pela linha 2 temos m = n + 1 e portanto X[n] o valor de um
svvm de {1, . . . , n}. Assim, o algoritmo cumpre o que prometeu.
Consumo de tempo. Uma execuo de qualquer linha do algoritmo I NTERVA LOS C OMPATVEIS consome uma quantidade de tempo que no depende de n. Logo, o
consumo de tempo total do algoritmo pode ser medido contando o nmero de execues das diversas linhas.
Para cada valor
5 executada no mximo m 1 vezes. Como m
Pn fixo de m, a linha
1
2
varia de 1 a n e m=1 (m 1) = 2 (n n), a linha 5 executada menos que n2 vezes.
Todas as demais linhas so executadas no mximo n 1 vezes. Logo, o consumo de
tempo total do algoritmo est em
O(n2 )
no pior caso. Uma anlise um pouco mais cuidadosa mostra que o consumo est em
(n2 ) no pior caso.
46
FEOFILOFF
Exerccios
8.3 Mostre que o algoritmo I NTERVALOS C OMPATVEIS pode ser implementado de modo a consumir apenas O(n) unidades de tempo. Sugesto: construa uma tabela auxiliar que produza, em tempo constante, efeito equivalente ao das linhas 4-5.
8.4 Escreva um algoritmo de ps-processamento que extraia da tabela X[1 . . n] produzida pelo
algoritmo I NTERVALOS C OMPATVEIS um svvm de {1, . . . , n}. O seu algoritmo deve consumir O(n) unidades de tempo.
Notas bibliogrficas
O problema dos intervalos valorados discutido no livro de Kleinberg e Tardos [10]. O
verbete Interval scheduling na Wikipedia trata do escalonamento de intervalos.
Captulo 9
As linhas de um pargrafo
Um pargrafo de texto uma sequncia de palavras, sendo cada palavra uma sequncia de caracteres. Queremos imprimir um pargrafo em uma ou mais linhas consecutivas de uma folha de papel de tal modo que cada linha tenha no mximo L caracteres.
As palavras do pargrafo no devem ser quebradas entre linhas e cada duas palavras
consecutivas numa linha devem ser separadas por um espao.
Para que a margem direita fique razoavelmente uniforme, queremos distribuir as
palavras pelas linhas de modo a minimizar a soma dos cubos dos espaos em branco
que sobram no fim de todas as linhas exceto a ltima.
9.1
O problema
48
FEOFILOFF
Figura 9.1: Duas decomposies do mesmo pargrafo. As linhas tm capacidade L = 30 e os caracteres - representam os espaos em branco que contribuem para o defeito. O defeito da primeira decomposio 03 + 53 = 125 e o da
segunda 43 + 13 = 65.
ccc
bbb ccc
aaa bbb-ccc
Exerccios
9.1 Tente explicar por que a definio de defeito usa a terceira potncia e no a primeira ou a
segunda.
9.2 Considere a seguinte heurstica gulosa: preencha a primeira linha at onde for possvel,
depois preencha o mximo possvel da segunda linha, e assim por diante. Mostre que esta
heurstica no resolve o problema.
9.3 Suponha que ci = 1 para i = n, . . . , 1. Mostre que o defeito de uma decomposio tima
no mximo b2n/Lc.
9.2
49
ANLISE DE ALGORITMOS
sendo o mnimo tomado sobre todos os trechos curtos da forma (n, k).
A recorrncia poderia ser transformada facilmente num algoritmo recursivo. Mas
o clculo do min em (9.1) levaria o algoritmo a resolver as mesmas subinstncias vrias
vezes, o que muito ineficiente.
9.3
Para usar a recorrncia (9.1) de maneira eficiente, basta interpretar X como uma tabela X[1 . . n] e calcular X[n], depois X[n1], e assim por diante. Esta a tcnica da
programao dinmica. O seguinte algoritmo implementa esta ideia. Ele devolve o defeito mnimo de um pargrafo cn , cn1 , . . . , c1 supondo n 1, linhas de capacidade L
e ci L para todo i:
D EFEITO M NIMO (cn , . . . , c1 , L)
1 para m 1 at n faa
2
X[m]
3
km
4
s cm
5
enquanto k > 1 e s L faa
6
X 0 (L s)3 + X[k1]
7
se X 0 < X[m] ento X[m] X 0
8
k k1
9
s s + 1 + ck
10
se s L ento X[m] 0
11 devolva X[n]
(No difcil modificar o algoritmo de modo que ele produza uma decomposio
tima e no apenas o seu defeito.)
No incio de cada iterao do bloco de linhas 6-9, o valor da varivel s c(m, k). As
primeiras execues do processo iterativo descrito nas linhas 5-9 terminam tipicamente
50
FEOFILOFF
Exerccio
9.4 Modifique o algoritmo D EFEITO M NIMO para que ele devolva a descrio hkq , kq1 , . . . , k1 i
de uma decomposio tima do pargrafo cn , . . . , c1 e no apenas o defeito da decomposio.
Notas bibliogrficas
O problema que discutimos neste captulo proposto como exerccio nos livros de Cormen et al. [3], Parberry [17] e Parberry e Gasarch [18].
Captulo 10
10.1
O problema
10.2
Seja S uma soluo da instncia (n, p, c, v). Temos duas possibilidades, conforme n
esteja ou no em S. Se n
/ S ento S tambm um soluo da instncia (n 1, p, c, v).
Se n S ento S {n} soluo de (n 1, p, c pn , v).
Podemos resumir isso dizendo que o problema tem estrutura recursiva: toda soluo de uma instncia do problema contm solues de instncias menores.
Se denotarmos por X(n, c) o valor de um soluo de (n, p, c, v), a estrutura recur51
52
FEOFILOFF
(10.1)
(10.2)
quando pn > c.
Poderamos calcular X(n, c) recursivamente. Mas o algoritmo resultante muito
ineficiente, pois resolve cada subinstncia um grande nmero de vezes.
Exerccio
10.1 Escreva um algoritmo recursivo baseado na recorrncia (10.1-10.2). Calcule o consumo de
tempo do seu algoritmo no pior caso. (Sugesto: para cada n, tome a instncia em que
c = n e pi = vi = 1 para cada i. Mostre que o consumo de tempo T (n) para essa famlia de
instncias satisfaz a recorrncia T (n) = 2T (n 1) + 1.)
10.3
Para obter um algoritmo eficiente a partir da recorrncia (10.1-10.2), preciso armazenar as solues das subinstncias numa tabela medida que elas forem sendo obtidas,
evitando assim que elas sejam recalculadas. Esta a tcnica da programao dinmica,
que j encontramos em captulos anteriores.
Como c e todos os pi so nmeros naturais, podemos tratar X como uma tabela
com linhas indexadas por 0 . . n e colunas indexadas por 0 . . c. Para cada i entre 0 e n
e cada b entre 0 e c, a casa X[i, b] da tabela ser o valor de uma soluo da instncia
(i, p, b, v). As casas da tabela X precisam ser preenchidas na ordem certa, de modo
que toda vez que uma casa for requisitada o seu valor j tenha sido calculado.
O algoritmo abaixo recebe uma instncia (n, p, c, v) do problema e devolve o valor
de uma soluo da instncia:1
M OCHILA PD (n, p, c, v)
1 para b 0 at c faa
2
X[0, b] 0
3
para j 1 at n faa
4
x X[j 1, b]
5
se b pj 0
6
ento y X[j 1, b pj ] + vj
7
se x < y ento x y
8
X[j, b] x
9 devolva X[n, c]
1
fcil extrair da tabela X um subconjunto vivel de {1, . . . , n} que tenha valor X[n, c]. Veja o Exerccio 10.4.
53
ANLISE DE ALGORITMOS
p
4
2
1
3
v
500
400
300
450
0
1
2
3
4
0
1
2
3
4
5
0
0
0
0
0
0
0
0
0
0 500 500
0
0 400 400 500 500
0 300 400 700 700 800
0 300 400 700 750 850
O algoritmo est correto. A cada passagem pela linha 1, imediatamente antes das
comparao de b com c, as b primeiras colunas da tabela esto corretas, ou seja,
X[i, a] o valor de uma soluo da instncia (i, p, a, v)
(10.3)
para todo i no intervalo 0 . . n e todo a no intervalo 0 . . b1. Para provar este invariante,
basta entender o processo iterativo nas linhas 3 a 8. No incio de cada iterao desse
processo,
X[i, b] o valor de uma soluo da instncia (i, p, b, v)
(10.4)
para todo i no intervalo 0 . . j1. Se o invariante (10.4) vale no incio de uma iterao,
ele continua valendo no incio da iterao seguinte em virtude da recorrncia (10.110.2). Isto prova que (10.3) de fato vale a cada passagem pela linha 1.
Na ltima passagem pela linha 1 temos b = c + 1 e portanto (10.3) garante que
X[n, c] o valor de uma soluo da instncia (n, p, c, v).
Consumo de tempo. razovel supor que uma execuo de qualquer das linhas
do cdigo consome uma quantidade de tempo que no depende de n nem de c. Portanto, basta contar o nmero de execues das diversas linhas.
Para cada valor fixo de b, o bloco de linhas 4-8 executado n vezes. Como b varia
de 0 a c, o nmero total de execues do bloco de linhas 4-8 (c + 1)n. As demais linhas
so executadas no mximo c + 1 vezes. Esta discusso mostra que o algoritmo consome
(nc)
unidades de tempo. (Poderamos ter chegado mesma concluso observando que o
consumo de tempo do algoritmo proporcional ao nmero de casas da tabela X.)
O consumo de tempo de M OCHILA PD muito sensvel s variaes de c. Imagine, por exemplo, que c e os elementos de p so todos multiplicados por 100. Como
isto constitui uma mera mudana de escala, a nova instncia do problema conceitualmente idntica original. No entanto, nosso algoritmo consumir 100 vezes mais
tempo para resolver a nova instncia.
54
FEOFILOFF
Exerccios
10.2 verdade que X[i, 0] = 0 para todo i depois da execuo do algoritmo M OCHILA PD?
10.3 Por que nosso enunciado do problema inclui instncias em que c vale 0? Por que inclui
instncias com objetos de peso nulo?
10.4 Mostre como extrair da tabela X[0 . . n, 0 . . c] produzida pelo algoritmo M OCHILA PD um
subconjunto timo de {1, . . . , n}.
10.5 Faa uma mudana de escala para transformar o conjunto {0, 1, . . . , c} no conjunto de
nmeros racionais entre 0 e n. Aplique o mesmo fator de escala aos pesos pi . O algoritmo
M OCHILA PD pode ser aplicado a essa nova instncia do problema?
10.4
Notas bibliogrficas
O problema da mochila discutido na Seo 16.2 do livro de Cormen et al. [3] e na
Seo 8.4 do livro de Brassard e Bratley [2], por exemplo.
2
Captulo 11
11.1
O problema
Convm repetir algumas das definies da Seo 10.1. Dados nmeros naturais
p1 , . . . , pn , c e v1 , . . . , vn , diremos que pi o peso e vi o P
valor de i. Para qualquer
subconjunto S de {1, . . . , n}, denotaremos por p(S) aP
soma iS pi e diremos que S
vivel se p(S) c. O valor de S o nmero v(S) := iS vi . Um conjunto vivel S
timo se v(S ) v(S) para todo conjunto vivel S.
Problema da Mochila: Dados nmeros naturais p1 , . . . , pn , c, v1 , . . . , vn , encontrar um subconjunto vivel timo de {1, . . . , n}.
Todo objeto de peso maior que c pode ser ignorado e qualquer objeto de peso nulo
pode ser includo em todos os conjuntos viveis. Suporemos ento, daqui em diante,
que
1 pi c
(11.1)
para todo i.
11.2
Algoritmo de aproximao
O algoritmo que descreveremos a seguir tem carter guloso e d preferncia aos objetos de maior valor especfico. O valor especfico de um objeto i o nmero vi /pi . Para
simplificar a descrio do algoritmo, suporemos que os objetos so dados em ordem
1
55
56
FEOFILOFF
.
p1
p2
pn
(11.2)
Nosso algoritmo recebe uma instncia do problema que satisfaz as condies (11.1)
e (11.2) e devolve um subconjunto vivel X de {1, . . . , n} tal que
v(X) 12 v(S ) ,
sendo S um subconjunto vivel timo:
M OCHILA Q UASE TIMA (n, p, c, v)
1 X
2 sx0
3 k1
4 enquanto k n e s + pk c faa
5
X X {k}
6
s s + pk
7
x x + vk
8
k k+1
9 se k > n ou x vk
10
ento devolva X
11
seno devolva {k}
O bloco de linhas 4 a 8 determina o maior k tal que p1 + + pk1 c. No incio
da linha 9, X = {1, . . . , k1}, s = p(X) e x = v(X).
O algoritmo est correto. No incio da linha 9, claro que X vivel. Se k > n
ento X = {1, . . . , n} e o algoritmo adota X como soluo. Nesse caso, evidente que
v(X) 21 v(S) para todo conjunto vivel S, como prometido.
Suponha agora que k n no incio da linha 9. Graas hiptese (11.1), o conjunto
{k} vivel e o algoritmo adota como soluo o mais valioso dentre X e {k}. Resta
mostrar que
max (v(X), vk ) 12 v(S)
para todo conjunto vivel S. O primeiro passo da demonstrao consiste na seguinte
observao:
max (v(X), vk ) 12 (v(X) + vk ) = 12 v(R) ,
sendo R := X {k}. O segundo passo mostra que v(R) > v(S) qualquer que seja o
57
ANLISE DE ALGORITMOS
conjunto vivel S:
v(R) v(S) = v(R S) v(S R)
X
X
=
vi
vi
iRS
iRS
=
>
=
iSR
X vi
X vi
pi
pi
pi
pi
iSR
vk
vk
p(R S)
p(S R)
pk
pk
vk
p(R) p(S)
pk
vk
cc
pk
0.
(11.3)
(11.4)
A relao (11.3) vale porque vi /pi vk /pk para todo i em R e vi /pi vk /pk para todo i
no complemento de R. J (11.4) vale porque p(R) > c e p(S) c.
Consumo de tempo. Adote n (poderia igualmente ter adotado 2n + 1) como medida do tamanho da instncia (n, p, c, v) do problema. Uma execuo de qualquer
das linhas do algoritmo consome uma quantidade de tempo que no depende de n. O
bloco de linhas 5-8 executado no mximo n vezes. Assim, o algoritmo todo consome
(n)
unidades de tempo, tanto no pior quanto no melhor caso. O algoritmo propriamente
dito , portanto, linear.
O pr-processamento necessrio para fazer valer (11.1) e (11.2) pode ser feito em
tempo (n lg n) (veja o Captulo 4). Portanto, o consumo de tempo do processo todo
(n lg n) .
Exerccio
11.1 Construa uma instncia do Problema da Mochila para a qual o algoritmo devolve {k} na
linha 11.
11.3
58
FEOFILOFF
Outros algoritmos de aproximao para o Problema da Mochila tm fator de aproximao bem melhor que 50%. O algoritmo de Ibarra e Kim (veja o livro de Fernandes et al. [8], por exemplo) garante um fator de aproximao to prximo de 100%
quanto o usurio desejar. Como seria de se esperar, o consumo de tempo do algoritmo
tanto maior quanto maior o fator de aproximao solicitado. O algoritmo de Ibarra e
Kim baseado numa variante de M OCHILA PD em que os papis de p e v so trocados.
(Veja o Exerccio 10.5.)
Notas bibliogrficas
Algoritmos de aproximao para o Problema da Mochila so discutidos na Seo 13.2
do livro de Brassard e Bratley [2].
Captulo 12
A cobertura de um grafo
Imagine um conjunto de salas interligadas por tneis. Um guarda postado numa sala
capaz de vigiar todos os tneis que convergem sobre a sala. Queremos determinar o
nmero mnimo de guardas suficiente para vigiar todos os tneis.
Se houver um custo associado com cada sala (este o custo de manter um guarda
na sala), queremos determinar o conjunto mais barato de guardas capaz de manter
todos os tneis sob vigilncia.
12.1
Grafos
Um grafo um par (V, A) de conjuntos tal que A V2 . Cada elemento de A , portanto, um par no ordenado de elementos de V . Os elementos de V so chamados
vrtices e os de A so chamados arestas.
Uma aresta {i, j} usualmente denotada por ij. Os vrtices i e j so as pontas
desta aresta.
12.2
O problema da cobertura
Uma cobertura de um grafo um conjunto X de vrtices que contm pelo menos uma
das pontas de cada aresta.
P Se cada vrtice i tem um custo ci , o custo de uma cobertura
X o nmero c(X) := iX ci .
Problema da Cobertura: Dado um grafo cujos vrtices tm custos em N, encontrar uma cobertura de custo mnimo.
Poderamos resolver o problema examinando todos os subconjuntos do conjunto
de vrtices, mas um tal algoritmo explosivamente lento: seu consumo de tempo
cresce exponencialmente com o nmero de vrtices. Infelizmente, acredita-se que
no existem algoritmos substancialmente mais rpidos para o problema, nem mesmo
quando todos os vrtices tm custo unitrio.1
1
59
60
FEOFILOFF
Faz sentido, portanto, procurar por um bom algoritmo de aproximao, um algoritmo rpido que encontre uma cobertura cujo custo seja limitado por um mltiplo
predeterminado do timo. (Veja a Seo 11.3.)
r
r
r
r
r
r
r
r
r
r
Exerccio
12.1 Seja (V, A) um grafo. Ignore os custos dos vrtices do grafo. Uma cobertura X desse grafo
mnima se no existe uma cobertura X 0 tal que |X 0 | < |X|. Uma cobertura X minimal
se no existe uma cobertura X 0 tal que X 0 X. Mostre que uma cobertura minimal pode
ser arbitrariamente maior que uma cobertura mnima.
12.3
Um algoritmo de aproximao
O seguinte algoritmo recebe um grafo (V, A) e um nmero natural ci para cada vrtice i
e devolve uma cobertura X tal que c(X) 2 c(X ), sendo X uma cobertura de custo
mnimo:
C OBERTURA B ARATA (V, A, c)
1 para cada i em V faa
2
xi 0
3 para cada ij em A faa
4
yij 0
5 para cada pq em A faa
6
e min (cp xp , cq xq )
7
ypq ypq + e
8
xp xp + e
9
xq xq + e
10 X
11 para cada i em V faa
12
se xi = ci ento X X {i}
13 devolva X
O algoritmo atribui nmeros naturais y s arestas. Voc pode imaginar que ypq
a quantia que a aresta pq paga a cada uma de suas pontas para convencer
Puma delas
a fazer parte da cobertura. Um vrtice p aceita participar da cobertura se q ypq cp ,
sendo a soma feita sobre todas as arestas
P que tm ponta p. A regra do jogo nunca
pagar mais que o necessrio. Portanto, q ypq cp para todo vrtice p.
61
ANLISE DE ALGORITMOS
O algoritmo est correto. No incio de cada iterao do bloco de linhas 6-9, temos
os seguintes invariantes:
P
i. xi = j yij para todo i em V ,
ii. xi ci para todo i em V ,
iii. para toda aresta ij j examinada tem-se xi = ci ou xj = cj .
Estas propriedades so obviamente verdadeiras no incio da primeira iterao. No
incio de cada iterao subsequente, o invariante i continua valendo, pois ypq , xp e xq
so acrescidos da mesma quantidade e. O invariante ii continua valendo, pois e
cp xp e e cq xq . O invariante iii continua valendo, pois e = cp xp ou e = cq xq .
Os invariantes i e ii tm a seguinte consequncia: no incio de cada iterao do
bloco de linhas 6-9, temos
X
yij c(Z)
(12.1)
ijA
P
para
qualquer
cobertura
Z.
Para
mostrar
isso,
basta
observar
que
ijA yij
P
P
P
P
iZ
j yij =
iZ xi
iZ ci . A primeira desigualdade vale porque toda aresta
tem pelo menos uma de suas pontas em Z. A igualdade seguinte vale em virtude do
invariante i. A ltima desigualdade decorre do invariante ii.
Agora observe que no fim do bloco de linhas 10-12 temos
X
c(X) 2
yij .
(12.2)
ijA
P
P
P
P
DePfato, como xi = ci para todo i em X, temos iX ci = iX xi = iX j yij
2 ijA yij . A segunda igualdade vale em virtude do invariante i. A ltima desigualdade verdadeira pois cada aresta tem no mximo duas pontas em X.
Segue de (12.2) e (12.1) que, depois do bloco de linhas 10-12, para qualquer cobertura Z,
c(X) 2 c(Z) .
Isto vale, em particular, se Z uma cobertura de custo mnimo. Como X uma cobertura (em virtude do invariante iii), o algoritmo cumpre o que prometeu.
O fator de aproximao 2 pode parecer ser grosseiro, mas o fato que ningum
descobriu ainda um algoritmo eficiente com fator de aproximao 1.9 por exemplo.
Consumo de tempo. Podemos supor que o grafo dado da maneira mais crua
possvel: os vrtices so 1, 2, . . . , n e as arestas so listadas em ordem arbitrria.
Seja m o nmero de arestas do grafo e adote o par (n, m) como tamanho de uma
instncia do problema. Podemos supor que uma execuo de qualquer das linhas do
algoritmo consome tempo que no depende de n nem de m. A linha 2 executada n
vezes. A linha 4 executada m vezes. A linha 12 executada n vezes. O bloco de
linhas 6-9 repetido m vezes. Assim, o consumo de tempo total do algoritmo est em
(n + m) ,
tanto no pior quanto no melhor caso. O algoritmo , portanto, linear.
62
12.4
FEOFILOFF
Exerccio
12.2 Considere as instncias do Problema da Cobertura em que todos os vrtices tm o mesmo
custo. D um algoritmo de aproximao para essas instncias que seja mais simples que
C OBERTURA B ARATA. O seu algoritmo deve produzir uma cobertura de tamanho no superior ao dobro do timo.
12.5
Um grafo bipartido se seu conjunto de vrtices admite uma bipartio (U, W ) tal que
toda aresta tem uma ponta em U e outra em W . (Portanto, U e W so coberturas.)
Existe um algoritmo muito elegante e eficiente para o Problema da Cobertura restrito a grafos bipartidos. (Veja a Seo 22.4 do livro de Sedgewick [19], por exemplo.)
O algoritmo consome (nm) unidades de tempo no pior caso, sendo n o nmero de
vrtices e m o nmero de arestas do grafo.
Notas bibliogrficas
Este captulo foi baseado no livro de Kleinberg e Tardos [10].
Captulo 13
13.1
O problema
63
64
FEOFILOFF
Exerccio
13.1 Mostre que o problema dos intervalos compatveis discutido no Captulo 8 um caso
especial (ou seja, uma coleo de instncias) do problema do conjunto independente.
13.2 Um conjunto independente I em um grafo maximal se no existe um conjunto independente I 0 no grafo tal que I 0 I. Mostre que um conjunto independente maximal pode ser
arbitrariamente menor que um conjunto independente mximo.
13.2
Algoritmo probabilstico
Convm lembrar que todo grafo com n vrtices tem entre 0 e n2 arestas. Portanto, se
m o nmero de arestas ento 0 2m n2 n. O algoritmo que discutiremos a seguir
produz um conjunto independente I cujo tamanho esperado
n2 /4m .
O resultado intuitivamente razovel: quanto mais denso o grafo, ou seja, quanto mais
prximo m de n2 , menor o tamanho esperado de I.
m
n/2
2n
10n
n2 /4m
n/2
n/4
n/8
n/40
n n/4
n2 /4
(n2 n)/2
n/(2n 2)
65
ANLISE DE ALGORITMOS
n2
n
=
.
2m
2m
n2
n2
n2
=
.
2m 4m
4m
66
FEOFILOFF
13.3
Notas bibliogrficas
O algoritmo deste captulo descrito, por exemplo, no livro de Mitzenmacher e Upfal [15]. Sobre algoritmos aleatorizados em geral, veja o verbete Randomized algorithm
na Wikipedia.
Captulo 14
14.1
O problema do componente
14.2
67
68
FEOFILOFF
P C = ,
v P C,
todo vrtice em P C est ligado a v e
toda aresta com uma ponta em P tem a outra ponta em P C.
evidente que estas propriedades valem no incio da primeira iterao. Suponha agora
que elas valem no incio de uma iterao qualquer. claro que i e ii continuam valendo
no incio da prxima iterao. No caso do invariante iii, basta verificar que os vrtices
acrescentados a P C durante esta iterao esto todos ligados a v. Para isso, suficiente observar que i est ligado a v (invariante iii) e portanto todos os vrtices em Z(i)
tambm esto ligados a v.
Finalmente, considere o invariante iv. Por um lado, o nico vrtice acrescentado a
P durante a iterao corrente i. Por outro lado, ao final da iterao, todos os vizinhos
de i esto em P C. Assim, o invariante iv continua vlido no incio da prxima
iterao.
No fim do processo iterativo, C est vazio. De acordo com os invariantes ii e iv,
todos os vrtices de qualquer caminho que comea em v esto em P . Reciprocamente,
todo vrtice em P est ligado a v, de acordo com invariante iii. Portanto, P o conjunto
de vrtices ligados a v. Assim, ao devolver P , o algoritmo cumpre o que prometeu.
Consumo de tempo. No h como discutir o consumo de tempo do algoritmo
de maneira precisa, pois no especificamos estruturas de dados que representem as
vizinhanas Z(i) e os conjuntos P e C.
69
ANLISE DE ALGORITMOS
Exerccios
14.1 Um grafo conexo se seus vrtices esto ligados dois a dois. Escreva um algoritmo que
decida se um grafo conexo.
14.2 Escreva um algoritmo que calcule o nmero de componentes de um grafo.
14.3
Podemos tratar agora de uma verso mais concreta do algoritmo C OMPONENTE P RE LIM , que adota estruturas de dados apropriadas para representar os vrios conjuntos
de vrtices.
Suponha que os vrtices do grafo so 1, 2, . . . , n. As vizinhanas dos vrtices sero
representadas por uma matriz Z com linhas indexadas pelos vrtices e colunas indexadas por 1, 2, . . . , n 1. Os vizinhos de um vrtice i sero
Z[i, 1], Z[i, 2], . . . , Z[i, g[i]] ,
onde g[i] o grau de i, ou seja, o nmero de vizinhos de i. (Na prtica, usam-se listas
encadeadas para representar essas vizinhanas.) Observe que cada aresta ij aparece
exatamente duas vezes nesta representao: uma vez na linha i da matriz Z e outra vez
na linha j.
Os conjuntos P e C da seo anterior sero representados por um vetor cor indexado pelos vrtices: cor [i] valer 2 se i P , valer 1 se i C e valer 0 nos demais
casos. O conjunto C ter tambm uma segunda representao: seus elementos ficaro
armazenados num vetor F [a . . b], que funcionar como uma fila com incio a e fim b.
Isso permitir implementar de maneira eficiente o teste C 6= na linha 3 de C OMPO NENTE P RELIM, bem como a escolha de i em C na linha 4.
O algoritmo recebe um grafo com vrtices 1, 2, . . . , n, representado por seu vetor de
graus g e sua matriz de vizinhos Z e recebe um vrtice v. O algoritmo devolve um vetor
cor [1 . . n] que representa o conjunto de vrtices ligados a v (os vrtices do componente
so os que tm cor 2).
70
FEOFILOFF
C OMPONENTE (n, g, Z, v)
1 para i 1 at n faa
2
cor [i] 0
3 cor [v] 1
4 ab1
5 F [b] v
6 enquanto a b faa
7
i F [a]
8
para h 1 at g[i] faa
9
j Z[i, h]
10
se cor [j] = 0
11
ento cor [j] 1
12
bb+1
13
F [b] j
14
cor [i] 2
15
aa+1
16 devolva cor [1 . . n]
O algoritmo C OMPONENTE est correto pois o cdigo no faz mais que implementar o algoritmo C OMPONENTE P RELIM, que j discutimos.
Consumo de tempo. SejaP
m o nmero de arestas do grafo. (Em termos dos parmetros do algoritmo, m 12 ni=1 g[i].) Adotaremos o par (n, m) como medida do
tamanho de uma instncia do problema.
Podemos supor que uma execuo de qualquer das linhas do algoritmo consome
uma quantidade de tempo que no depende de n nem de m. A linha 7 executada n
vezes no pior caso, pois cada vrtice do grafo faz o papel de i na linha 7 uma s vez ao
longo da execuo do algoritmo. (Segue da, em particular, que b n.) Para cada valor
fixo de i, o bloco de linhas 9-13 executado g[i] vezes. Segue dessas duas observaes
que, no pior caso, o processo iterativo nas linhas 6-15 consome tempo proporcional
soma
n
X
g[i] ,
i=1
que vale 2m. O consumo desse processo iterativo est, portanto, em (m) no pior caso.
Como o consumo de tempo das linhas 1-5 est em (n), o consumo de tempo total
do algoritmo est em
(n + m)
no pior caso. (No melhor caso, o vrtice v no tem vizinhos e portanto o algoritmo
consome apenas (n) unidades de tempo.)
Exerccio
14.3 Escreva um algoritmo que calcule um caminho de comprimento mnimo dentre os que
ligam dois vrtices dados de um grafo. (O comprimento de um caminho o nmero de
arestas do caminho.)
Captulo 15
15.1
Busca em profundidade
71
72
FEOFILOFF
onde X o conjunto dos vrtices ligados a p por caminhos brancos e g(x) := |Z(x)| o
grau do vrtice x.
A rotina est correta. A prova da correo da rotina B USCA E M P ROFUNDIDADE
uma induo no tamanho da instncia. Se o tamanho for 0, o vrtice p no tem vizinhos.
Se o tamanho for 1, o nico vrtice em Z(p) preto. Em qualquer desses casos, a rotina
cumpre o que prometeu.
Suponha agora que o tamanho da instncia maior que 1. Seja B o conjunto de
vrtices brancos no incio da execuo da rotina e seja X o conjunto dos vrtices ligados
a p em B. Queremos mostrar que no fim do processo iterativo descrito nas linhas 6-8 o
conjunto dos vrtices brancos B X.
Sejam q1 , q2 , . . . , qk os elementos de Z(p) na ordem em que eles sero examinados
na linha 6. Para j = 1, 2, . . . , k, seja Yj o conjunto dos vrtices ligados a qj em B {p}.
claro que X = {p} Y1 Yk .
Se Yi Yj 6= ento Yi = Yj . De fato, se Yi e Yj tm um vrtice em comum ento
existe um caminho em B {p} com origem qi e trmino em Yj . Portanto tambm existe
um caminho em B {p} de qi a qj , donde qj Yi . Segue da que Yj Yi . Um raciocnio
anlogo mostra que Yi Yj .
O processo iterativo descrito nas linhas 6-8 pode ser reescrito como
6
7
8
para j 1 at k faa
se cor [qj ] = 0
ento B USCA E M P ROFUNDIDADE (qj )
73
ANLISE DE ALGORITMOS
(15.2)
Esta propriedade certamente vale no incio da primeira iterao. Suponha agora que
ela vale no incio de uma iterao qualquer. Se tivermos Yj = Yi para algum i entre 1
e j 1 ento, no incio desta iterao, todos os vrtices em Yj j so pretos e a linha 8 no
executada. Caso contrrio, Yj disjunto de Y1 Yj1 e portanto
os vrtices
todosP
em Yj esto ligados a qj por caminhos em B {p} Y1 Yj1 . Como yYj g(y)
P
menor que xX g(x), podemos supor, por hiptese de induo, que a invocao de
B USCA E M P ROFUNDIDADE na linha 8 com argumento qj produz o resultado prometido.
Assim, no fim desta iterao, o conjunto dos vrtices brancos B {p} Y1 Yj .
Isto prova que (15.2) continua valendo no incio da prxima iterao.
No fim do processo iterativo, o invariante (15.2) garante que o conjunto de vrtices
brancos B {p}) Y1 Yk , ou seja, B X. Logo, B USCA E M P ROFUNDIDADE
cumpre o que prometeu.
Consumo de tempo. A anlise da correo da rotina B USCA E M P ROFUNDIDADE
permite
concluir que o consumo de tempo da rotina proporcional ao tamanho,
P
xX g(x), da instncia.
P Em particular, o consumo de tempo da linha 3 de C OM PONENTE no passa de
xV g(x). Como esta soma igual ao dobro do nmero de
arestas do grafo, m, podemos dizer que a linha 3 de C OMPONENTE consome
O(m)
unidades de tempo. No pior caso, o consumo (m).
Se levarmos em conta o consumo de tempo das linhas 1-2 de C OMPONENTE, teremos um consumo total de
(n + m)
unidades de tempo no pior caso.
Exerccio
15.1 Escreva e analise uma verso no recursiva do algoritmo B USCA E M P ROFUNDIDADE.
74
FEOFILOFF
Posfcio
O texto fez uma modesta introduo Anlise de Algoritmos usando material dos
excelentes livros citados na bibliografia. Embora tenha tratado apenas de problemas
e algoritmos muito simples, espero que este minicurso possa guiar o leitor que queira
analisar os seus prprios algoritmos.
O tratamento de algoritmos probabilsticos foi muito superficial e muitos outros
assuntos ficaram de fora por falta de espao. Assim, no foi possvel discutir a anlise
de tipos abstratos de dados, como filas de prioridades e estruturas union/find. A anlise
amortizada (muito til para estimar o consumo de tempo dos algoritmos de fluxo em
redes, por exemplo) foi igualmente ignorada. Finalmente, no foi possvel mencionar
a teoria da complexidade de problemas e a questo P=NP.
75
Bibliografia
[1] J.L. Bentley. Programming Pearls. ACM Press, second edition, 2000. 9, 27, 31, 32, 36
[2] G. Brassard and P. Bratley. Fundamentals of Algorithmics. Prentice Hall, 1996. 9, 22,
23, 42, 54, 58
[3] T.H. Cormen, C.E. Leiserson, R.L. Rivest, and C. Stein. Introduction to Algorithms.
MIT Press and McGraw-Hill, second edition, 2001. 9, 11, 22, 50, 54, 55, 59
[4] S. Dasgupta, C.H. Papadimitriou, and U.V. Vazirani. Algorithms. McGraw-Hill,
2006. 42
[5] A.C.P.L. de Carvalho and T. Kowaltowski, editors. Atualizaes em Informtica 2009.
SBC (Soc. Bras. de Computao). PUC-Rio, 2009. ISBN 978-85-87926-54-8. 7
[6] P. Feofiloff. Algoritmos de Programao Linear. Internet http://www.ime.usp.
br/~pf/prog-lin/, 1999. 206 pginas. 62
[7] P. Feofiloff. Anlise de Algoritmos.
analise_de_algoritmos/, 2011.
Internet http://www.ime.usp.br/~pf/
[8] C.G. Fernandes, F.K. Miyazawa, M. Cerioli, and P. Feofiloff, editors. Uma Introduo Sucinta a Algoritmos de Aproximao. XXIII Colquio Brasileiro de Matemtica.
IMPA (Instituto de Matemtica Pura e Aplicada), Rio de Janeiro, 2001. Internet
http://www.ime.usp.br/~cris/aprox/. 58
[9] J. Hromkovic. Algorithmics for Hard Problems: Introduction to Combinatorial Optimization, Randomization, Approximation, and Heuristics. Springer, second edition,
2004.
[10] J. Kleinberg and E. Tardos. Algorithm Design. Addison-Wesley, 2005. 9, 42, 46, 62
[11] D.E. Knuth. Seminumerical Algorithms, volume 2 of The Art of Computer Programming. Addison-Wesley, third edition, 1997. 42
[12] D.E. Knuth. Selected Papers on Analysis of Algorithms. CSLI Lecture Notes, no. 102.
Center for the Study of Language and Information (CSLI), Stanford, CA, 2000. 9
[13] D.E. Knuth. The Art of Computer Programming. Addison-Wesley, ca. 1973. Several
volumes.
77
ndice remissivo
bxc, 11, 12
dxe, 12
lg n, 11
( ), 14
( ), 15
N, 12
N> , 12
R, 12
R , 12
R> , 12
algoritmo, 9
aleatorizado, 66
correto, 9
de aproximao, 57
de Karatsuba, 40
ene-log-ene, 16
exponencial, 16
guloso, 43, 44, 54
linear, 16
ineartmico, 16
Mergesort, 25
polinomial, 16
primal-dual, 62
probabilstico, 66
quadrtico, 16
recursivo, 11, 25, 39, 44, 49, 52, 71
anlise assinttica, 13
aproximao (algoritmo de), 57
aresta (de grafo), 59
assintoticamente no decrescente, 22
assinttico, 13
Bentley, 9, 27, 31, 32, 36
BFS, 67
Brassard, 9, 22, 23, 42, 54, 58
Bratley, 9, 22, 23, 42, 54, 58
breadth-first search, 67
bucket sort, 33
busca
em largura, 67
em profundidade, 71
caminho (em grafo), 67
cobertura (de grafo), 59
compatveis (intervalos), 43
componente (de grafo), 67
conexo (grafo), 69
conjunto independente (em grafo), 63
consumo de tempo, 10
Cormen, 9, 11, 22, 50, 54, 55, 59
correo (de algoritmo), 9
crescente, 25
Dasgupta, 42
depth-first search, 71
DFS, 71
dgito, 37
dgitos (nmero de), 37
diviso e conquista, 22, 26, 29, 42
eficincia, 10
estrutura recursiva
de um problema, 11, 32, 44, 48, 51
firmeza (de vetor), 30
fortemente polinomial, 54
Gasarch, 50
grafo, 59
bipartido, 62
conexo, 69
grau de vrtice, 69
guloso (algoritmo), 43, 44, 54
induo matemtica, 11, 14, 18, 25
instncia de problema, 9
intercalao de vetores, 25, 26
intervalo, 43
invariante, 28, 31, 35, 49, 50, 53, 61, 68, 73
79
80
Karatsuba, 40
Kleinberg, 9, 42, 46, 62
Knuth, 9, 42
Leiserson, 9
lg n, 12
log, 11
maioria, 33
majoritrio, 33
Manber, 9, 36
maximal, 64
melhor caso, 10
Mergesort, 25
minimal, 60
mnimo, 60
Mitzenmacher, 66
mochila
de valor mximo, 51
de valor quase mximo, 55
multiplicao de nmeros, 37
N, 12
N> , 12
no decrescente, 22
notao
O grande, 13
mega grande, 14
Teta grande, 15
NP-difcil, 54, 55, 59
nmero de dgitos, 37
nmeros
naturais, 12
reais, 12
O( ), 13
( ), 14
O grande, 13
mega () grande, 14
Ofman, 42
palavra, 47
Papadimitriou, 42
pargrafo, 47
Parberry, 50
pen drive, 54
pior caso, 10
piso de logaritmo, 11
piso de nmero, 11, 12
pontas (de aresta), 59
primal-dual, 62
problema, 9
FEOFILOFF