Algoritmos I

Transcription

Algoritmos I
Algoritmos I
Roberto de Beauclair Seixas
Abu Abd-Allah ibn
Musa al'Khwarizmi
z Seu trabalho mais importante escrito
em 830 nos dá a palavra álgebra.
Æ classifica a solução de equações quadráticas
e dá métodos geométricos para completar o quadrado.
z Al'Khwarizmi também escreveu números Hindu-árabe.
Æ Este texto de árabe está perdido mas uma tradução latina
“Algoritmi de numero Indorum”, em inglês “Algoritmi de
numero Indorum in English Al-Khwarizmi on the Hindu Art of
Reckoning”, deu origem a palavra algoritmo que deriva do
nome dele no título.
z O primeiro uso do zero com lugar posicional na anotação
básica provavelmente foi devida a al'Khwarizmi.
2
Algoritmo
z Dicionário Webster:
“Any special method of solving a certain kind of problem.”
3
Algoritmo
z Dicionário Webster:
“Any special method of solving a certain kind of problem.”
( parece coisa do McGuiver! )
4
Algoritmo
z Fundamentals of Computer Algorithms;
E.Horowitz, S.Sahni; 1978:
“A precise method useable by a computer for the
solution of a problem.”
5
Algoritmo
z Fundamentals of Computer Algorithms;
E.Horowitz, S.Sahni; 1978:
“A precise method useable by a computer for the
solution of a problem.”
6
Pi com 24 casas
How I want a drink, alcoholic of
course, after the heavy lectures
involving quantum mechanics. All of
the geometry, Herr Planck, is fairly
hard ...
3.14159265358979323846264...
7
Fibonacci
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377 ...
z Isto se parece um padrão simples, contudo determina a forma
da concha de um molusco, o bico de um papagaio ou o
brotando de folhas do talo de qualquer planta, foi revelado por
Leonardo Pisano (depois Fibonacci) a quase 800 anos atrás.
Pisano, o primeiro grande matemático de Europa medieval, descobriu estes
números mágicos analisando a natalidade de coelhos em 1202.
z A relação entre os números de Fibonacci se aproxima de 1,6180. Esta relação
mágica os gregos chamava de “proporção divina” e seus templos, como por
exemplo o Parthenon em Atenas, possuíam comprimento = 1,6180 × largura.
z Antes dos gregos, os egípcios construíram suas pirâmides seguindo as mesmas
regras: base = 1,6180 × altura.
z Nos organismos vivos, as garras de um leão, os chifres de um carneiro, os
dentes de elefantes, a concha de um caracol e etc., seguem a regra da “espiral
dourada” (derivada do “retângulo dourado” onde
largura = 1,6180 × altura)
8
Algoritmos I - Ementa
z
Motivação 9
Æ Presente, Passado e Futuro(?)
z
z
z
z
z
Modelos de Computação
Fundamentos Matemáticos *
Ordenação
Busca
Grafos
9
Presente
Os próximos 7 slides foram
adaptados de duas apresentações
da TechMark
Engenharia de Software:
What the Hell is this?
z Engenheiros Civis fazem Plantas antes de
construírem prédios;
z Engenheiros Eletrônicos fazem Esquemas antes
de montarem aparelhos;
z Engenheiros Mecânicos fazem Desenhos antes de
produzirem máquinas;
z Engenheiros de Software são superdotados pela
Mãe Natureza, e não precisam de nada disso!
Æ “Se prédios fossem construídos da mesma forma que fazemos
sistemas, o primeiro pica-pau que aparecesse no planeta destruiria
a humanidade” - Weinberg
11
A Engenharia de Software é
uma área MUITO NOVA!
z
z
z
z
O ser humano faz casas e abrigos há
milhões de anos;
O ser humano lida com eletricidade há
milhares de anos;
O ser humano produz máquinas e
ferramentas há outros milhares de anos;
O ser humano faz software há 40 anos.
Æ Estamos nos primórdios da computação...
12
Conclusão
“A formulação de um problema é
freqüentemente mais essencial do que sua
solução, a qual pode ser meramente uma
questão de habilidade matemática ou
experimental.”
(LQVWHLQH,QIHOG
DXWRUHVGH³$(YROXomRGD)tVLFD´
13
“Tamanho” dos Sistemas
Sistemas grandes (>12 meses) são
melhor atendidos por metodologias
completas e rigorosas, com passos
formais, revisões estruturadas,
documentos intermediários formais e
ciclo de vida em cascata. O
desenvolvedor deverá estar
interessado em reuso a longo prazo.
Sistemas menores (<6 meses) são
mais adequados a metodologias
leves, sem muito rigor, com passos
intermediários informais e ciclo de
vida iterativo. Documentação não é a
base do projeto, mas apenas uma
ferramenta de consulta. O
desenvolvedor está interessado em
reuso imediato.
14
Habilidades Técnicas dos
Analistas e Programadores
Constrói-se utilizando-se abordagens
conservadoras, organizando-se bem o
processo de desenvolvimento e
utilizando-se de técnicas
estruturadas, que capitalizam sobre
conhecimentos existentes. Em
compensação, você está mais
próximo da obsolescência.
Se a sua equipe é nova, aberta a
mudanças e propensa a tentar coisas
novas, não hesite. Você tem uma
excelente oportunidade de introduzir
técnicas Orientadas por Objetos em
sua organização.
Seus sistemas terão uma vida mais
longa desta forma.
15
Exigências com
Relação à Tecnologias
Caso os seus clientes tenham perfil
conservador (denota-se através de
sua arquitetura de hardware e rede)
você deve sintonizar-se com a
linguagem deles e utilizar algo que
use a mesma terminologia. Deixe
claro o risco da obsolescência.
Caso seus clientes exigem de você a
“última palavra” em tecnologia, sorte
sua. Mantenha o foco, invista em
tecnologia OO e vá em frente. Mas,
divida e responsabilidade pelo
sucesso (ou fracasso) com o cliente.
16
Ambiente de Desenvolvimento
• COBOL, FORTRAN, “C”, BASIC,
• VB5, Java, PowerBuilder, C++,
Pascal, PL/1, VB3, Natural, e outras
linguagens procedurais: Fique com
métodos estruturados e técnicas de
Entidade/Relacionamento;
• Use DeMarco, Yourdon, Martin,
Constantine, Gane/Sarson, Peter
Chen, etc…;
SmallTalk, CORBA, Forté, Informix
NewEra, Delphi e outras linguagens
que suportam conceitos de classes,
heranças e agregações: Aprenda OO
imediatamente, ou não terá benefício
em utilizá-las;
• Use UML, OMT, Shlaer/Mellor,
Martin/Odell, Coad/Yourdon, etc
17
Passado e Futuro(?)
Alan M. Turing
(1912-1954)
z
Computing Machinery and Intelligence.
Mind, Vol. LIX. 433-460, 1950
Æ Os computadores terão inteligência.
z
Debate: Então, e agora ?
Æ Será uma relação simbiótica ?
(computador como uma ferramenta)
Æ Os computadores terão “consciência”?
19
Teste de Turing
z
1o Teste - Jogo de Imitação:
Æ 3 pessoas: Juiz, homem e mulher;
Æ Toda conversa por e-mail;
Æ Homem finge ser a mulher;
Æ Homem mente;
Æ Mulher tenta ajudar o juiz;
Æ Juiz tem que identificar o homem
em 5 minutos.
20
Teste de Turing
z
2o Teste - Jogo de Substituição:
Æ Troque o homem ou a mulher por um computador;
Æ O juiz é enganado 30% do tempo.
21
O que Turing disse?
“I believe that in about fifty years' time it will be possible, to
program computers, with a storage capacity of about 109 , to
make them play the imitation game so well that an average
interrogator will not have more than 70 per cent chance of
making the right identification after five minutes of
questioning. The original question, “Can machines think?”
I believe to be too meaningless to deserve discussion.
Nevertheless I believe that at the end of the century the use of
words and general educated opinion will have altered so much
that one will be able to speak of machines thinking without
expecting to be contradicted.”
Alan M.Turing, 1950
“Computing Machinery and Intelligence.” Mind, Vol. LIX. 433-460
22
49 anos depois
z Previsão de tecnologia de Turing foi fantástica!
Æ Armazenamento de Gb de memória são comuns.
z Previsão de inteligência foi otimista.
Æ Vários locais da Internet oferecem “chatterbots” do teste.
Æ Ninguém passou (ainda)
` http://www.loebner.net/Prizef/loebner-prize.html
z Mas acredita-se que não demorará
Æ menos de 50 anos, mais de 10 anos.
z Os testes de Turing ainda se apresentam como desafios de
longo prazo.
23
Mas, houve progresso ...
z Computadores solucionaram alguns problemas:
“Mapa de 4 cores”
Æ
K. Appel and W. Haken, “The solution of the four-color-map problem,”
Scientific American, Oct 1977, 108-121
e uma prova “manual” http://www.math.gatech.edu/~thomas/FC/fourcolor.html
(1995)
z Os computadores venceram o campeão mundial de xadrez
Æ
com alguma ajuda dos programadores, mas … venceu!
z Os computadores estão presentes no dia-a-dia
z Ajudam a projetar e idealizar novas coisas
z Estas são relações simbióticas.
z Aprendizado e formação de conhecimento ainda são ilusórios.
24
Armadilha dos números
z Os seres humanos possuem 100 Tb de informação (1012) e podem
processar 100 T ops.
Æ
ROBOT, Hans Moravec, Oxford, 1998, page 58
Æ
Æ
Æ
Æ
90% lixo
90% em comum com os chimpanzés
90% comum entre os indivíduos
Então, realmente só 106 bytes são relevantes (huh?!)
Æ
Æ
Æ
Um excelente algoritmo de compressão ?
Uma melhor linguagem de programação ?
Técnicas de aprendizado ?
z Então, um supercomputador “tem” um poder comparável.
z O Genoma humano tem 109 bits:
z Estamos perdendo algo ...
25
26
Charles Babbage
(1791-1871)
z Os objetivo de Babbage foram
alcançados
Æ mas ainda precisamos de melhores algoritmos e máquinas mais
rápidas.
z O que acontecerá quando:
Æ A capacidade de processamento for infinita ?
Æ A capacidade de armazenamento for infinita ?
z Limites remanescentes:
Æ Conteúdo: A capacidade de informação do Cyberspace
Æ Software: Bugs, >100$ por linha de código (!)
Æ Processamento: > 1,000 $/cpu/ano
27
Mais 3 desafios
z Implícitos nos teste de Turing:
Æ
Æ
Ler e entender tão bem quanto um humano
Escrever e pensar tão bem quanto um humano
–
Traduzir “fala” para “texto”
z Ouvir tão bem quanto uma pessoa (locutor nativo)
z Falar tão bem quanto uma pessoa (interlocutor nativo)
–
Traduzir “texto” para “fala”
z Ver tão bem quanto uma pessoa (reconhecer objetos e comportamentos)
z Ilustrar/Mostrar/Desenhar tão bem como uma pessoa (já feito)
Æ
Æ
mas, Realidade Virtual ainda é um grande desafio
criar cenas 3D “reais” em tempo real
z E ainda: Lembrar o que foi (é) visto e ouvido e rapidamente responder
quando solicitado.
28
Benefícios
z Hoje os computadores podem:
Æ Ler para os cegos (OCR & Texto → Fala)
Æ Ouvir para os surdos (Fala → Texto)
Æ Escrever para os deficientes (Fala → Texto)
z Logo:
Æ Substituir deficiências:
` melhor memória, melhor visão, …
Æ Novas formas de comunicação
` Tradução automática de telefonemas
Æ Revolucionar a interface homem-computador
29
Vannevar Bush
(1890-1974)
z “As We May Think” The Atlantic Monthly, 1945
http://www.theatlantic.com/unbound/flashbks/computer/bushf.htm
z Memex
Æ Todo conhecimento humano
… “a billion books” hyper-linked together ...
Æ Registrando tudo o que se vê
` filmes e fotos
` ... “a machine which types when talked to” ...
Æ Navigate by
` … text search following links associations ...
z Conexões diretas ao sistema nervoso ?
30
Memex Individual
Memex: “Lembrar o que é visto e ouvido e rapidamente
devolver qualquer informação solicitada”
31
Quanto de Informação Existe ?
z Logo, tudo poderá ser gravado e
catalogado.
z A maioria da informação nunca será
vista.
z Fundamentos tecnológicos:
Æ Atenção humana
Æ “Sumarização” automática
Æ Busca automática
http://www.lesk.com/mlesk/ksg97/ksg.html
32
Resumo
z Pense seriamente sobre Algoritmos
z Qual o melhor algoritmo para um problema?
→ “aderência”
z Oito paradigmas para projetar um bom algoritmo:
1. reduzir a um problema conhecido (ex: ordenação);
2. recursão;
3. criar ou expandir uma estrutura de dados;
4. dividir e conquistar;
5. guloso;
6. programação dinâmica;
7. probabilidade;
8. aproximação.
33
Usa Windows ?!?
34
Cuidado com os efeitos colaterais!
35
Modelos de Computação
Problemas & Algoritmos
suponha n=8
Problema: Como computar S ?
Æ entrada: lista de salários S1, S2, … , Sn
Æ saída: despesa total com salários: S = S1+S2+…+Sn
Æ recursos: pessoa alfabetizada, papel e lápis
solução 1:
solução 2:
solução 3:
- estimar o salário típico T
(por exemplo, o 1o da lista)
- calcular S por S = n * T
37
Modelos Computacionais
z Procuram abstrair e simplificar o comportamento
dos computadores.
Æ Máquina de Turing
` Utilizado para estabelecer resultados básicos em
computabilidade e complexidade
computacional.
Æ Árvore de Decisões Algébricas
` Muito usado para obtenção de resultados
teóricos em computação.
38
Problema Algorítmico
z Problema
E ⇒ conjunto das possíveis entradas
S ⇒ conjunto das saídas desejadas
R(E,S) ⇒ relação entre entradas e saídas desejadas
O ⇒ operações válidas
z Solução
A ⇒ algoritmo correto
e
∀e ∈ E
A
s
(e,s) ∈ R(E,S)
39
Solução de Problemas
modelo
modelomatemático
matemático
algoritmo
algoritmoinformal
informal
tipo
tipoabstrato
abstratode
dedados
dados
pseudo
pseudocódigo
código
estrutura
estruturade
dedados
dados
programa
programa
...
código
códigode
demáquina
máquina
40
Algoritmos e Complexidade
z
z
Problema, Instância e Algoritmo.
Dado um problema:
Æ Como encontrar um algoritmo eficiente para
solucioná-lo ?
Æ Uma vez encontrado, como compará-lo a outros
algoritmos que também resolvem o problema ?
Æ Como determinar se o algoritmo está correto ?
Æ Como determinar se o algoritmo é eficiente ?
41
Algoritmo
Conjunto finito de instruções, composta de uma ou
mais operações válidas, com o objetivo de
resolver um problema específico.
z Operações válidas
Æ definidas
5÷0
Æ efetivas
√π
z Término em tempo finito (procedimento computacional)
z Entrada (opcional)
z Saída (uma ou mais)
42
Alguns Exemplos Iniciais
Para qualquer algoritmo, temos que provar que ele sempre
retornará o resultado desejado para todas as instâncias
possíveis do problema.
¼ Correção (Correctness)
¼ Eficiência
43
Critérios de Análise
especificação
z Eficácia
Æ Correção
problema
algoritmo
requisitos
verificação
NÃO
erros
z Eficiência
Æ
Æ
Æ
Æ
Tempo
Espaço
Simplicidade / Clareza
Otimalidade
z Limitações
Æ Computabilidade
Æ Tratabilidade
SIM
solução
código
z Parcialmente Correto
Æ
Æ
entrada válida → saída desejada
pode ser tempo infinito
Æ
Æ
tempo finito
saída desejada
z Totalmente Correto
44
Correção não é óbvio!
¼ Você recebeu a tarefa de programa um braço de robô de
soldagem.
¼ O robô deve soldar (visitar) o primeiro ponto de solda,
depois o segundo, terceiro e assim por diante.
¼ Determine um algoritmo para achar o melhor caminho.
45
Vizinho Mais Próximo
¼ Inicie em algum ponto p0 e então vá para o ponto mais
próximo p1. Repita o processo a partir de p1, etc. até que
todos os pontos sejam visitados.
Escolha e visite um ponto inicial p0
p = p0;
i = 0;
enquanto existirem pontos não visitados
i=i+1
escolha e visite o ponto pi, mais próximo de pi-1
retorne ao ponto inicial
¼ Este algoritmo é simples de entender, simples de entender
e muito eficiente. Está correto ?
46
Vizinho Mais Próximo
¼ Algoritmo não é correto!
¼ Escolher sempre o ponto mais próximo é muito
restritivo, pois pode nos levar a fazer movimentos
desnecessários.
47
Par Mais Próximo
¼ Conectar ao par mais próximo de pontos cuja conexão
não irá causar um ciclo ou bifurcações, até se formar uma
única cadeia de pontos com todos os pontos.
faça n ser o número de pontos do conjunto e d = ∞
para i = 1 até n - 1 faça
para cada par de pontos (x,y) de caminhos parciais
if (dist(x,y) <= d) então
xm = x; ym = y; d = dist(x,y);
conecte (xm, ym) por uma aresta
conecte os dois pontos por uma aresta
¼ Este algoritmo está correto para o contra-exemplo
anterior. Então agora estará correto ?
48
Par Mais Próximo
¼ Algoritmo não é correto!
¼ Existe algoritmo correto ?!
49
Um algoritmo correto
z Podemos tentar todas as ordenações de pontos possíveis e
então selecionar a ordenação que minimiza o
comprimento total.
z Uma vez que todas as possíveis ordenações são
consideradas, podemos garantir que teremos o melhor
caminho possível.
z Mas, isso significa testar n! permutações, que é
extremamente lento. Tão lento que é inviável quanto se
tem mais de 10 ou 20 pontos.
z Conclusão: Não existe um algoritmo correto eficiente!
Traveling Salesman Problem 50
Eficiência
“Porque (simplesmente) não usar um supercomputador?”
z Supercomputadores são para pessoas muito ricas e muito
estúpidas para escrever algoritmos eficientes! (S.Skiena)
z Um algoritmo rápido rodando em um computador lento
irá sempre ganhar de um supercomputador com um
algoritmo ruim para instâncias suficientemente grandes.
z Normalmente, os problemas não chegam a ficar tão
grandes antes do algoritmo rápido ganhar.
51
Correção
z Método de Solução
Æ Fórmulas / Propriedades
Æ Lemas / Teoremas
z Conjunto de Instruções
Æ Invariantes & Convergentes
` trecho de código faz exatamente o desejado
` não tem nenhum loop infinito
Æ Prova de Teoremas
` seqüência de instruções usa corretamente as propriedades
teóricas
` garante a integridade das fórmulas
52
M.D.C.
Entrada: x, y ∈ Z*
Saída: mdc(x,y)
max{z ∈ Z | ∃ a,b ∈ Z, x=a*z, y=b*z}
exemplo 1:
exemplo 2:
mdc(67,12) = 1
mdc(64,12) = 4
53
Algoritmo Ingênuo - mdc
int mdc(int x, int y)
{
int t;
if (x < y) t = x;
else
t = y;
while ((x%t != 0) && (y%t != 0))
t--;
return t;
}
54
Correção Total
Correção Parcial + Término = Correção Total
z Correção Parcial
Æ pontos de verificação e invariantes
z Término
Æ
Æ
Æ
0 < t <= min(x,y)
t = 1 ⇒ não itera
a cada iteração t decresce ⇒ t é o convergente
Conclusão: O algoritmo ingênuo para o problema
do M.D.C. é totalmente correto!
55
Algoritmo de Euclides - mdc
Entrada: x, y ∈ Z*
Saída: mdc(x,y)
max{z ∈ Z | ∃ a,b ∈ Z, x=a*z, y=b*z}
exemplo 1:
67
7
5
12
5
exemplo 2:
1
7
2
1
5
1
2
2
0
2
1
64
4
5
12
0
3
4
56
Algoritmo de Euclides - mdc
mdc (54180,13125) = ?
4
54180 13125
7
5
Algoritmo Ingênuo:
Algoritmo Euclides:
7
1680
2
1
1365
1
13020
5
4
315
0
3
105
iterações
iterações
(2604 x !!!)
Correção:
Æ mdc (0, x) = x, pois qualquer número é divisor de zero
Æ mdc (x, y) = mdc (y, x mod y) é o resultado básico usado na solução
57
Algoritmo de Euclides - mdc
Com recursividade:
int mdc(int u, int v) {
if (v == 0)return (u);
else
return (mdc(v,u%v));
}
int
int mdc(int
mdc(int u,
u, int
int v){
v){
int
int t;
t;
Convertendo de
recursivo para
não-recursivo:
while
while (v
(v !=
!= 0)
0) {{
t=u%v;
t=u%v; u=v;
u=v; v=t;
v=t;
}}
return
return u;
u;
}}
58
Problema: Ponto em Polígono
Dado em polígono plano simples, ou seja, os
lados não se cruzam, P e um ponto p do
plano, decidir se p é interior ou não ao
polígono P.
P
•p
59
Complexidade Assintótica
z Existe algum algoritmo que resolve o problema?
Æ Isso requer que o algoritmo pare após um número finito de
passos para qualquer instância do problema.
z Dado um certo algoritmo A, quão eficiente é este
algoritmo? Dado dois algoritmos A e B, qual deles é
superior?
z Dentre todos os algoritmos que resolvem o problema, qual
deles é melhor?
z Medir a complexidade (ou eficiência) de um algoritmo
pelo tempo necessário à sua execução em função do
tamanho da instância. (Complexidade Assintótica O(f (n)))
60
Análise de Algoritmos
z Recursos Computacionais
Æ Tempo de execução e quantidade de memória
z Implementação do Algoritmo
Æ Linguagem e arquitetura
z Tamanho da entrada (N)
Æ Número de elementos ou número de nós da expressão
z Complexidade (tempo) de Pior Caso
Æ T(N): Maior tempo de execução do algoritmo com todos os
problemas possíveis de tamanho N.
Æ T(N) é proporcional ao número total de instruções t (N)
executadas para o pior caso de tamanho N ⇒ T(N) = c t (N)
61
Definição 1
Um algoritmo A para resolver P tem
complexidade O(f (n)) se existe uma
constante k > 0 e um natural N tais que, para
qualquer instância de P de tamanho n > N, o
número de passos de A necessários para
resolver esta instância é, no máximo, k f (n).
ex. 1000 n2
“ambiente computacional” “natureza do método”
62
Ordens de Magnitude
x←x+y
for i ← 1 to n
for i ← 1 to n
begin
begin
x←x+y
for j ← 1 to n
begin
end
x←x+y
end
end
1
n
n2
63
Complexidade
z Se um algoritmo processa problemas de tamanho
n em tempo cn2 para alguma constante c, então
dizemos que a complexidade (time complexity) do
algoritmo é O(n2), lendo-se “ordem n2”.
algoritmo
A1
A2
A3
A4
A5
complexidade
n
n log n
n2
n3
2n
1s
1000
140
31
10
9
1m
6x104
4893
244
39
15
1h
3.6x106
2.0x105
1897
153
21
64
Complexidade
65
Tempo de Execução
20
50
100
200
500
1000
1000 n
0.02 s
0.05 s
0.1 s
0.2 s
0.5 s
1s
1000 n log n
0.09 s
0.3 s
0.6 s
1.5 s
4.5 s
10 s
100 n2
0.04 s
0.25 s
1s
4s
25 s
2m
10 n3
0.02 s
1s
10 s
1m
21 n
2.7 h
nlog n
0.4 s
1.1 h
220 d
125 s
5E8 s
2n
1s
35 a
3E4 s
Tamanho
Complexidade
-
Obs.: Supondo que 1 operação leva 1 µs.
66
Tamanho Máximo do Problema
Tempo
Complexidade
1s
1.7 m
2.7 h
12 d
3a
3s
1000 n
1E3
1E5
1E7
1E9
1E11
1E13
1000 n log n
1.4E2
7.7E3
5.2E5
3.9E7
3.1E9
2.6E11
100 n2
1E2
1E3
1E4
1E5
1E6
1E7
10 n3
46
2.1E2
1E3
4.6E3
2.1E4
1E5
nlog n
22
36
54
79
112
156
2n
19
26
33
39
46
53
67
Curiosidade
z Explosão Combinatorial
Æ
Æ
Æ
Æ
100! → número com 158 dígitos
120! → número com 200 dígitos
número de prótons no universo → 126 dígitos
número de µ segundos desde o Big-Bang → 24 dígitos
z Impacto da Evolução Tecnológica
algoritmo
n
n2
n3
2n
atuais
N1
N2
N3
N4
100 x
100 N1
10 N2
4.64 N3
N4 + 6.64
1000 x
1000 N1
31.6 N2
10 N3
N4 + 9.97
68
Outra Curiosidade (sic!)
z
Dada a função f abaixo, calcule o seu valor
para x = 40545 e y = 70226.
f (x,y) = 9 x4 - y4 + 2 y2
dígitos: 3
7
11 15
19 21
1010 -10-13 1.3 107 82152 2
Oops! O valor correto é 1
69
Outra Curiosidade (sic!)
z Dada a função f abaixo, calcule o seu valor para:
x = 77617
y = 33096.
f (x,y) = 333.75 y6 + x2 (11 x2 y2 - y6 - 121 y4 - 2) + 5.5 y8 + x/2y
Precisão simples:
Precisão dupla:
Precisão extendida:
1.172603…
1.1726039400531…
1.172603940053178…
Oops! O valor correto é -0.8273960599…
( - 54767 / 66192 )
70
Moral da História
“Computers do not solve problems,
People do!”
E.R.Davidson
71
Algoritmos para Ordenação
z Insertion Sort
z Selection Sort
z Bubble Sort
z Shell Sort
z etc.
72
Ordenação por Seleção
SelectionSort(x,n)
para i = 1 .. n-1
m=i
para j = i+1 .. n
se xj < xm então m = j
troque xi com xm
73
Ordenação por Seleção
74
Ordenação por Seleção
z Para analisar tal algoritmo, a primeira observação é que o
tamanho de uma instância é dada pelo número n de reais a
serem ordenados.
z Na primeira execução do corpo do loop principal, são feitas
n-1 comparações e 1 troca, num total de n operações.
z Na segunda execução, n-2 comparações e 1 troca, e assim
por diante. Logo, o número de passos para o algoritmo é:
n(n + 1) n 2 n
n + (n − 1) + (n − 2 ) + + 1 =
=
+ ≈ n2
2
2 2
z Assim, o algoritmo tem complexidade O(n2)
75
Não entendeu ?!
z Porque
N (N + 1)
i=
∑
2
i =1
N
?
… soma de seqüências!
z Quanto é a soma de inteiros de 1 até 100 ?
Æ Com papel e lápis pode demorar um pouco …
Æ Podemos usar uma calculadora …
Æ Escrever um programa …
z Em 1786, um garoto de 9 anos respondeu em
alguns 5 segundos!
z Nome dele ? Gauss.
76
Demonstração de Gauss
n
S (n ) = ∑ i = 1 + 2 + 3 + + n
i =1
S (n ) = 1 + 2 + 3 + + n
+
S (n ) = n + (n − 1) + (n − 2 ) + + 1
2 S (n ) = (n + 1) + (n + 1) + + (n + 1)
n ⋅ (n + 1)
S (n ) =
2
n vezes
77
Ordenação por Inserção
Insertsort(x)
para i = 2 .. N
v = xi
j=i
enquanto xj-1 > v
xj = xj-1
j=j-1
xj = v
Este algoritmo descobre a posição
correta para xi no segmento
x1..xi-1 ao mesmo tempo que o
coloca lá.
Com isso, obtemos soluções
parciais e algoritmo deste tipo
são chamados de incrementais
ou on-line.
Usando árvores balanceadas, é
possível implementar
algoritmos incrementais ótimos
para ordenação.
78
Ordenação por Inserção
79
Mergesort
z Usa o paradigma “dividir-para-conquistar” que obtém a
solução de um problema através da resolução de problemas
de tamanho menor.
z Ao invés de ordenar o conjunto de n números, dividimos
este conjunto em dois conjuntos com n/2 elementos cada,
ordenamos cada um destes conjuntos e reunimos esses
conjuntos já ordenados.
z Para ordenar cada um dos conjuntos com n/2 elementos,
aplicamos recursivamente o mesmo algoritmo.
80
Mergesort
Mergesort (x, l, r)
se (r <= l) então retorne; /* caso básico da recursão */
m = (l + r) / 2;
mergesort(x, l, m);
mergesort(x, m+1, r);
merge(x, l, m, r)
/* separação */
/* recursão */
/* combinação */
81
Mergesort
82
Mergesort
z Para facilitar, n=2p e seja T(n) a complexidade do
algoritmo, expressa pelo número de passos necessários à
sua execução.
z Duas chamadas recursiva do mesmo algoritmo para
instâncias de tamanho n/2, seguidas por uma etapa em que,
a partir de dois conjuntos já ordenados, deve-se obter sua
união, também já ordenada. Esta união é obtida em um
número de passos que é proporcional a n.
T(n) = 2 T(n/2) + k n
onde k é uma constante.
83
Mergesort
T(n) = 2 T(n/2) + k n
Por sua vez,
T(n/2) = 2 T(n/4) + k n/2
o que fornece
T(n) = 4 T(n/4) + 2 k n
Continuando o mesmo processo, obtemos sucessivamente:
T(n) = 8 T(n/8) + 3 k n
...
T(n) = n T(n/n) + p k n
T(n) = 2p T(n/2p) + p k n
n = 2p
T(n) = n T(1) + k (log2 n) n
p = log2 n
Daí, concluímos que T(n) = O(n log n)
84
Algoritmo Dividir-para-Conquistar
Separação: decompor a instância do
problema em duas instâncias de tamanhos
menores;
Recursão: aplicar recursivamente o mesmo
algoritmo para cada uma destas
instâncias;
Combinação: combinar os resultados para
obter a solução da instância original.
85
Teorema 1
Se um algoritmo recursivo do tipo dividir-paraconquistar para resolver um problema decompõe
uma instância de tamanho n em duas instâncias de
tamanho n/2 do mesmo problema e, se o
processamento necessário à execução das etapas
de separação e combinação tem, no total,
complexidade O(n), então o algoritmo resultante
tem complexidade O(n log n).
86
QuickSort
z Também utiliza o paradigma de dividir-para-conquistar.
z Toma-se um elemento do conjunto (x1) e a etapa de
separação consiste em dividir o conjunto a ser ordenado em
dois subconjuntos: o primeiro é composto por todos os
elementos menores que x1 e o segundo por todos os maiores
ou iguais a x1. Cada um destes conjuntos é ordenado
utilizando recursivamente o mesmo algoritmo.
z A etapa de combinação é trivial, já que a seqüência
ordenada consiste em listar os elementos (já ordenados) que
são menores que x1, seguidos pelos elementos (também já
ordenados) que são maiores ou iguais a x1.
87
QuickSort
quicksort(r,s)
se (s <= r) então retorne
v = xr ; i = r; j = s + 1;
repita
repita i = i + 1 até xi >= v
repita j = j + 1 até xj <= v
troque xi com xj
até j <= i
troque xi com xj
troque xi com xj
quicksort(r,i - 1)
quicksort(i+1,s)
/* caso básico */
/* separação */
Observações:
Observações:
••não
nãohá
háuma
umachamada
chamadaexplícita
explícita
de
decombinação
combinação
••ooinício
iníciodo
doalgoritmo
algoritmose
sedá
dá
quicksort(1,n)
chamando
chamando quicksort(1,n)
/* recursão */
88
QuickSort
89
QuickSort
z Como o processamento da separação requer O(n) passos,
uma análise semelhante à desenvolvida para o Mergesort
permite demonstrar que a complexidade média do algoritmo
é O(n log n).
z No entanto, a complexidade deste algoritmo no pior caso é
O(n2). Para se constatar este fato, basta observar que, caso o
conjunto esteja ordenado, o algoritmo descrito vai executar
n-1 separações. A primeira exige n-1 comparações, a
segunda n-2, e assim por diante, num total de O(n2)
comparações.
90
ShellSort
z Utiliza o algoritmo de inserção em sub-seqüências periódicas
da entrada para produzir um algoritmo mais rápido.
shellsort(a)
h = 1; faça (h = 3 * h + 1) até (h > N)
faça
h = h div 3
para i = h+1 até N faça
v = a i;
j = i;
enquanto aj-h > v faça
j = j - h;
aj = aj-h;
se (j <=h) termine enquanto
aj = v
até (h = 1)
91
13
ShellSort
4
• Usa uma seqüência decremental
de incrementos;
• Cada passo torna o próximo
mais fácil;
• Como saber qual incremento
usar ?
1
• Ex.: 1, 4, 13, 40, 121, 363, ...
92
BubbleSort
n bubblesort(a)
faça
t = a1
para j = 2 até N faça
se (aj-1 > aj) então t = aj-1; aj-1 = aj; aj = t;
até (t = a1)
o bubblesort(a)
para i = 1 até n-1
para j = n até i+1 passo -1
if (aj < aj-1) troque aj com aj-1
93
BubbleSort
94
Comparação
z
Selection Sort
Æ comparações: n-1 + n-2 + … + 2 + 1 = n2/2
Æ trocas: n
z
Insertion Sort
Æ comparações: (n-1 + n-2 + … + 2 + 1) / 2 = n2/4
Æ trocas: n2/4
z
Bubble Sort
Æ comparações: n-1 + n-2 + … + 2 + 1 = n2/2
Æ trocas: n2/2
95
Árvore de Decisão
A complexidade de uma árvore de decisão é dada pela sua
profundidade p, isto é, pela profundidade máxima de uma de suas
folhas.
No caso do problema de ordenação, cada uma das folhas da árvore
de decisão deverá estar associada a uma possível ordenação dos n
elementos. Como há n! ordenações possíveis, a árvore possui no
mínimo n! folhas.
Mas o número máximo possível de folhas é obtido quando todas as
folhas ocorrem a profundidade p e cada nó que não é uma folha
tem exatamente 2 descendentes.
Assim, o número de folhas é igual ao número de nós à profundidade
p que é 2p.
96
Árvore de Decisão
Logo, a profundidade p de uma árvore de decisão que possua pelo
menos n! folhas satisfaz 2p ≥ n , isto é, p ≥ log2 (n!)
Mas a aproximação de Stirling para n! é
( e)
n!= 2 Π n n
ou seja:
log 2 (n!) = log 2
(
n
)
2Π n + n log 2 n − n log 2 e ≥ kn log n
Logo, como existe um algoritmo de complexidade O(n log n),
concluímos que a complexidade do problema de ordenação é
Θ(n log n).
97
Definição 2
Dizemos que a complexidade de um problema P tem
cota inferior dada por Ω(f (n)) se existe uma
constante k tal que todo algoritmo que resolve P
requer pelo menos k f (n) passos para resolver
alguma instância de tamanho n. Dizemos que a
complexidade de P é Θ(f (n)) se, além disso,
existir um algoritmo de complexidade O(f (n))
para P. Neste caso, dizemos que o algoritmo é
ótimo para P.
98
Análise de Algoritmos
z Medidas de Consumo dos Recursos Computacionais
Æ Θ (f)
Cota assintótica superior
Æ Ο (f)
Ordem
Æ Ω (f)
Cota assintótica inferior
z Contabilidade
Æ por pontos de verificação
` em geral entrada de loops
Æ por rateio (usado em grafos)
` centros de custo
99
Exemplo: Régua comum
Entrada: número de marcas n
Saída: régua com n marcas
regua(n)
para i = 1 até n faça
marque(i,”|”)
fim_para
...
⇒
Ο(n)
100
Exemplo: Régua binária
Entrada: número de marcas n
Saída: régua com n marcas
n = 2h (h marcas diferentes)
regua_binaria(l,r,k)
m = (l + r) / 2
marque(l,m,k)
se (k > 1) então
regua_binaria(l,m,k-1)
regua_binaria(m,r,k-1)
101
Recorrência
z Vários algoritmos, particularmente os baseados no
paradigma Dividir-para-Conquistar, tem complexidades
que são naturalmente modeladas por relações de
recorrência.
z Uma relação de recorrência é uma equação que é definida
em termos dela mesma.
z Várias funções naturais são facilmente expressas como
recorrências:
Æ an = an-1 + 1, a1 = 1
→ an = n (polinomial)
Æ an = 2 * an-1, a1 = 1
→ an = 2n-1 (exponencial)
Æ an = n * an-1, a1 = 1
→ an = n! (explosão combinatória)
102
Indução
z Recursão é uma indução matemática
Æ Temos condições gerais e de fronteira, com a condição
geral dividindo em partes cada vez menores o problema.
Æ A condição de fronteira (ou inicial) termina a recursão.
z Nenhum procedimento (geral) é conhecido para
se resolver relações de recorrência.
z A indução provê uma ferramenta para resolver
recorrências: Adivinhar a solução e prová-la por
indução.
103
Prova por Indução
n
Tn
Tn = 2 * Tn-1 + 1, T0 = 0
0 1 2 3 4 5 6 7
0 1 3 7 15 31 63 127
z Qual a solução ? Prove que é Tn = 2n -1 por indução.
Æ Mostre a condição básica: T0 = 20 - 1 = 0
Æ Assuma que é verdade para Tn-1
Æ Partindo da afirmação anterior, mostre que
Tn = 2 * Tn-1 + 1 = 2 (2n-1 - 1) + 1 = 2n - 1
104
Exemplo: Régua binária
Entrada: número de marcas n
Saída: régua com n marcas
n = 2h (h marcas diferentes)
regua_binaria(l,r,k)
m = (l + r) / 2
marque(l,m,k)
se (k > 1) então
}⇒ c
regua_binaria(l,m,k-1) ⇒ T(n/2)
regua_binaria(m,r,k-1) ⇒ T(n/2)
105
Exemplo: Régua binária
T(n) = 2 T(n/2) + c
= 2 [ 2 T(n/4) + c] + c
= c + 2c + 4 T(n/4)
= c + 2c + 4c + 8c + … + 2i T(n/2i)
mas, T(2) = c
T(n) = c + 2c + 4c + 8c + … + 2i-1 T(2)
= c (1 + 2 + 22 + 23 + … + 2h-1)
= c (20 + 21 + 22 + 23 + … + 2h-1)
= c (2h - 1) = c (n - 1)
T(n) = c (n - 1)
⇒
T(n) = O(n)
106
Recorrências Usuais em DPC
ck
n=
z T(n) = a T(n/c) + k n
Esforço de
combinação
Æ a → fator de crescimento dos sub-problemas
Æ c → fator de divisão (tamanha dos sub-problemas)
T(n) = O(n)
Æa<c
T(n) = O(n log n)
Æa=c
T(n) = O(nlogc a)
Æa>c
z
T(n) = T(n/c) + k
Æ T(n) = O(logc n)
p.ex.: busca binária
107
Exemplos
T(n) = 9 T(n/3) + n
` T(n) = O(n2)
T(n) = T(2n/3) + 1
` T(n) = (log n)
T(n) = 3 T(n/4) + n log n
` T(n) = O(nlog4 3) = O(n0.793)
108
HeapSort
z
Construindo a heap
109
HeapSort
z
“Ordenando” a heap
110
Radix Sort
z Até agora, foi razoável definir métodos de
ordenação em termos de operações básicas de
comparação e troca de dois elementos quaisquer.
z Entretanto, para algumas aplicações é possível
tirar vantagem de que os elementos são números
dentro de um intervalo.
z Esse métodos são chamados de Radix Sorts.
Æ Não somente comparam os elementos.
Æ Processam e comparam pedaços dos elementos.
111
Radix Sort
329
457
657
839
436
720
355
720
355
436
457
657
329
839
720
329
436
839
355
457
657
329
355
436
457
657
720
839
Qual a complexidade deste algoritmo ?
112
Radix Sort
113
Radix Sort (exchange)
radix_sort (l,r,b)
if (r > l) and (b >= 0) then
i = l;
j = r;
repeat
while (bits(a[i],b,1)=0) and (i<j) do i=i+1;
while (bits(a[j],b,1)=1) and (i<j) do j=j+1;
t=a[i]; a[i]=a[j]; a[j]=t;
until j=i;
if (bits(a[r],b,1)=0) then j = j+1;
radix_sort(l,j-1,b-1);
radix_sort(j,r,b-1);
114
Radix Sort (straight)
115
Redução
z
z
Os resultados obtidos a respeito do
problema de ordenação são úteis para
estabelecer cotas inferiores para vários
problemas computacionais.
Para tal, recorreremos a um mecanismo que
consiste em reduzir um problema a outro.
116
Definição 3
Um problema P1 é redutível (em tempo
linear) a um problema P2 se dada uma
instância de tamanho n de P1 for
possível, em tempo O(n), obter uma
instância de I2 de P2 tal que a resposta de
P1 para I1 possa ser obtida, em tempo
O(n), a partir da resposta de P2 para I2.
Neste caso, escrevemos P1∝ P2 .
117
118
Algoritmos de Busca
z
z
z
z
z
z
Linear Search
Binary Search
Binary Search Tree
B-Tree
Hashing
Quadtree
119
Busca Linear
z Este método de procurar dados é direto e fácil entender.
Æ Para achar um determinado dado, comece sua procura ao
começo do conjunto de dados e continue ou olhando até você
achar, ou acabar o espaço de procura.
Æ A complexidade deste tipo de procura é O(n) porque, no pior
caso serão examinados todos os dados no espaço de procura.
z Como nós veremos adiante, existem muitos algoritmos
que podem melhorar tempo de procura. Por exemplo, o
algoritmo de busca binária opera muito mais eficazmente
que uma busca linear mas requer que o conjunto de dados
esteja ordenado.
120
Busca Binária
z Para se determinar se um elemento a está no vetor
A, comparamos a com o elemento b da posição
mediana do vetor A. Se a=b então “sim”. Senão,
repetimos o processo na primeira metade de A se
a<b, ou na segunda metade de A se a<b.
z Pela divisão sucessiva do espaço de busca, nunca
faremos mais de log n+1 comparações para achar
a, ou que a ∉ A.
121
Busca Binária
busca_bin(a,f,l)
se (f > l) então retorne “não”
senão se (a = A[(f+l)/2]) então retorne “sim”
senão se (a < A[(f+l)/2]) então busca_bin(a,f,(f+l)/2-1)
senão busca_bin(a,(f+l)/2+1,l)
7?
32 ?
não
sim
2
3
6
8
12 20 24 29 32 38 46 55
122
Árvore de Busca Binária - BST
Definição: Uma árvore de busca binária é uma árvore binária
onde cada vértice v é identificado por um elemento
l(v) ∈ S tal que:
Æ para cada vértice u na sub-árvore esquerda de v, l(u) < l(v)
Æ para cada vértice u na sub-árvore direita de v, l(u) > l(v)
Æ para cada elemento a ∈ S, existe um único vértice v tal que l(v) = a.
z A operação mais comum realizada em uma BST é a busca
por um elemento armazenado na árvore. No entanto,
também se pode realizar mínimo, máximo, sucessor e
predecessor.
z Todas essas operações são feitas em tempo O(h) em uma
BST de altura h.
123
Árvore de Busca Binária
search_BST(13) ⇒ 15 → 6 → 7 → 13.
min_BST() ⇒ 15 → 6 → 3 → 2.
max_BST() ⇒ 15 → 18 → 20.
suc_BST(15) ⇒ min_BST(right[15]) → 17.
pre_BST(15) ⇒ max_BST(left[15]) → 13.
15
6
3
2
18
7
17
20
13
4
9
124
BST: Busca, Min e Max
search_BST(x,k)
if x = nil or x = key[x]
then return x
if k < key[x]
then return search_BST(left[x],k)
else return search_BST(right[x],k)
min_BST(x)
while left[x] ≠ nil
do x ← left[x]
return x
max_BST(x)
while right[x] ≠ nil
do x ← right[x]
return x
125
BST: Sucessor e Predecessor
suc_BST(x)
if right[x] ≠ nil
then return min_BST(right[x])
y ← parent[x]
while y ≠ nil and x = right[y]
do x ← y
y ← parent[y]
return y
pre_BST(x)
if left[x] ≠ nil
then return max_BST(left[x])
y ← parent[x]
while y ≠ nil and x = left[y]
do x ← y
y ← parent[y]
return y
126
BST: Inserção
insert_BST(T,z)
y ← nil
x ← root[T]
while x ≠ nil
do y ← x
if key[z] < key[x] then x ← left[x]
else x ← right[x]
parent[z] ← y
if y = nil then root[T] ← z
else if key[z] < key[y] then left[y] ← z
else right[y] ← z
127
BST: Inserção
128
BST: Remoção
delete_BST(T,z)
if left[z] = nil or right[z] = nil then y ← z
else y ← suc_BST(z)
if left[y] ≠ nil then x ← left[y]
else x ← right[y]
if x ≠ nil then parent[x] ← parent[y]
if parent[y] = nil then root[x] ← x
else if y = left[parent[y]] then left[parent[y]] ← x
else right[parent[y]] ← x
if y ≠ z then key[z] ← key[y]
return y
129
BST: Remoção
Nó não tem filhos.
Nó tem 1 filho.
Nó tem 2 filhos.
130
Balanced Trees
z
z
2-3-4 Tree
Red-Black Tree
131
2-3-4 Tree
z Para eliminar o pior caso da BST, precisamos de
alguma flexibilidade na estrutura de dados.
z Para obter esta flexibilidade, permitimos que os
nós da árvore possam conter mais de um elemento.
Æ Especificamente, permite-se 3-nodes ou 4-nodes, que
podem conter dois ou três elementos respectivamente.
Æ Os nós padrões (BST) 2-nodes possuem um elemento
e dois links.
132
2-3-4 Tree
E
X
A
M
P
L
E
133
Red-Black Trees
z É uma BST com um bit extra por nó: sua cor, que pode ser
“red” ou “black”.
z Por restrição, a forma como os nós são coloridos, por qualquer
caminho, da raiz para as folhas assegura que nenhum caminho
é mais do que duas vezes maior que qualquer outro. Assim, é
aproximadamente balanceada.
z Propriedades:
Æ Todo nó é red ou black sendo que toda folha (nil) é black.
Æ Se um nó é red, então os filhos são black.
Æ Todo caminho de um nó para um descendente, tem o
mesmo número de nós black.
134
Red-Black Tree
Uma red-black tree com n nós internos
tem no máximo 2 log(n +1).
135
Heap e Heap Tree
z Heap = garbage-collected storage
z Heap Tree: É uma BSP (a) que possui um vetor
associado (b).
136
Heap Tree
z
A Heap Tree tem as seguintes propriedades:
Æ A[parent(i)] ≥ A[i]
Æ parent(i) { return (i/2) }
Æ left(i) { return (2*i) }
Æ right(i) { return (2*i + 1) }
A
137
Heapify: Corrigir a Heap
A[2], i = 2 → violou a propriedade da heap
heapify(A,2) → troca A[2] com A[4]
A[4], i = 4 → violou a propriedade da heap
heapify(A,4) → troca A[2] com A[4]
A[9], i = 9 → propriedade da heap ok!
Heapify(A,9) → não precisa fazer nada
138
Heapify
T(n)
heapify(a,i)
T(n)==T(2n/3)
T(2n/3)++cc
T(n)
T(n)==O(log
O(logn)
n)
l ← left(i)
r ← right(i)
Obs.:
Obs.:Alternativamente,
Alternativamente,podemos
podemos
if A[l] > A[i] and l ≤ heap_size[A]
caracterizar
caracterizarootempo
tempode
deexecução
execução
then largest ← l
do
doheapify
heapifyem
emum
umnó
nóde
dealtura
alturahh
com
else largest ← i
comO(h).
O(h).
if A[r] > A[largest] and r ≤ heap_size[A]
then largest ← r
if largest ≠ i
then exchange(A[i],A[largest])
heapify(A,largest)
139
Construindo a Heap Tree
z Podemos usar a heapify para converter um array A em
uma heap.
z Uma vez que os elementos do sub-array A[n/2+1..n] são
todos folhas da árvore, cada um é um heap para se iniciar.
build_heap(A)
heap_size[A] ← length[A]
for i = length[A] / 2 downto 1
do heapify(A,i)
140
Heap
141
Heap Sort
z Construir uma Heap Tree (build_heap)
Æ Maior elemento do array que é armazenado na raiz deve ser
colocado no seu lugar correto A[n] e então basta chamar a
heapify(A,1)
Heapsort
heap_sort(A)
HeapsortééO(n
O(nlog
logn)
n)
pois:
pois:
build_heap(A)
build_heap
build_heapéé O(n)
O(n)
for i ← length[A] downto 2
heapify
heapifyéé O(log
O(logn)
n)** n-1
n-1
do exchange(A[1],A[i])
heap_size[A] ← heap_size[A] - 1
heapify(A,1)
142
Heap
Sort
build_heap
heapify
143
Inserindo elementos na Heap Tree
Insere uma folha
heap_insert(A,key)
heap_size[A] ← heap_size[A]+1
i ← heap_size[A]
while i > 1 and A[parent(i)] > key
do A[i] ← A[parent(i)]
i ← parent(i)
A[i] ← key
Desce os elementos
um nível, desde a nova
folha até o local correto
Insere o 15
144
B-Tree
z São balanced search trees projetadas para trabalhar
em memória secundária, tais como discos, fitas ou
outro dispositivo de armazenamento secundário de
acesso direto.
z Diferem das red-black trees e 2-3-4 trees pois
podem ter vários filhos, de unidades a milhares.
z A característica de “branching factor” de uma
B-tree é determinada pelo dispositivo de
armazenamento utilizado.
145
Propriedades da B-Tree
z Todo nó x tem os seguintes dados:
Æ
Æ
Æ
n[x], o número de elementos armazenados no nó x;
os n[x] elementos armazenados de forma ordenada;
leaf[x], indica se é uma folha (true) ou um nó (false).
z Cada folha tem a mesma profundidade, que é a altura h da árvore.
z Existem limites, inferior e superior, que um nó pode conter. Esses
limites podem ser expressos em termos de um inteiro fixo t ≥ 2
chamado grau mínimo da B-tree.
Æ
Æ
Exceto o nó raiz, cada nó tem que ter ao menos t-1 elementos e tem pelo
menos t filhos. Se a árvore não for vazia, o nó raiz tem que conter pelo menos
um elemento.
Cada nó pode conter no máximo 2t-1 filhos e no máximo 2t filhos. O nó
estará cheio quando conter exatos 2t-1 elementos.
146
Busca na B-Tree
z
Alguns detalhes:
Æ A raiz da B-tree esta sempre na memória principal.
Æ Todos os nós utilizados tem que ser previamente
lidos para a memória principal.
z
Searching a B-Tree
Æ É parecida com a BST, exceto que ao invés de uma
escolha binária a cada nó, teremos uma escolha
múltipla dependente do número de filhos.
Æ Mais precisamente, a cada nó teremos n[x]+1
escolhas a decidir.
147
Inserindo elementos
na B-Tree
Supondo t = 3, cada nó
pode ter no máximo
5 elementos.
148
Retirando elementos da B-Tree
149
Hashing
z Uma abordagem completamente diferente da
baseada em comparações é conhecida como
hashing: referencia registros em uma tabela através
de operações aritméticas que convertem o elemento
em um endereço da tabela.
z Hash function: converte o elemento de busca em
um endereço da tabela.
z Collision-resolution: trata o problema de dois ou
mais elementos serem convertidos para um mesmo
endereço da tabela.
150
Hash Function
z Como as funções serão aritméticas, o primeiro
passo é converter o elemento em números.
z O métodos mais comum é escolher um número
primo M que, para qualquer elemento k, calcular
hash(k) = k mod M.
z Exemplos:
Æ M = 101, elemento “AKEY” = 44217 ⇒ 44217 mod 101 = 80
Æ Mas, se o elemento for “BARH”, o resultado também é 80.
151
Tratamento de Colisões
Tratamento da colisão
por listas encadeadas.
152
Separate Chaining
M = 11
153
Linear Probing
z Se o número de elementos N é previamente
conhecido e se M > N, então existirão espaços
vazios na tabela. Os métodos que se aproveitam
disso são chamados de open-addressing.
z Destes, o método mais simples é conhecido por
linear probing.
Æ Quando existir uma colisão, simplesmente
teste (probe) a(s) posição(ões) seguinte(s).
154
Linear Probing
M = 19
155
Linear Probing
156
Double Hashing
z Em linear probing, principalmente quando a tabela
começa a encher, várias posições tem que ser
examinadas para se poder inserir um elemento.
z Ainda pior, geralmente ocorre em vários lugares da
tabela um agrupamento, denominado clustering,
fazendo com que o desempenho caia muito.
z No entanto, existe um forma fácil de resolver este
problema, denominada double hashing: em caso de
colisão, utilizamos uma outra função de hashing.
157
Double Hashing
M = 19
158
Double Hashing
159
Grafos
z Vários problemas são naturalmente modelados
por objetos e conexões entre eles.
z Por exemplo:
Æ Caminho mínimo:
` Qual o menor caminho entre a cidade A e a cidade B ?
Æ Conectividade:
` O interruptor A está conectado a lâmpada B ?
Æ Fluxos:
` Para fazer a tarefa A, precisamos antes fazer a B e C.
z Um grafo (graph) é um objeto matemático que
modela precisamente estes problemas.
160
Nomenclatura de Grafos
Æ Um grafo é uma coleção de vértices (ou nós) e arestas.
Æ Um caminho (path) entre os vértices a e b é uma lista sucessiva
de vértices conectados por arestas.
Æ Um grafo é dito conectado se existe um caminho de cada nó
para qualquer outro.
Æ Um ciclo é um caminho em que começa e termina no mesmo
vértice.
161
Nomenclatura de Grafos
Æ Um grafo sem ciclos é chamado de árvore.
Æ Um grupo de árvores desconectadas é chamada de floresta.
Æ Uma spanning tree de um grafo é um sub-grafo que contém
todos os vértices mas apenas as arestas necessárias para formar
uma árvore.
162
Nomenclatura de Grafos
z Além dos tipos anteriores, denominados não dirigidos
(undirected graphs), existem tipos de grafos mais
complicados, onde algumas informações são atribuídas aos
vértices e/ou as arestas.
z Quando associamos a cada aresta uma informação, um custo
ou uma distancia por exemplo, denomina-se weighted graphs.
z Quando as arestas possuem uma única direção, ou seja, uma
aresta conecta o vértice a ao vértice b mas não o inverso, é dito
que temos um grafo dirigido (directed graphs).
z Os grafos que possuem as duas características anteriores, são
chamados directed weighted graph ou de networks.
163
Representação de Grafos
Grafo
Lista de adjacências
Matriz
164
Busca em Grafos
z Problema: Dado um vértice inicial, queremos
percorrer o grafo visitando todos os vértices
possíveis de serem alcançados a partir do vértice
inicial.
z Os dois algoritmos mais usados em árvores, ou
seja, grafos sem ciclos, são a busca em largura e a
busca em profundidade.
Æ Breadth-First Search
Æ Depth-First Search
165
Depth-First Search - DFS
Também conhecido como backtracking, faz um
caminho partindo do vértice inicial e vai até o
mais longe possível no grafo.
Æ Cada nova aresta percorrida tem que ser uma aresta
ainda não usada pelo algoritmo.
Æ O algoritmo continua até atingir um vértice que não
possua arestas ou que conduzam a vértices ainda não
visitados. A partir deste vértice, retornamos ao
vértice anterior e escolhemos uma nova aresta. Este
procedimento é feito até que todas as arestas sejam
percorridas e todos os vértices visitados.
166
Depth-First Search
?
167
DFS (com matriz)
visit(k)
id = id + 1; val[k] = id
para t = 1 até V faça
se a[k,t] então
se val[t]=0 então visit(t);
dfs()
id = 0;
para k = 1 até V faça val[k] = 0;
para k = 1 até V faça
se val[k] = 0 então visit(k);
168
DFS (com listas)
visit(k)
id = id + 1; val[k] = id
t = next[k];
enquanto t ≠ nil faça
se val[t]=0 então visit(t);
t = next[t];
dfs()
id = 0;
para k = 1 até V faça val[k] = 0;
para k = 1 até V faça
se val[k] = 0 então visit(k);
169
Breadth-First Search - BFS
z DFS “explora” o grafo procurando novos vértices
cada vez mais distante do vértice inicial e só
utiliza vértices mais próximos quando não existe
nada “mais distante” naquele caminho.
z BFS “explora”, primeiro, todos os vértices mais
próximos do vértice inicial, só utilizando vértices
mais distantes depois que todos os vértices
próximos forem visitados.
z É também chamada de busca em amplitude.
170
Breadth-First Search
171
BFS (com listas)
visit(k)
queue(k);
faça
k = dequeue();
id = id + 1; val[k] = id;
t = next[k]
enquanto t ≠ nil faça
se val[t] = 0 então
queue(t);
val[t] = -1;
t = next[t];
até queue_empty();
172
DFS x BFS
DFS
1/3
BFS
2/3
1/3
2/3
173
Árvore Geradora Mínima
z
z
Minimum Spanning Tree
Algoritmo de Prim
174
MST = 16
175
Algoritmo de Prim
z
z
Segue a estratégia do guloso (greedy)
Existem três tipos de vértices:
Æ os vértices que já estão na árvore mínima (S)
Æ os adjacentes aos vértices da árvore (F de fringe)
Æ os vértices ainda não examinados (U de unseen)
V=S∪F∪U
176
Algoritmo de Prim
177
Algoritmo de Prim
1. Inicie com qualquer vértice v
S = {V}
F = {vértices adjacentes}
U = {vértices restantes}
178
Algoritmo de Prim
2. Construa a MST
Usa-se
heappara
Usa-seuma
umaheap
paraarmazenar
armazenar
os
osvértices
vérticesde
deFF..
OOmenor
heap.
menorpeso
pesofica
ficana
naraiz
raizda
daheap.
repita
ache aresta (v,w) de menor peso tal que v∈S e w∈F
inclua (v,w) na MST
inclua w a S
atualize F
até S = V.
179
Algoritmo de Prim:
passo-a-passo
180
Algoritmo de Prim:
passo-a-passo
181
Caminho Mínimo
z
z
Shortest Paths
Algoritmo de Dijkstra
origem
destino
182
Algoritmo de Dijkstra
1. Adicione um vértice de cada vez ao caminho mínimo,
escolhendo o vértice mais próximo a um vértice da árvore.
2. Os vértice são divididos em unseen, fringe e tree.
3. Os vértices vão de unseen para fringe via da operação de
insert.
4. Os vértices vão de fringe para tree via operação de
remove_min.
5. Atualiza-se a fringe sempre que um novo vértice for
inserido na tree.
183
Algoritmo de Dijkstra
184
Algoritmo de Dijkstra
185
Algoritmo de Dijkstra
186
Algoritmo de Dijkstra
187
Algoritmo de Dijkstra
d(PVD, SFO) = 200+1000+1500+800
d(PVD, SFO) = 3500
188
Caminho Mínimo em uma
Superfície 3D
189
Caminho Mínimo em Mapas
190
Caminho Mínimo em Imagens:
Detecção de Contorno
191
Redes de Fluxos
z
z
Maximum Flow
The Tao of Flow:
Æ “Let your body go with the flow.”
- Madonna, Vogue
Æ “Maximum flow … because you’re worth it.”
- Lóreal
Æ “Use the flow, Luke!”
- Obi-wan Kenobi, Star Wars
192
Redes de Fluxos
z Possui dois vértices distintos dos demais:
Æ Fonte s (source) e Tanque t (sink)
z Os pesos (weights) das arestas são chamados de
“capacidades”.
193
Fluxo e Capacidades
z
Capacidades:
Æ Similares aos pesos dos grafos, mas não podem ser
negativos.
z
Fluxo:
Æ É função da rede de arestas.
Æ 0 ≤ fluxo ≤ capacidade
Æ Em cada vértice: fluxo entrando = fluxo saindo
Æ Valor: combinação dos fluxos no tanque.
194
Fluxo e Capacidades
195
Problema do Fluxo Máximo
“Dada uma rede de fluxos N, ache o fluxo f de
valor máximo.”
z Aplicações:
Æ Tráfego
Æ Sistemas hidráulicos
Æ Circuitos Elétricos
196
Aumentando o Fluxo
Fluxo da rede = 3
Caminhos aumentados
Fluxo da rede = 4
?
197
Caminhos Aumentados
z Arestas para frente
Æ fluxo < capacidade
Æ fluxo pode ser aumentado!
z Arestas para trás
Æ fluxo > 0
Æ fluxo pode ser diminuído!
z
Teorema do Fluxo Máximo
“Um fluxo tem um valor máximo se e somente
se não tiver um caminho aumentado.”
198
Algoritmo de Ford & Fulkerson
z inicialize a rede com fluxo igual a zero
z Find_Flow()
se existir um caminho aumentado então
ache o caminho aumentado
aumente o fluxo
Find_Flow()
199
Achando o Fluxo Máximo
200
Roberto Beauclair
tron@visgraf.impa.br
tron@tecgraf.puc-rio.br
tron@lncc.br
201