Sie sind auf Seite 1von 13

Paradigmas de Projeto

de Algoritmos

ltima alterao: 10 de Outubro de 2006

Transparncias elaboradas por Charles Ornelas, Leonardo Rocha, Leonardo


Mata e Nivio Ziviani
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos 1
Paradigmas de Projeto de Algoritmos
induo,
recursividade,
algoritmos tentativa e erro,
diviso e conquista,
balanceamento,
programao dinmica,
algoritmos gulosos,
algoritmos aproximados.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.1 2
Induo Matemtica
til para provar asseres sobre a correo
e a ecincia de algoritmos.
Consiste em inferir uma lei geral a partir de
instncias particulares.
Seja T um teorema que que tenha como
parmetro um nmero natural n. Para provar
que T vlido para todos os valores de n,
basta provarmos que:
1. T vlido para n = 1;
2. Para todo n > 1, se T vlido para n 1,
ento T vlido para n.
A condio 1 chamada de passo base.
Provar a condio 2 geralmente mais fcil
que provar o teorema diretamente, uma vez
que podemos usar a assero de que T
vlido para n 1.
Esta armativa chamada de hiptese de
induo ou passo indutivo
As condies 1 e 2 implicam T vlido para
n = 2, o que junto com a condio 2 implica T
tambm vlido para n = 3, e assim por diante.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.1 3
Exemplo de Induo Matemtica
S(n) = 1 + 2 + + n = n(n + 1)/2
Para n = 1 a assero verdadeira, pois
S(1) = 1 = 1 (1 + 1)/2 (passo base).
Assumimos que a soma dos primeiros n
nmeros naturais S(n) n(n + 1)/2 (hiptese
de induo).
Pela denio de S(n) sabemos que
S(n + 1) = S(n) + n + 1.
Usando a hiptese de induo,
S(n+1) = n(n+1)/2+n+1 = (n+1)(n+2)/2,
que exatamente o que queremos provar.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.1 4
Limite Superior de Equaes de
Recorrncia
A soluo de uma equao de recorrncia
pode ser difcil de ser obtida.
Nesses casos, pode ser mais fcil tentar
adivinhar a soluo ou chegar a um limite
superior para a ordem de complexidade.
Adivinhar a soluo funciona bem quando
estamos interessados apenas em um limite
superior, ao invs da soluo exata.
Mostrar que um limite existe mais fcil do
que obter o limite.
Ex.: T(2n) 2T(n) + 2n 1, T(2) = 1,
denida para valores de n que so potncias
de 2.
O objetivo encontrar um limite superior
na notao O, onde o lado direito da
desigualdade representa o pior caso.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.1 5
Induo Matemtica para Resolver
Equao de Recorrncia
T(2n) 2T(n) + 2n 1, T(2) = 1, denida para
valores de n que so potncias de 2.
Procuramos f(n) tal que T(n) = O(f(n)), mas
fazendo com que f(n) seja o mais prximo
possvel da soluo real para T(n).
Vamos considerar o palpite f(n) = n
2
.
Queremos provar que T(n) = O(f(n))
utilizando induo matemtica em n.
Passo base: T(2) = 1 f(2) = 4.
Passo de induo: provar que T(n) f(n)
implica T(2n) f(2n).
T(2n) 2T(n) + 2n 1, (def. da recorrncia)
2n
2
+ 2n 1, (hiptese de induo)
< (2n)
2
,
que exatamente o que queremos provar.
Logo, T(n) = O(n
2
).
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.1 6
Induo Matemtica para Resolver
Equao de Recorrncia
Vamos tentar um palpite menor, f(n) = cn,
para alguma constante c.
Queremos provar que T(n) cn implica em
T(2n) c2n. Assim:
T(2n) 2T(n) + 2n 1, (def. da recorrncia)
2cn + 2n 1, (hiptese de induo)
> c2n.
cn cresce mais lentamente que T(n), pois
c2n = 2cn e no existe espao para o valor
2n 1.
Logo, T(n) est entre cn e n
2
.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.1 7
Induo Matemtica para Resolver
Equao de Recorrncia
Vamos ento tentar f(n) = nlog n.
Passo base: T(2) < 2 log 2.
Passo de induo: vamos assumir que
T(n) nlog n.
Queremos mostrar que T(2n) 2nlog 2n.
Assim:
T(2n) 2T(n) + 2n 1, (def. da recorrncia)
2nlog n + 2n 1, (hiptese de induo)
< 2nlog 2n,
A diferena entre as frmulas agora de
apenas 1.
De fato, T(n) = nlog n n + 1 a soluo
exata de T(n) = 2T(n/2) + n 1, T(1) = 0,
que descreve o comportamento do algoritmo
de ordenao Mergesort.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.2 8
Recursividade
Um mtodo que chama a si mesmo, direta ou
indiretamente, dito recursivo.
Recursividade permite descrever algoritmos
de forma mais clara e concisa, especialmente
problemas recursivos por natureza ou que
utilizam estruturas recursivas.
Ex.: rvore binria de pesquisa:
Todos os registros com chaves menores
esto na subrvore esquerda;
Todos os registros com chaves maiores
esto na subrvore direita.
2 4 6
3 7
5
1
package cap2;
public class ArvoreBinaria {
private static class No {
Object reg;
No esq, di r ;
}
private No rai z ;
}
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.2 9
Recursividade
Algoritmo para percorrer todos os registros
em ordem de caminhamento central:
1. caminha na subrvore esquerda na ordem
central;
2. visita a raiz;
3. caminha na subrvore direita na ordem
central.
No caminhamento central, os ns so
visitados em ordem lexicogrca das chaves.
private void central (No p) {
i f (p ! = null ) {
central (p.esq) ;
System. out . pri nt l n (p. reg. toString ( ) ) ;
central (p. di r ) ;
}
}
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.2.1 10
Implementao de Recursividade
Usa-se uma pilha para armazenar os dados
usados em cada chamada de um
procedimento que ainda no terminou.
Todos os dados no globais vo para a pilha,
registrando o estado corrente da computao.
Quando uma ativao anterior prossegue, os
dados da pilha so recuperados.
No caso do caminhamento central:
para cada chamada recursiva, o valor de p
e o endereo de retorno da chamada
recursiva so armazenados na pilha.
Quando encontra p=null o procedimento
retorna para quem chamou utilizando o
endereo de retorno que est no topo da
pilha.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.2.1 11
Problema de Terminao em
Procedimentos Recursivos
Procedimentos recursivos introduzem a
possibilidade de iteraes que podem no
terminar: existe a necessidade de considerar
o problema de terminao.
fundamental que a chamada recursiva a um
procedimento P esteja sujeita a uma
condio B, a qual se torna no-satisfeita em
algum momento da computao.
Esquema para procedimentos recursivos:
composio c de comandos S
i
e P.
P if B then c[S
i
, P]
Para demonstrar que uma repetio termina,
dene-se uma funo f(x), sendo x o
conjunto de variveis do programa, tal que:
1. f(x) 0 implica na condio de
terminao;
2. f(x) decrementada a cada iterao.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.2.1 12
Problema de Terminao em
Procedimentos Recursivos
Uma forma simples de garantir terminao
associar um parmetro n para P (no caso por
valor) e chamar P recursivamente com n 1.
A substituio da condio B por n > 0
garante terminao.
P if n > 0 then T[S
i
, P(n 1)]
necessrio mostrar que o nvel mais
profundo de recurso nito, e tambm
possa ser mantido pequeno, pois cada
ativao recursiva usa uma parcela de
memria para acomodar as variveis.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.2.2 13
Quando No Usar Recursividade
Nem todo problema de natureza recursiva
deve ser resolvido com um algoritmo
recursivo.
Estes podem ser caracterizados pelo
esquema P if B then (S, P)
Tais programas so facilmente transformveis
em uma verso no recursiva
P (x := x
0
; while B do S)
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.2.2 14
Exemplo de Quando No Usar
Recursividade
Clculo dos nmeros de Fibonacci
f
0
= 0, f
1
= 1,
f
n
= f
n1
+ f
n2
paran 2
Soluo: f
n
=
1

5
[
n
()
n
], onde
= (1 +

5)/2 1, 618 a razo de ouro.


O procedimento recursivo obtido diretamente
da equao o seguinte:
package cap2;
public class Fibonacci {
public static int fibRec ( int n) {
i f (n < 2) return n;
else return ( fibRec ( n1) + fibRec ( n2));
}
}
O programa extremamente ineciente
porque recalcula o mesmo valor vrias vezes.
Neste caso, a complexidade de espao para
calcular f
n
O(
n
).
Considerando que a complexidade de tempo
f(n) o nmero de adies, f(n) = O(
n
).
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.2.2 15
Verso iterativa do Clculo de
Fibonacci
package cap2;
public class Fibonacci {
public static int f i bI t er ( int n) {
int i = 1 , f = 0;
for ( int k = 1; k <= n; k++) {
f = i + f ;
i = f i ;
}
return f ;
}
}
O programa tem complexidade de tempo
O(n) e complexidade de espao O(1).
Devemos evitar uso de recursividade quando
existe uma soluo bvia por iterao.
Comparao verses recursiva e iterativa:
n 10 20 30 50 100
bRec 8 ms 1 s 2 min 21 dias 10
9
anos
bIter 1/6 ms 1/3 ms 1/2 ms 3/4 ms 1,5 ms
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.3 16
Algoritmos Tentativa e Erro
(Backtracking)
Tentativa e erro: decompor o processo em
um nmero nito de subtarefas parciais que
devem ser exploradas exaustivamente.
O processo de tentativa gradualmente
constri e percorre uma rvore de subtarefas.
Algoritmos tentativa e erro no seguem regra
xa de computao:
Passos em direo soluo nal so
tentados e registrados;
Caso esses passos tomados no levem
soluo nal, eles podem ser retirados e
apagados do registro.
Quando a pesquisa na rvore de solues
cresce rapidamente necessrio usar
algoritmos aproximados ou heursticas que
no garantem a soluo tima mas so
rpidos.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.3 17
Backtracking: Passeio do Cavalo
Tabuleiro com n n posies: cavalo
movimenta-se segundo as regras do xadrez.
Problema: a partir de (x
0
, y
0
), encontrar, se
existir, um passeio do cavalo que visita todos
os pontos do tabuleiro uma nica vez.
Tenta um prximo movimento:
void tenta ( ) {
inicializa seleo de movimentos;
do {
seleciona prximo candidato ao movimento;
i f ( aceitvel ) {
registra movimento;
i f ( tabuleiro no est cheio) {
tenta novo movimento; / / Chamada recursiva
para tenta
i f ( no sucedido) apaga registro anterior ;
}
}
} while ( movimento no sucedido e no acabaram can-
didatos a movimento) ;
}
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.3 18
Exemplo de Backtracking - Passeio do
Cavalo
O tabuleiro pode ser representado por uma
matriz n n.
A situao de cada posio pode ser
representada por um inteiro para recordar o
histrico das ocupaes:
t[x,y] = 0, campo < x, y > no visitado,
t[x,y] = i, campo < x, y > visitado no
i-simo movimento, 1 i n
2
.
Regras do xadrez para os movimentos do
cavalo:
4
3 2
1
8
7 6
5
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.3 19
Implementao do Passeio do Cavalo
package cap2;
public class PasseioCavalo {
private int n; / / Tamanho do lado do tabuleiro
private int a[ ] , b[ ] , t [ ] [ ] ;
public PasseioCavalo ( int n) {
this.n = n;
this. t = new int [n] [ n] ; this.a = new int [n] ;
this.b = new int [n] ;
a[ 0] = 2; a[ 1] = 1; a[2] =1; a[3] =2;
b[ 0] = 1; b[ 1] = 2; b[ 2] = 2; b[ 3] = 1;
a[4] = 2; a[5] = 1; a[ 6] = 1; a[ 7] = 2;
b[4] = 1; b[5] = 2; b[6] =2; b[7] = 1;
for ( int i = 0; i < n; i ++)
for ( int j = 0; j < n; j ++) t [ i ] [ j ] = 0;
t [ 0] [ 0] = 1; / / escolhemos uma casa do tabuleiro
}
/ / { Entra aqui os mtodos tenta, imprimePasseio e main mos-
trados a seguir }
}
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.3 20
Implementao do Passeio do Cavalo
public boolean tenta ( int i , int x, int y) {
int u, v, k; boolean q;
k = 1; / / inicializa seleo de movimentos
do {
k = k + 1; q = false;
u = x + a[ k ] ; v = y + b[ k] ;
/ Teste para vericar se os limites do tabuleiro
sero respeitados. /
i f ( (u >= 0) && (u <= 7) && (v >= 0) && (v <= 7))
i f ( t [u] [ v] == 0) {
t [u] [ v] = i ;
i f ( i < n n) { / / tabuleiro no est cheio
q = tenta ( i +1, u, v) ; / / tenta novo movimento
i f ( ! q) t [u] [ v] = 0; / / no sucedido apaga reg.
anterior
}
else q = true;
}
} while ( ! q && (k ! = 7) ) ; / / no h casas a visitar a par-
tir de x,y
return q;
}
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.3 21
Implementao do Passeio do Cavalo
public void imprimePasseio ( ) {
for ( int i = 0; i < n; i ++) {
for ( int j = 0; j < n; j ++)
System. out . pri nt ( " \ t " +this. t [ i ] [ j ] ) ;
System. out . pri nt l n ( ) ;
}
}
public static void main ( String [ ] args) {
PasseioCavalo passeioCavalo = new PasseioCavalo ( 8) ;
boolean q = passeioCavalo. tenta (2 , 0 , 0);
i f (q) passeioCavalo. imprimePasseio( ) ;
else System. out . pri nt l n ( "Sem solucao" ) ;
}
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.4 22
Diviso e Conquista
Consiste em dividir o problema em partes
menores, encontrar solues para as partes,
e combin-las em uma soluo global.
Exemplo: encontrar o maior e o menor
elemento de um vetor de inteiros, v[0..n 1],
n 1,. Algoritmo na prxima pgina.
Cada chamada de maxMin4 atribui
maxMin[0] e maxMin[1] o maior e o menor
elemento em v[linf ], v[linf + 1], . . . , v[lsup],
respectivamente.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.4 23
Diviso e Conquista
package cap2;
public class MaxMin4 {
public static int [ ] maxMin4( int v[ ] , int l i nf , int lsup) {
int maxMin[ ] = new int [ 2] ;
i f ( lsup l i nf <= 1) {
i f ( v[ l i nf ] < v[ lsup ] ) {
maxMin[ 0] = v[ lsup ] ; maxMin[ 1] = v[ l i nf ] ;
}
else {
maxMin[ 0] = v[ l i nf ] ; maxMin[ 1] = v[ lsup] ;
}
}
else {
int meio = ( l i nf + lsup) / 2;
maxMin = maxMin4 ( v, l i nf , meio) ;
int max1 = maxMin[ 0] , min1 = maxMin[ 1] ;
maxMin = maxMin4 ( v, meio + 1 , lsup) ;
int max2 = maxMin[ 0] , min2 = maxMin[ 1] ;
i f (max1 > max2) maxMin[ 0] = max1;
else maxMin[ 0] = max2;
i f (min1 < min2) maxMin[ 1] = min1;
else maxMin[ 1] = min2;
}
return maxMin;
}
}
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.4 24
Diviso e Conquista - Anlise do
Exemplo
Seja T(n) uma funo de complexidade tal
que T(n) o nmero de comparaes entre
os elementos de v, se v contiver n elementos.
T(n) = 1, para n 2,
T(n) = T(n/2|) + T(n/2|) + 2, para n > 2.
Quando n = 2
i
para algum inteiro positivo i:
T(n) = 2T(n/2) + 2
2T(n/2) = 4T(n/4) + 2 2
4T(n/4) = 8T(n/8) + 2 2 2
.
.
.
.
.
.
2
i2
T(n/2
i2
) = 2
i1
T(n/2
i1
) + 2
i1
Adicionando lado a lado, obtemos:
T(n) = 2
i1
T(n/2
i1
) +

i1
k=1
2
k
=
= 2
i1
T(2) + 2
i
2 = 2
i1
+ 2
i
2 =
3n
2
2.
Logo, T(n) = 3n/2 2 para o melhor caso, o
pior caso e o caso mdio.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.4 25
Diviso e Conquista - Anlise do
Exemplo
Conforme o Teorema da pgina 10 do livro, o
algoritmo anterior timo.
Entretanto, ele pode ser pior do que os
apresentados no Captulo 1, pois, a cada
chamada do mtodo salva os valores de linf ,
lsup, maxMin[0] e maxMin[1], alm do
endereo de retorno dessa chamada.
Alm disso, uma comparao adicional
necessria a cada chamada recursiva para
vericar se lsup linf 1.
n deve ser menor do que a metade do maior
inteiro que pode ser representado pelo
compilador, para no provocar overow na
operao linf + lsup.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.4 26
Diviso e Conquista - Teorema Mestre
Teorema Mestre: Sejam a 1 e b > 1
constantes, f(n) uma funo
assintoticamente positiva e T(n) uma medida
de complexidade denida sobre os inteiros. A
soluo da equao de recorrncia:
T(n) = aT(n/b) + f(n),
para b uma potncia de n :
1. T(n) = (n
log
b
a
), se f(n) = O(n
log
b
a
)
para alguma constante > 0,
2. T(n) = (n
log
b
a
log n), se f(n) = (n
log
b
a
),
3. T(n) = (f(n)), se f(n) = (n
log
b
a+
) para
alguma constante > 0, e se
af(n/b) cf(n) para alguma constante
c < 1 e todo n a partir de um valor
sucientemente grande.
O problema dividido em a subproblemas de
tamanho n/b cada um sendo resolvidos
recursivamente em tempo T(n/b) cada.
A funo f(n) descreve o custo de dividir o
problema em subproblemas e de combinar os
resultados de cada subproblema.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.4 27
Diviso e Conquista - Teorema Mestre
A prova desse teorema no precisa ser
entendida para ele ser aplicado.
Em cada um dos trs casos a funo f(n)
comparada com a funo n
log
b
a
e a soluo
de T(n) determinada pela maior dessas
duas funes.
No caso 1, f(n) tem de ser
polinomialmente menor do que n
log
b
a
.
No caso 2, se as duas funes so iguais,
ento
T(n) = (n
log
b
a
log n) = (f(n) log n).
No caso 3, f(n) tem de ser
polinomialmente maior do que n
log
b
a
e,
alm disso, satisfazer a condio de que
af(n/b) cf(n).
Ele no pode ser aplicado nas aplicaes que
cam entre os casos 1 e 2 (quando f(n)
menor do que n
log
b
a
, mas no
polinomialmente menor), entre os casos 2 e 3
(quando f(n) maior do que n
log
b
a
, mas no
polinomialmente maior) ou quando a
condio af(n/b) cf(n) no satisfeita.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.4 28
Diviso e Conquista - Exemplo do Uso
do Teorema Mestre
Considere a equao de recorrncia:
T(n) = 4T(n/2) + n,
onde a = 4, b = 2, f(n) = n e
n
log
b
a
= n
log
2
4
= (n
2
).
O caso 1 se aplica porque
f(n) = O(n
log
b
a
) = O(n), onde = 1, e a
soluo T(n) = (n
2
).
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.5 29
Balanceamento
No projeto de algoritmos, importante
procurar sempre manter o balanceamento
na subdiviso de um problema em partes
menores.
Diviso e conquista no a nica tcnica em
que balanceamento til.
Vamos considerar um exemplo de ordenao
Seleciona o menor elemento do conjunto
v[0..n 1] e ento troca este elemento com o
primeiro elemento v[0].
Repete o processo com os n 1 elementos,
resultando no segundo maior elemento, o
qual trocado com o segundo elemento v[1].
Repetindo para n 2, n 3, . . ., 2 ordena a
seqncia.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.5 30
Balanceamento - Anlise do Exemplo
O algoritmo leva equao de recorrncia:
T(n) = T(n 1) + n 1, T(1) = 0, para o
nmero de comparaes entre elementos.
Substituindo:
T(n) = T(n 1) + n 1
T(n 1) = T(n 2) + n 2
.
.
.
.
.
.
T(2) = T(1) + 1
Adicionando lado a lado, obtemos:
T(n) = T(1) + 1 + 2 + + n 1 =
n(n1)
2

Logo, o algorimo O(n
2
).
Embora o algoritmo possa ser visto como
uma aplicao recursiva de diviso e
conquista, ele no eciente para valores
grandes de n.
Para obter ecincia assinttica necessrio
balanceamento: dividir em dois
subproblemas de tamanhos
aproximadamente iguais, ao invs de um de
tamanho 1 e o outro de tamanho n 1.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.5 31
Exemplo de Balanceamento -
Mergesort
Intercalao: unir dois arquivos ordenados
gerando um terceiro ordenado (merge).
Colocar no terceiro arquivo o menor elemento
entre os menores dos dois arquivos iniciais,
desconsiderando este mesmo elemento nos
passos posteriores.
Este processo deve ser repetido at que
todos os elementos dos arquivos de entrada
sejam escolhidos.
Algoritmo de ordenao (Mergesort):
dividir recursivamente o vetor a ser
ordenado em dois, at obter n vetores de 1
nico elemento.
Aplicar a intercalao tendo como entrada
2 vetores de um elemento, formando um
vetor ordenado de dois elementos.
Repetir este processo formando vetores
ordenados cada vez maiores at que todo
o vetor esteja ordenado.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.5 32
Exemplo de Balanceamento -
Implementao do Mergesort
package cap2;
public class Ordenacao {
public static void mergeSort ( int v[ ] , int i , int j ) {
i f ( i < j ) {
int m = ( i + j ) / 2;
mergeSort ( v, i , m) ; mergeSort ( v, m + 1 , j ) ;
merge ( v, i , m, j ) ; / / Intercala v[i..m] e v[m+1..j] em
v[i..j]
}
}
}
Considere n como sendo uma potncia de 2.
merge(v, i, m, j), recebe duas seqncias
ordenadas v[i..m] e v[m + 1..j] e produz uma
outra seqncia ordenada dos elementos de
v[i..m] e v[m + 1..j].
Como v[i..m] e v[m + 1..j] esto ordenados,
merge requer no mximo n 1 comparaes.
merge seleciona repetidamente o menor
dentre os menores elementos restantes em
v[i..m] e v[m + 1..j]. Caso empate, retira de
qualquer uma delas.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.5 33
Anlise do Mergesort
Na contagem de comparaes, o
comportamento do Mergesort pode ser
representado por:
T(n) = 2T(n/2) + n 1, T(1) = 0
No caso da equao acima temos:
T(n) = 2T(n/2) + n 1
2T(n/2) = 2
2
T(n/2
2
) + 2
n
2
2 1
.
.
.
.
.
.
2
i1
T(n/2
i1
) = 2
i
T(n/2
i
) + 2
i1
n
2
i1
2
i1
Adicionando lado a lado:
T(n) = 2
i
T(n/2
i
) +
i1

k=0
n
i1

k=0
2
k
= in
2
i1+1
1
2 1
= nlog n n + 1.
Logo, o algoritmo O(nlog n).
Para valores grandes de n, o balanceamento
levou a um resultado muito superior, samos
de O(n
2
) para O(nlog n).
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.6 34
Programao Dinmica
Quando a soma dos tamanhos dos
subproblemas O(n) ento provvel que o
algoritmo recursivo tenha complexidade
polinomial.
Quando a diviso de um problema de
tamanho n resulta em n subproblemas de
tamanho n 1 ento provvel que o
algoritmo recursivo tenha complexidade
exponencial.
Nesse caso, a tcnica de programao
dinmica pode levar a um algoritmo mais
eciente.
A programao dinmica calcula a soluo
para todos os subproblemas, partindo dos
subproblemas menores para os maiores,
armazenando os resultados em uma tabela.
A vantagem que uma vez que um
subproblema resolvido, a resposta
armazenada em uma tabela e nunca mais
recalculado.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.6 35
Programao Dinmica - Exemplo
Produto de n matrizes
M = M
1
M
2
M
n
, onde cada M
i

uma matriz com d
i1
linhas e d
i
colunas.
A ordem da multiplicao pode ter um efeito
enorme no nmero total de operaes de
adio e multiplicao necessrias para obter
M.
Considere o produto de uma matriz p q por
outra matriz q r cujo algoritmo requer
O(pqr) operaes.
Considere o produto M =
M
1
[10, 20] M
2
[20, 50] M
3
[50, 1] M
4
[1, 100],
onde as dimenses de cada matriz est
mostrada entre colchetes.
A avaliao de M na ordem
M = M
1
(M
2
(M
3
M
4
)) requer 125.000
operaes, enquanto na ordem
M = (M
1
(M
2
M
3
)) M
4
requer apenas
2.200.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.6 36
Programao Dinmica - Exemplo
Tentar todas as ordens possveis para
minimizar o nmero de operaes f(n)
exponencial em n, onde f(n) 2
n2
.
Usando programao dinmica possvel
obter um algoritmo O(n
3
).
Seja m
ij
menor custo para computar
M
i
M
i+1
M
j
, para 1 i j n.
Neste caso,
m
ij
=

0, se i = j,
Min
ik<j
(m
ik
+ m
k+1,j
+ d
i1
d
k
d
j
), se j > i.
m
ik
representa o custo mnimo para calcular
M

= M
i
M
i+1
M
k
m
k+1,j
representa o custo mnimo para
calcular M

= M
k+1
M
k+2
M
j
.
d
i1
d
k
d
j
representa o custo de multiplicar
M

[d
i1
, d
k
] por M

[d
k
, d
j
].
m
ij
, j > i representa o custo mnimo de
todos os valores possveis de k entre i e
j 1, da soma dos trs termos.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.6 37
Programao Dinmica - Exemplo
O enfoque programao dinmica calcula os
valores de m
ij
na ordem crescente das
diferenas nos subscritos.
O calculo inicia com m
ii
para todo i, depois
m
i,i+1
para todo i, depois m
i,i+2
, e assim
sucessivamente.
Desta forma, os valores m
ik
e m
k+1,j
estaro
disponveis no momento de calcular m
ij
.
Isto acontece porque j i tem que ser
estritamente maior do que ambos os valores
de k i e j (k + 1) se k estiver no intervalo
i k < j.
Programa para computar a ordem de
multiplicao de n matrizes,
M
1
M
2
M
n
, de forma a obter o
menor nmero possvel de operaes.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.6 38
Programao Dinmica -
Implementao
package cap2;
import java. i o . ;
public class AvaliaMultMatrizes {
public static void main( String [ ] args)throws IOException {
int n, maxn = Integer . parseInt ( args[ 0] ) ;
int d[ ] = new int [maxn + 1] ;
int m[ ] [ ] = new int [maxn] [maxn] ;
BufferedReader i n = new BufferedReader (
new InputStreamReader (System. i n ) ) ;
System. out . pri nt ( "Numero de matrizes n: " ) ;
n = Integer . parseInt ( i n . readLine( ) ) ;
System. out . pri nt l n ( "Dimensoes das matrizes: " ) ;
for ( int i = 0; i <= n; i ++) {
System. out . pri nt ( " d[ "+i +" ] = " ) ;
d[ i ] = Integer . parseInt ( i n . readLine( ) ) ;
}
/ / Continua na prxima transparncia...
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.6 39
Programao Dinmica - Continuao
da Implementao
for ( int i = 0; i < n; i ++) m[ i ] [ i ] = 0;
for ( int h = 1; h < n; h++) {
for ( int i = 1; i <= n h; i ++) {
int j = i + h;
m[ i 1][ j 1] = Integer .MAX_VALUE;
for ( int k = i ; k < j ; k++) {
int temp = m[ i 1][k1] +m[ k] [ j 1] +
+ d[ i 1] d[ k] d[ j ] ;
i f (temp < m[ i 1][ j 1]) m[ i 1][ j 1] = temp;
}
System. out . pri nt ( " m[ " +i +" ] [ "+j +" ]= " + m[ i 1][ j 1]);
}
System. out . pri nt l n ( ) ;
}
}
}
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.6 40
Programao Dinmica -
Implementao
A execuo do programa obtm o custo
mnimo para multiplicar as n matrizes,
assumindo que so necessrias pqr
operaes para multiplicar uma matriz p q
por outra matriz q r.
A execuo do programa para as quatro
matrizes onde d
0
, d
1
, d
2
, d
3
, d
4
so 10, 20, 50,
1, 100, resulta:
m
11
= 0 m
22
= 0 m
33
= 0 m
44
= 0
m
12
= 10.000 m
23
= 1.000 m
34
= 5.000
m
13
= 1.200 m
24
= 3.000
m
14
= 2.200
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.6 41
Programao Dinmica - Princpio da
Otimalidade
A ordem de multiplicao pode ser obtida
registrando o valor de k para cada entrada da
tabela que resultou no mnimo.
Essa soluo eciente est baseada no
princpio da otimalidade:
em uma seqncia tima de escolhas ou
de decises cada subseqncia deve
tambm ser tima.
Cada subseqncia representa o custo
mnimo, assim como m
ij
, j > i.
Assim, todos os valores da tabela
representam escolhas timas.
O princpio da otimalidade no pode ser
aplicado indiscriminadamente.
Quando o princpio no se aplica provvel
que no se possa resolver o problema com
sucesso por meio de programao dinmica.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.6 42
Aplicao do Princpio da Otimalidade
Por exemplo, quando o problema utiliza
recursos limitados, quando o total de recursos
usados nas subinstncias maior do que os
recursos disponveis.
Se o caminho mais curto entre Belo Horizonte
e Curitiba passa por Campinas:
o caminho entre Belo Horizonte e
Campinas tambm o mais curto possvel
assim como o caminho entre Campinas e
Curitiba.
Logo, o princpio da otimalidade se aplica.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.6 43
No Aplicao do Princpio da
Otimalidade
No problema de encontrar o caminho mais
longo entre duas cidades:
Um caminho simples nunca visita uma
mesma cidade duas vezes.
Se o caminho mais longo entre Belo
Horizonte e Curitiba passa por Campinas,
isso no signica que o caminho possa ser
obtido tomando o caminho simples mais
longo entre Belo Horizonte e Campinas e
depois o caminho simples mais longo
entre Campinas e Curitiba.
Quando os dois caminhos simples so
ajuntados pouco provvel que o caminho
resultante tambm seja simples.
Logo, o princpio da otimalidade no se
aplica.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.7 44
Algoritmos Gulosos
Resolve problemas de otimizao.
Exemplo: algoritmo para encontrar o caminho
mais curto entre dois vrtices de um grafo.
Escolhe a aresta que parece mais
promissora em qualquer instante;
Independente do que possa acontecer
mais tarde, nunca reconsidera a deciso.
No necessita avaliar alternativas, ou usar
procedimentos sosticados para desfazer
decises tomadas previamente.
Problema geral: dado um conjunto C,
determine um subconjunto S C tal que:
S satisfaz uma dada propriedade P, e
S mnimo (ou mximo) em relao a
algum critrio .
O algoritmo guloso para resolver o problema
geral consiste em um processo iterativo em
que S construdo adicionando-se ao mesmo
elementos de C um a um.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.7 45
Caractersticas dos Algoritmos
Gulosos
Para construir a soluo tima existe um
conjunto ou lista de candidatos.
So acumulados um conjunto de candidatos
considerados e escolhidos, e o outro de
candidatos considerados e rejeitados.
Existe funo que verica se um conjunto
particular de candidatos produz uma soluo
(sem considerar otimalidade no momento).
Outra funo verica se um conjunto de
candidatos vivel (tambm sem preocupar
com a otimalidade).
Uma funo de seleo indica a qualquer
momento quais dos candidatos restantes o
mais promissor.
Uma funo objetivo fornece o valor da
soluo encontrada, como o comprimento do
caminho construdo (no aparece de forma
explicita no algoritmo guloso).
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.7 46
Pseudo Cdigo de Algoritmo Guloso
Conjunto guloso ( Conjunto C) { / C: conjunto de candidatos /
S = ; / S contm conjunto soluo /
while ( (C ,= ) && not soluo(S) ) {
x = seleciona (C) ;
C = C x;
i f ( vivel (S + x) ) S = S + x;
}
i f ( soluo (S) )
return S else return ( "No existe soluo" ) ;
}
Inicialmente, o conjunto S de candidatos
escolhidos est vazio.
A cada passo, o melhor candidato restante
ainda no tentado considerado. O critrio
de escolha ditado pela funo de seleo.
Se o conjunto aumentado de candidatos se
torna invivel, o candidato rejeitado. Seno,
o candidato adicionado ao conjunto S de
candidatos escolhidos.
A cada aumento de S vericamos se S
constitui uma soluo tima.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.7 47
Caractersticas da Implementao de
Algoritmos Gulosos
Quando funciona corretamente, a primeira
soluo encontrada sempre tima.
A funo de seleo geralmente
relacionada com a funo objetivo.
Se o objetivo :
maximizar provavelmente escolher o
candidato restante que proporcione o
maior ganho individual.
minimizar ento ser escolhido o
candidato restante de menor custo.
O algoritmo nunca muda de idia:
Uma vez que um candidato escolhido e
adicionado soluo ele l permanece
para sempre.
Uma vez que um candidato excludo do
conjunto soluo, ele nunca mais
reconsiderado.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.8 48
Algoritmos Aproximados
Problemas que somente possuem algoritmos
exponenciais para resolv-los so
considerados difceis.
Problemas considerados intratveis ou
difceis so muito comuns.
Exemplo: problema do caixeiro viajante
cuja complexidade de tempo O(n!).
Diante de um problema difcil comum
remover a exigncia de que o algoritmo tenha
sempre que obter a soluo tima.
Neste caso procuramos por algoritmos
ecientes que no garantem obter a soluo
tima, mas uma que seja a mais prxima
possvel da soluo tima.
Projeto de Algoritmos Cap.2 Paradigmas de Projeto de Algoritmos Seo 2.8 49
Tipos de Algoritmos Aproximados
Heurstica: um algoritmo que pode produzir
um bom resultado, ou at mesmo obter a
soluo tima, mas pode tambm no
produzir soluo alguma ou uma soluo que
est distante da soluo tima.
Algoritmo aproximado: um algoritmo que
gera solues aproximadas dentro de um
limite para a razo entre a soluo tima e a
produzida pelo algoritmo aproximado
(comportamento monitorado sob o ponto de
vista da qualidade dos resultados).

Das könnte Ihnen auch gefallen