1
Divisão e Conquista Divisão e Conquista
4 6.4=24
Fatorial(p);
Se (p = 0) Então
Retornar 1 3 2.3=6
Senão
Retornar p.Fatorial(p-1); A B C
Fim; 2 1.2=2
Quer-se levar os n pratos da vareta A para a
1 1.1=1 vareta C, um a um, usando B como auxílio, sem
nunca colocar um prato sobre um prato menor.
0 1
1
3 2 1 3 2
A B C A B C
Mover 1 para C
Mover 1 para B
Mover 2 para B
1
2 3 1 2 3
A B C A B C
2
Divisão e Conquista Divisão e Conquista
Hanoi (n, V1, V2, V3); Hanoi (n, V1, V2, V3);
(1) Se (n > 0) Então (1) Se (n > 0) Então
(2) Hanoi (n-1, V1, V3, V2) (2) Hanoi (n-1, V1, V3, V2)
(3) Mover topo de V1 para V3 (3) Mover topo de V1 para V3
(4) Hanoi (n-1, V2, V1, V3); (4) Hanoi (n-1, V2, V1, V3);
Fim; A B C Fim; A B C
3 A B C 1/2 3 A B C 1/2
2 A C B 1/2 2 A C B 1/2
1 A B C 1/2 1 A B C 3/4
0 A C B 1 0 A C B 1 0 B A C 1
3
Divisão e Conquista Divisão e Conquista
Hanoi (n, V1, V2, V3); Hanoi (n, V1, V2, V3);
(1) Se (n > 0) Então (1) Se (n > 0) Então
(2) Hanoi (n-1, V1, V3, V2) (2) Hanoi (n-1, V1, V3, V2)
(3) Mover topo de V1 para V3 (3) Mover topo de V1 para V3
(4) Hanoi (n-1, V2, V1, V3); (4) Hanoi (n-1, V2, V1, V3);
Fim; A B C Fim; A B C
3 A B C 1/2 3 A B C 1/2
2 A C B 3/4 2 A C B 3/4
1 A B C 1 C A B 1/2 1 A B C 1 C A B 3/4
0 A C B 1 0 B A C 1 0 C B A 1 0 A C B 1 0 B A C 1 0 C B A 1 0 A C B 1
2 A C B 3/4 2 B A C 1 Exercício:
1 A B C 1 C A B 3/4
Provar, por indução, que a fórmula acima é
verdadeira.
0 A C B 1 0 B A C 1 0 C B A 1 0 A C B 1
Solução da recorrência:
Então o algoritmo é ineficiente?
T(n) = 2n - 1
Prova: Resposta:
a) Verdadeiro para n = 0 e n = 1 Não. Prova-se que qualquer solução exige um nú-
b) Se verdadeiro para n-1, mero exponencial de passos. Então o problema é
T(n) = 2*(2n-1 -1)+ 1 = 2n -1 que é “ruim”, não o algoritmo.
então também é verdadeiro para n.
4
Divisão e Conquista Divisão e Conquista
Quicksort: Quicksort:
Este é um importante método de ordenação, Quicksort (e, d);
inventado por Hoare, em 1962. Se (d > e) Então
A idéia recursiva básica é a seguinte: Particao (e, d, i, j);
a) Fazer uma partição no vetor, através de trocas, basea- Quicksort (e, j);
da em um pivô p, tal que os elementos da partição es- Quicksort (i, d);
querda sejam ≤ p, e os da direita, ≥ p. Fim;
b) Então basta ordenar, recursivamente, as duas partições
geradas.
c) O problema infantil é a partição ter tamanho igual ou in-
A idéia é fazer partição no vetor em 2 ou 3 partes. O
ferior a 1, quando nada deve ser feito.
algoritmo de Partição a ser apresentado, usa como pivô o
V elemento do meio do vetor e, algumas vezes, particiona o
vetor em 3 partes, onde a parte do meio tem tamanho 1 e
≤ p ≥ p é igual ao pivô.
1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11
P R I M O G E N I T O P R I M O G E N I T O
E R I M O G P N I T O
E G I M O R P N I T O
1 2 3 4 5 6 7 8 9 10 11
E R I M O G P N I T O
5
Divisão e Conquista Divisão e Conquista
1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11
E R I M O G P N I T O E G I M O R P N I T O
≤ G ≥ G i = 3 j = 2
1 2 1 2
E G E G
=E ≥ E i = 2 j = 0 (!!)
Quicksort: exemplo
Quicksort
1 2 3 4 5 6 7
P R I M A T A
A A I M R T P
A A I R T P
Exercício: A R P T
Executar o algoritmo de Partição para o A I R P
MIXSTRING (10 letras) I P R
P
R
T
6
Divisão e Conquista Divisão e Conquista
AAI RTP
1 3 2 1 AAI 57 7 6 RPT
Exercício:
AI RP
5 6 6 5 PR 77- - Mostrar a execução do Quicksort para o
1 1 - - A 2 3 3 1 AI T
MIXSTRING (10 letras). Mostrar a árvore de
recursão.
2 1 - - 33 - I 5 5 - - P 6 6 - R
Máximo e Mínimo.
Análise da Ordenação pelo Quicksort:
Problema: Dado um conjunto de números
Complexidade:
S= {s1, s2,... sn}, determinar simultâneamente o
Pior caso: O(n2)
menor e o maior elementos do conjunto.
Melhor caso = caso médio: O(n log n)
Estabilidade (manutenção da ordem relativa de Solução ingênua:
chaves iguais): Encontrar o mínimo e o máximo, separadamente,
Algoritmo não estável utilizando 2*(n-1) comparações.
7
Divisão e Conquista Divisão e Conquista
Pergunta:
É possível encontrar os números procurados
fazendo menos que 2*(n-1) comparações?
Cálculo de Combinações
Cálculo de Combinações
Versão 1. Define-se a recorrência:
Comb(n, p) = n, se p = 1
Problema: Às vezes tem-se problemas numéricos no Comb(n, p) = Comb(n, p-1)*(n-p+1)/p.
cálculo de combinações, se usar-se a fórmula.
Ex: Calculando-se Comb(50, 3), haveria um estouro Exemplo: Comb(50, 3).
numérico no cálculo de 50!
50 3 1225*48/3 = 19600
A versão recursiva pode evitar o problema. 50 2 50*49/2 = 1225
50 1 50
Versão 1. Define-se a recorrência:
Comb(n, p) = n, se p = 1
Comb(n, p) = Comb(n, p-1)*(n-p+1)/p , se p > 1.
8
Divisão e Conquista Divisão e Conquista
Torneio.
Cálculo de Combinações
Problema: quer-se montar uma tabela de torneio, com n
competidores, onde todos os competidores jogam entre sí,
em rodadas. Se n for par, deve haver n-1 rodadas e, em
Exercício: cada uma delas, todos os times jogam; se n for ímpar deve
Escrever outra versão recursiva para o haver n rodadas, ficando um time “bye” em cada uma.
cálculo de combinações (Comb(n, p)), diminuindo o
Exemplos para n = 6 e n = 5.
problema pelo n.
r0 r1 r2 r3 r4 r5 r0 r1 r2 r3 r4 r5
1 2 3 4 5 6 1 2 3 4 5 -
2 1 5 3 6 4 2 1 5 3 - 4
3 6 1 2 4 5 3 - 1 2 4 5
4 5 6 1 3 2 4 5 - 1 3 2
5 4 2 6 1 3 5 4 2 - 1 3
6 3 4 5 2 1
Propriedades da tabela de Torneio com n par. Propriedades da tabela de Torneio com n ímpar.
Considerando a coluna r0 como numeração dos times 1 a n: Considera-se mais um time artificial e substituem-
a) cada linha é uma permutação de 1 a n. se os “bye” por esse time. Passa-se a ter a
b) cada coluna é uma permutação de 1 a n. situação par.
c) T[i, j] = p ⇒ T[p, j] = i, pelo emparelhamento.
2 1 5 3 6 4 2 1 5 3 - 4 2 1 5 3 6 4 2 1 5 3 6
- 4
3 6 1 2 4 5 3 - 1 2 4 5 3 6 1 2 4 5 3 6
- 1 2 4 5
4 5 6 1 3 2 4 5 - 1 3 2 4 5 6 1 3 2 4 5 6
- 1 3 2
5 4 2 6 1 3 5 4 2 - 1 3 5 4 2 6 1 3 5 4 2 -6 1 3
6 3 4 5 2 1 6 3 4 5 2 1 6 3 4 5 2 1
9
Divisão e Conquista Divisão e Conquista
Resolve-se o problema para n = 4 e depois elimi- Resolve-se o problema para n = 8 e depois elimi-
na-se a linha 4 e transforma o 4 em “bye” na-se a linha 8 e transforma o 8 em “bye”
r1 r2 r3 r4 r5 r6 r7
r1 r2 r3 1 2 3 4 5 6 7 -
8
1 2 3 -4 2 1 4 3 6 5 -
8 7
2 1 -4 3 3 4 1 2 7 -
8 5 6
3 -4 1 2 4 3 2 1 -
8 7 6 5
4 3 2 1 5 6 7 -
8 1 2 3 4
6 5 -
8 7 2 1 4 3
7 -
8 5 6 3 4 1 2
8 7 6 5 4 3 2 1
10
Divisão e Conquista Divisão e Conquista
r1 r2 r3 r4 r5
r1 r2 r3 r4 r5 r6
1 2 3 4 5 6
1 2 3 - 4 5 6
2 1 5 3 6 4
2 1 - 3 5 6 4
3 6 1 2 4 5
3 - 1 2 6 4 5
4 5 6 1 3 2
4 5 6 - 1 3 2
5 4 2 6 1 3
5 4 - 6 2 1 3
6 3 4 5 2 1
6 - 4 5 3 2 1
11
Divisão e Conquista Divisão e Conquista
BALANCEAMENTO BALANCEAMENTO
Critério recomendado para gerar recursões
eficientes: Mergesort:
Dividir um problema de tamanho n em k subproble- Sort(e, d); Complexidade: O(n log n)
Se (d > e) Então
mas de tamanho aproximado n/k. m ← (e+d)/2; Sort(e, m); Sort(m+1, d);
Merge (e, m, d);
Exemplo: ordenação de um vetor de tamanho n Fim;
Bubblesort:
Mergesort: divide o problema em 2 sub- Sort(d);
problemas de tamanho n/2. Se (d > 1) Então
O(n2)
Para j de 2 a d: Complexidade:
Bublesort: divide o problema em 2 sub- Se (V[j-1] > V[j]) Então
Troca(j-1, j);
problemas, 1 de tamanho 1 e o outro de Fp;
tamanho n-1. Sort(d-1);
Fim;
Complexidade do FIB recursivo: O(Fib(n)), que é > O(2n); No Brasil, m = 6 e V = [1, 5, 10, 25, 50,100].
12
Divisão e Conquista Divisão e Conquista
MEMORIZAÇÃO - MOEDAS
MEMORIZAÇÃO - MOEDAS - n = 120
T(p, n) = 0, se n < 0
T(p, 0) = 1;
6, 120 T(p, n) = T(p, n - V[p]) + T(p-1, n), se n > 0
6, 20 5, 120
6, -80 5, 20 5, 70 4, 120 Moedas (p, q);
Se (q < 0) Então c ← 0
5, 20 Senão Se (q = 0) Então c ← 1
Senão Se (T[p, q] = -1) Então
Se (p = 1) Então c ← Moedas(1,q-V[1])
Senão c ← Moedas(p,q-V[p])+Moedas(p-1,q);
Árvore de recursão explosiva!!! T[p, q] ← c;
Senão c ← T[p, q];
Retornar c;
Fim;
13
Divisão e Conquista Divisão e Conquista
Divisão e Conquista
FIM
14