Escolar Documentos
Profissional Documentos
Cultura Documentos
Vasco Pedro
(edited by Salvador Abreu)
Departamento de Informática
Universidade de Évora
2023/24
Docentes
▶ Teóricas
Salvador Abreu
spa@uevora.pt / CLV-240
▶ Práticas
João Pereira
joao.pedro.pereira@uevora.pt / CLV-256
▶ Análise da complexidade
▶ Complexidade amortizada
▶ Construção de algoritmos
▶ Divisão e conquista
▶ Algoritmos greedy
▶ Programação dinâmica
▶ Estruturas de dados
▶ Partição (Union-find)
▶ Algoritmos sobre grafos
▶ Percursos, ordenação topológica, árvore de cobertura mı́nima,
caminhos, fluxos
▶ Teoria da complexidade
▶ P e NP
Pré-requisitos
Estruturas de dados e algoritmos
▶ Tipo abstracto de dados (TAD)
▶ Listas
▶ Pilha
▶ Fila (com e sem prioridade)
▶ Árvores
▶ Árvore binária de pesquisa
▶ Tabelas de dispersão (hash)
▶ Ordenação
▶ Bases de análise de complexidade
Programação
▶ Bases (sólidas)
▶ Java
Bibliografia
Referência principal
Introduction to Algorithms, Cormen, Leiserson, Rivest, e Stein
(qualquer edição, a partir da 2ª), MIT Press
Outras
Algorithms Unlocked, Cormen, MIT Press, 2013
...
Avaliação
2. Afectação: O(1)
3. Acessos a i, n, V[i] e k, comparações e saltos condicionais
com complexidade constante
Juntando tudo
O(1) + O(1) + O(|V|) + O(|V|) + O(1) + max{O(1), O(1)} =
= 4 O(1) + 2 O(|V|) =
= O(|V|)
T (n) = O(n)
O(g (n)) = {f (n) : ∃c,n0 >0 tais que ∀n≥n0 0 ≤ f (n) ≤ c g (n)}
cg.n/
f .n/
n
n0
f .n/ D O.g.n//
A notação O (2)
O(g (n)) = {f (n) : ∃c,n0 >0 tais que ∀n≥n0 0 ≤ f (n) ≤ c g (n)}
Ω(g (n)) = {f (n) : ∃c,n0 >0 tais que ∀n≥n0 0 ≤ c g (n) ≤ f (n)}
f .n/
cg.n/
n
n0
f .n/ D .g.n//
Θ(g (n)) = {f (n) : ∃c1 ,c2 ,n0 >0 t.q. ∀n≥n0 0 ≤ c1 g (n) ≤ f (n) ≤ c2 g (n)}
c2 g.n/
f .n/
c1 g.n/
n
n0
f .n/ D ‚.g.n//
o(g (n)) = {f (n) : ∀c>0 ∃n0 >0 tal que ∀n≥n0 0 ≤ f (n) < c g (n)}
∀k>0 nk = o(2n )
ω(g (n)) = {f (n) : ∀c>0 ∃n0 >0 tal que ∀n≥n0 0 ≤ c g (n) < f (n)}
∀k>0 2n = ω(nk )
Traduzindo. . .
f (n) = O(g (n)) f (n) não cresce mais depressa que g (n)
f (n) = Ω(g (n)) f (n) não cresce mais devagar que g (n)
PESQUISA-DICOTÓMICA(V, k)
1 n <- |V|
2 return PESQUISA-DICOTÓMICA-REC(V, k, 1, n)
PESQUISA-DICOTÓMICA-REC(V, k, i, f)
1 if i > f then
2 return INEXISTENTE // intervalo vazio
3 m <- (i + f) / 2
4 if k < V[m] then
5 return PESQUISA-DICOTÓMICA-REC(V, k, i, m - 1)
6 if k > V[m] then
7 return PESQUISA-DICOTÓMICA-REC(V, k, m + 1, f)
8 return m // V[m] = k
Complexidade temporal das pesquisas linear e dicotómica
Pesquisa linear
T (n) = O(n)
Pesquisa dicotómica
T (n) = O(log n)
Pesquisas linear e dicotómica
Dos n elementos de um vector
70
60
50
40
tempo (s)
30
20
10
0
10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200
n elementos (milhares)
linear dicotómica
Pesquisas linear e dicotómica (com escalas diferentes)
Dos n elementos de um vector
70 0.05
60
0.04
50
0.03
40
tempo (s)
tempo (s)
30
0.02
20
0.01
10
0 0.00
10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200
n elementos (milhares)
linear dicotómica
Pesquisas linear e dicotómica (com escalas diferentes)
Dos n elementos de um vector
70 0.05
60
0.04
50
0.03
40
tempo (s)
tempo (s)
30
0.02
20
0.01
10
0 0
10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200
n elementos (milhares)
if (n == 1)
return 1;
√
Tem-se que CR(n) = Θ(ϕn ), onde ϕ = 1+2 5 ≈ 1.618 é o número
de ouro. De igual modo, temos CR(n) = O(2n ).
Logo, a complexidade temporal de fibonacci(n) é exponencial
em n
Números de Fibonacci
Versão iterativa com tabelação
// casos base
tabela[0] = 0;
tabela[1] = 1;
// caso recursivo
for (int i = 2; i <= n; ++i)
tabela[i] = tabela[i - 1] + tabela[i - 2];
return tabela[n];
}
Números de Fibonacci
Versão iterativa :-(
while (i<n) {
int p = c + a;
a = c;
c = p;
i++;
}
return c; }
Números de Fibonacci
Versão iterativa :-)
static {
memoria = new int[NMAX + 1];
memoria[1] = 1;
}
return memoria[n];
}
Complexidade temporal do cálculo dos números de
Fibonacci
T (n) = Θ(ϕn )
Cálculo iterativo
Cálculo iterativo com tabelação
Cálculo recursivo com memória
T (n) = Θ(n)
Números de Fibonacci
7000
6000
5000
4000
tempo (ms)
recursivo
memória
3000
iterativo
2000
1000
0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
n
Números de Fibonacci
Escalas diferentes
7000 0.002
6000
5000
4000
tempo (ms)
0.001
recursivo
3000 memória
iterativo
2000
1000
0 0.000
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40
n
Números de Fibonacci
Escalas diferentes
7000 0.002
6000
5000
4000
tempo (ms)
recursivo
0.001
c phi^n
memória
3000
cn
iterativo
c' n
2000
1000
0 0.000
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40