View
217
Download
0
Category
Preview:
Citation preview
Caminhos Mais Curtos Fluxo Máximo Árvores Geradoras Mínimas
Túlio Toffolo – www.toffolo.com.br Marco Antônio Carvalho – marco.opt@gmail.com
BCC402 – Aula 14
Algoritmos e Programação Avançada
Plano da Aula
• Caminhos Mais Curtos
• Algoritmo de Dijkstra
• Algoritmo de Floyd
• Fluxo Máximo
• Algoritmo de Ford Fulkerson
• Árvores Geradoras Mínimas
• Algoritmo de Kruskal
• Algoritmo de Prim
• Otimização dos algoritmos
2
Caminhos mais Curtos
• Dados: grafo G=(V,A) orientado e
distância cij associada ao arco (i,j) ∈ A.
Problema: Obter o caminho mais curto entre dois nós s e t.
4
• O comprimento de um caminho é igual à soma dos comprimentos (distâncias) dos arcos que formam o caminho.
• A “distância” ou “comprimento” de um arco pode ter diversas interpretações
Exemplo 1: Dado um mapa rodoviário, determinar a rota mais curta de uma cidade a outra.
Caminhos mais Curtos
5
Exemplo 2: Construção de uma estrada entre duas cidades A e K. O grafo abaixo representa os diversos trechos possíveis e o custo de construção de cada um. Determinar o trajeto ótimo cujo custo de construção seja mínimo (corresponde a achar o caminho mais curto de A a K em relação a estes custos).
A
B
C
D
F
E
G J
I
H
K
8
7
5
6 4
2 4
5
4
4
2
2 4 4
5
2 4 4
Solução: A – D – G – I – K custo = 7 + 2 + 2 + 5 = 16
Caminhos mais Curtos
• Condição de existência:
Caminho de i a j contendo um circuito w:
6
k j
i
w
Comprimento do caminho = comprimento (i → k) + comprimento (w) + comprimento (k → j)
Qual é o comprimento do caminho mais curto de i a j se o comprimento do circuito w é negativo?
Caminhos mais Curtos
Condição de existência:
não há circuitos de comprimento negativo.
7
A solução ótima (caminho mais curto) sempre será um caminho elementar (sem ciclo).
Caminhos mais Curtos
8
" Caminho mais curto:
- De um nó a outro - De um nó a todos os demais - Entre todos os pares de nós de um grafo
Caminhos mais Curtos
9
Caminho mais curto do nó 1 a cada nó do grafo G=(V,A)
Hipótese: todas as distâncias cij são positivas: cij ≥ 0, ∀(i,j) ∈ A
• Algoritmo de Moore-Dijkstra (1957-1959) π*(i) = comprimento do caminho mais curto do nó 1 ao nó i Em especial, π*(1)=0 (distâncias positivas).
" Algoritmo com n-1 iterações " No início de cada iteração, o conjunto V de nós está
particionado em dois subconjuntos S e S, com o nó 1 em S.
VSS
SS
=∪
=∩ φ
Caminhos mais Curtos
10
– Cada nó i ∈ V possui um rótulo π(i ), que verifica a seguinte propriedade:
)(*)( Se
)(*)( Se
iiSiiiSi
ππ
ππ
≥⇒∈
=⇒∈ { }kiΓkSk
ckii
+=−∈
∈)(min)( ππ
– dá o valor do caminho mais curto de 1 a i sob a restrição de que todos os nós utilizados (exceto o próprio i ) pertençam a S.
, ),( Sii ∈π
a
1 b
c
i
)(aπ
)(bπ
)(cπ
)(iπcai
cbi
cci
SS
Caminhos mais Curtos
11
Teorema: Seja o nó tal que . Então , isto é, o comprimento do caminho mais curto do nó 1 ao nó j é igual a .
Sj ∈ )( min)( ijSiππ
∈=
)( )(* jj ππ =
Demonstração:
– Por construção, certamente existe um caminho de 1 até j com comprimento π(j).
– Suponhamos que exista outro caminho de 1 a j de comprimento menor do que π(j).
– Dividamos este caminho em duas partes:
- P1 é a parte inicial, do nó 1 ao nó L, onde L é o primeiro nó de encontrado
- P2 é a parte final, do nó L ao nó j
)( jπ
S
Caminhos mais Curtos
12
– comprimento de P1 ≥ π(L) ≥ π(j)
comprimento de P2 ≥ 0
Logo, o comprimento de P1 + P2 ≥ π(j).
Caminhos mais Curtos
Algoritmo de Moore-Dijkstra
14
Inicializar S ← {2,3,...,n}, S ← {1}, π(1)← 0, π(j)← c1j se j∈Γ1+ +∞ caso contrário Enquanto S ≠ ∅ faça Selecionar j∈S tal que π(j)= mini∈S{π(i)} S ← S – {j} Para ∀i∈S e i∈Γj+ faça π(i) ← min{π(i), π(j)+cji} fim_enquanto
Caminhos mais Curtos
• O algoritmo de Moore-Dijkstra constrói progressivamente o conjunto dos nós mais próximos de 1.
• Construção de uma arborescência com raiz em 1 que define os caminhos mais curtos do nó 1 a cada nó do grafo.
15
Caminhos mais Curtos
16
Exemplo:
1
2
3
4
5
6 1
2
3 5
7
7
5
1 2
4
ITERAÇÃO 1
π*(1) = 0
π*(3) = 1
1
2
3
4
5
6 1
2
3 5
7
7
5
1 2
4
S = {1} S = {2,3,4,5,6}
π(1) = 0 π(2) = 7 π(3) = 1 π(4) = π(5) = π(6) = +∞
π(2) = min{7, π(5) = min{∞, π(6) = min{∞,
j = 3 S = {2,4,5,6}
1+5} = 6 1+2} = 3 1+7} = 8
Caminhos mais Curtos
17
ITERAÇÃO 2
π(2) = min{6, π(4) = min{∞,
j = 5 S = {2,4,6}
3+2} = 5 3+5} = 8
π*(1) = 0
π*(3) = 1
1
2
3
4
5
6 1
2
3 5
7
7
5
1 2
4 π*(5) = 3
ITERAÇÃO 3
π(4) = min{8, π(6) = min{∞,
j = 2 S = {4,6}
5+4} = 8 5+1} = 6
π*(1) = 0
π*(3) = 1
1
2
3
4
5
6 1
2
3 5
7
7
5
1 2
4 π*(5) = 3 π*(2) = 5
Caminhos mais Curtos
18
ITERAÇÃO 4
π(4) = 8
j = 6 S = {4}
ITERAÇÃO 5
j = 4 S = { }
π*(1) = 0
π*(3) = 1
1
2
3
4
5
6 1
2
3 5
7
7
5
1 2
4 π*(5) = 3 π*(2) = 5
π*(6) = 6
π*(1) = 0
π*(3) = 1
1
2
3
4
5
6 1
2
3 5
7
7
5
1 2
4 π*(5) = 3 π*(2) = 5
π*(6) = 6
π*(4) = 8
Caminhos mais Curtos
19
1
2
3
5
4 2
3
2 5
4
3
1 2
6
7
3
1
4
3
6 5 4 3 2 1
1
2
3
7
6
5
4
nó Iteração
Início
0
4
2
∞
∞
∞
∞
π
0
4
2
5
4
7
7
0
4
2
5
4
∞
∞
0
4
2
5
4
7
7
0
4
2
5
4
7
7
0
4
2
5
4
7
7
0
4
2
5
4
7
7
Caminhos mais Curtos
20
• Número de operações (tempo): ~ n2
n-1 iterações, cada iteração busca o mínimo em uma lista com até n-1 elementos (vetor π)
" Caminho mais curto do nó 1: → ao nó j → a todos os nós Mesma complexidade, mas critérios de parada diferentes.
" Distâncias negativas:
1
3
2 10
- 8
3 Caminho mais curto de 1 a 3?
Resultado do algoritmo?
2
3
Por que?
Caminhos mais Curtos
Algoritmo de Moore-Dijkstra para o caso com distâncias negativas
21
Inicializar S ← {2,3,...,n}, S ← {1}, π(1)← 0, π(j)← c1j se j∈Γ1+ +∞ caso contrário Enquanto S ≠ ∅ faça Selecionar j∈S tal que π(j)= mini∈S{π(i)} S ← S – {j} Para ∀i∈Γj+ faça Calcular π* ← π(j)+ cji Se π* < π(i) então S ← S ∪ {i} π(i) ← π* fim-se fim-para fim-enquanto
Caminhos mais Curtos
• Dados:
Grafo G=(V, A) orientado, |V | = n.
Não há circuitos negativos.
c = {cij}, j = 1,...,n, i = 1,...,n
cij ≥ 0
cii = 0
cij = +∞, (i, j ) ∉ A
23
Ak(i, j ) = valor do caminho mais curto de i a j podendo usar apenas nós numerados de 1 a k como nós intermediários.
Caminhos mais Curtos
A0(i, j ) = cij : caminho mais curto de i a j usando no máximo o nó “0” (que não existe) como nó intermediário (caminho mais curto de i a j sem nós intermediários)
24
Ak(i, j ) : pode usar o nó k ou não.
Ak+1(i, j ) : pode usar o nó k+1 ou não.
A0 → A1
A1 → A2
...
An-1 → An
An(i, j ) = valor do caminho mais curto de i a j podendo usar qualquer nó de 1 a n como nó intermediário.
Caminhos mais Curtos
• Se Ak+1(i, j ) não usa o nó k+1 como intermediário, então:
Ak+1(i, j ) = Ak(i, j )
• Se Ak+1(i, j ) usa o nó k+1 como intermediário, então:
Ak+1(i, j ) = Ak(i, k+1) + Ak(k+1, j )
25
Ak+1(i, j ) = min { Ak(i, j ), Ak(i, k+1) + Ak(k+1, j ) }
Caminhos mais Curtos
Algoritmo de Floyd:
26
Para i = 1,...,n faça Para j = 1,...,n faça
A0(i,j) ← cij fim-para fim-para Para k = 1,...,n faça Para i = 1,...,n faça Para j = 1,...,n faça Ak(i,j) ← min{Ak-1(i,j), Ak-1(i,k) + Ak-1(k,j)} fim-para fim-para fim-para
Caminhos mais Curtos
Teoriade Grafos 27
0 7 3 2 0 6 11 4 0
A1 =
Exemplo:
1 2
3
3
6
4
11 2 0 +∞ 3 2 0 6 11 4 0
C = 0 +∞ 3 2 0 6 11 4 0
A0 =
0 7 3 2 0 6 6 4 0
A2 = 0 7 3 2 0 5 6 4 0
A3 =
Caminhos mais Curtos
• Algoritmo de Dijkstra: número de operações (tempo) ~ n2
n-1 iterações, cada iteração busca o mínimo em uma lista com até n-1 elementos (vetor π)
• Algoritmo de Floyd: número de operações (tempo) ~ n3
Três comandos for de 1 até n um dentro do outro
• Ou seja, o problema de calcular os caminhos mais curtos entre todos os pares de nós pode ser resolvido com a mesma eficiência aplicando-se n vezes o algoritmo de Dijkstra, uma vez a partir de cada nó inicial.
28
Otimizações: uso de Heaps
Operação Complex. “Real”
Complexidade Amortizada
Pairing Heap Fibonacci Heap
isEmpty O(1) O(1) O(1)
size O(1) O(1) O(1)
getMax O(1) O(1) O(1)
put O(1) O(log n) ** O(1)
removeMax O(n) O(log n) O(log n)
meld O(1) O(log n) ** O(1)
remove O(n) O(log n) O(log n)
increaseKey O(n) O(log n) ** O(1)
Problema do Fluxo Máximo
• Dados: Grafo G=(X,U) orientado
∀u ∈ U: capacidade c(u)
0 ≤ f(u) ≤ c(u)
31
• Problema: Obter um fluxo máximo de S a P respeitando as restrições de capacidade e as restrições de conservação de fluxo em cada nó.
S P fonte sumidouro f
Problema do Fluxo Máximo
32
Exemplo:
S P
f
S P
a
b
1
2
4 3
5 1,
1,
2, 3,
0,
∞ 3,
capacidades c fluxos f
" Inserindo-se um arco de retorno, transforma-se um fluxo em uma “circulação”:
Problema do Fluxo Máximo
33
Com o arco de retorno:
=− ∑∑== xuTuxuIuufuf
)(:)(:
)()( v, x = S
0, ∀x ≠ S, ∀x ≠ P
-v, x ≠ P
I(u) T(u) u
: ( ) : ( )
( ) ( ) 0,u I u x u T u x
f u f u x X= =
− = ∀ ∈∑ ∑
Problema do Fluxo Máximo
34
Exemplo:
a
b
c
d
e S P
∞
∞
∞ ∞
∞ 5 2
1 1
1 7
3 2
" Capacidades associadas aos nós:
x
2
8 7
3
x1
2
8
x2
7
3 c(x)
Problema do Fluxo Máximo
" Algoritmo de rotulação de Ford e Fulkerson (idéia básica)
36
Início: fluxo viável (por exemplo um fluxo nulo) Iteração:
Determinar um caminho C de S a P ao longo do qual nenhum arco esteja saturado. (isto é, f(u) = c(u))
Circuito Γ = C ∪ {(P,S)}
Aumentar o fluxo ao longo dos arcos de Γ do valor δ = minu∈Γ[c(u)-f(u)]
Problema do Fluxo Máximo
37
Exemplo:
S P
a
b
1
4 3
5
2
Este fluxo (f=3) é máximo?
Por que?
2
2
1
1
1
1 3
3
Fluxo máximo = 4
Problema do Fluxo Máximo
• Obter uma cadeia ligando S e P que, em conjunto com o arco de retorno (P,S) defina um ciclo Γ:
Γ+: arcos de Γ orientados como (P,S)
Γ-: arcos de Γ orientados no sentido oposto a (P,S)
δ1= minu∈Γ+ [c(u) – f(u)] (aumento possível nos arcos de Γ+)
δ2= minu∈Γ- [f(u)] (redução possível nos arcos de Γ-)
38
" Melhorar a solução (aumentar o fluxo) somando δ = min{δ1, δ2} aos fluxos nos arcos de Γ+ e subtraindo δ aos fluxos nos arcos de Γ-.
" A inexistência de um caminho aumentante no grafo original não quer dizer que não seja possível aumentar o fluxo.
Problema do Fluxo Máximo
39
Exemplo:
S P
a
b 2, 4
1, 1
3, 3
0, 5
1, 2 Γ-
Γ+
Γ+
Γ+ 3, ∞
Γ
δ1 = 2
δ2 = 1
f(u) c(u)
δ = 1
+1 -1
+1
+1
X 3
X 0
1 X
X 4
Problema do Fluxo Máximo
Algoritmo
• Procedimento de rotulação para obter um ciclo Γ:
40
Nó x → rótulo δ(x) Quantidade pela qual pode ser aumentado o fluxo de S a x seguindo uma cadeia cujo último arco é A(x)
" Rotulação direta:
x marcado δ(x) com u = (x,y)
f(u) < c(u) y não marcado
δ(y) = min { δ(x), c(u)-f(u) }
x y u
δ(x)
A(y) = u
Problema do Fluxo Máximo
41
" Rotulação inversa:
x marcado δ(x) arco u = (y,x)
f(u) > 0 y não marcado
δ(y) = min { δ(x), f(u) }
x y u
δ(x)
A(y) = u
f(u) ← 0 ∀u
ROTULAR(f,δ,A,Y)
Enquanto δ > 0 faça
ALTERAR_FLUXOS(f,δ,A)
ROTULAR(f,δ,A,Y)
fim-enquanto
Problema do Fluxo Máximo
42
ROTULAR(f,δ,A,Y) δ, δ(S) ← +∞ Y ← {S} Enquanto P ∉ Y e δ > 0 faça Se ∃u =(x,y): x ∈ Y, y ∉ Y e f(u) < c(u) então Y ← Y ∪ {y} A(y) ← u δ(y) ← min {δ(x), c(u)-f(u)} Senão Se ∃u =(y,x): x ∈ Y, y ∉ Y e f(u) > 0 então Y ← Y ∪ {y} A(y) ← u δ(y) ← min {δ(x), f(u)} Senão δ ← 0 fim-enquanto Se P ∈ Y então δ ← δ(P) FIM-ROTULAR
Problema do Fluxo Máximo
43
ALTERAR_FLUXOS(f,δ,A) x ← P f(P,S) ← f(P,S) + δ Enquanto x ≠ S faça u ← A(x) Se x = T(u) então f(u) ← f(u) + δ x ← I(u) Senão f(u) ← f(u) - δ x ← T(u) fim-enquanto FIM-ALTERAR_FLUXOS
Problema do Fluxo Máximo
44
Exemplo:
S P
a
b 2, 4
1, 1
3, 3
0, 5
1, 2
3, ∞
A(P) = (a,P) Y = {S, b, a, P} δ(P) = 1
A(a) = (a,b) Y = {S, b, a} δ(a) = 1
δ = 1
A(b) = (S,b) Y = {S, b} δ(b) = 2
A(S) = (P,S) Y = {S} δ(S) = +∞
f(S,b) = 3
f(a,b) = 0
f(a,P) = 1
f(b,P) = 3
f(S,a) = 1
f(P,S) = 4
4, ∞
1, 5
0, 2
3, 4
Marcação:
Problema do Fluxo Máximo
45
S P
a
b
1, 1
3, 3
δ = 0, P ∉ Y
Y = {S, b} δ(b) = 1
4, ∞
1, 5
0, 2
3, 4
Y = {S} δ(S) = +∞
FIM
Marcação:
Exemplo:
Problema do Fluxo Máximo
46
1 5
2
3 4 8
7
6
10
20
12
8
9 12
6
8
8
15 4
5
15
∞
A(7) = (6,7) Y = {1, 2, 6, 7} δ(7) = 15
A(6) = (2,6) Y = {1, 2, 6} δ(6) = 15
δ = 15
A(2) = (1,2) Y = {1, 2} δ(2) = 20
A(1) = (7,1) Y = {1} δ(1) = +∞ f(6,7) = 15
f(2,6) = 15
f(1,2) = 15
f(7,1) = 15
15 15
15
15
Exemplo:
Problema do Fluxo Máximo
47
1 5
2
3 4 8
7
6
10
20
12
8
9 12
6
8
8
15 4
5
15
∞
A(8) = (4,8) Y = {1, 3, 4, 8} δ(8) = 9
A(4) = (3,4) Y = {1, 3, 4} δ(4) = 9
δ = 8
A(3) = (1,3) Y = {1, 3} δ(3) = 10
A(1) = (7,1) Y = {1} δ(1) = +∞
f(4,8) = 8
f(3,4) = 8
f(1,3) = 8
f(7,1) = 23
15 15
15
15
A(7) = (8,7) Y = {1, 3, 4, 8, 7} δ(7) = 8
f(8,7) = 8
23
8 8 8
8
Exemplo:
Problema do Fluxo Máximo
48
1 5
2
3 4 8
7
6
10
20
12
8
9 12
6
8
8
15 4
5
15
∞
A(5) = (3,5) Y = {1, 2, 3, 5} δ(5) = 5
A(3) = (2,3) Y = {1, 2, 3} δ(3) = 5
δ = 5
A(2) = (1,2) Y = {1, 2} δ(2) = 5
A(1) = (7,1) Y = {1} δ(1) = +∞
f(3,5) = 5
f(2,3) = 5
f(1,2) = 20
f(7,1) = 28
15 15
15
23
A(7) = (5,7) Y = {1, 2, 3, 5, 7} δ(7) = 5
f(5,7) = 5
8 8 8
8
28
20
5 5 5
Exemplo:
Problema do Fluxo Máximo
49
20
1 5
2
3 4 8
7
6
10
20
12
8
9 12
6
8
8
15 4
5
15
∞
A(7) = (5,7) Y = {1, 3, 5, 7} δ(7) = 2
A(5) = (3,5) Y = {1, 3, 5} δ(5) = 2
δ = 2
A(3) = (1,3) Y = {1, 3} δ(3) = 2
A(1) = (7,1) Y = {1} δ(1) = +∞ f(5,7) = 7
f(3,5) = 7
f(1,3) = 10
f(7,1) = 30
15
15
28
8 8 8
8
30
5 5 5
10
7 7
Exemplo:
Problema do Fluxo Máximo
50
7 7
10
30
20
1 5
2
3 4 8
7
6
10
20
12
8
9 12
6
8
8
15 4
5
15
∞
Y = {1} δ(1) = +∞
15
15
8 8
8 5
δ = 0, P ∉ Y FIM
Exemplo:
Problema do Fluxo Máximo
Teorema do Corte Mínimo
• Um conjunto de arcos C é chamado de corte separando P de S se ∃ Y ⊂ X com S ∈ Y e P ∉ Y tal que
C = { u ∈ U: I(u) ∈ Y, T(u) ∉ Y }
• Um corte separando P de S corta qualquer caminho de S a P no grafo G = (X,U).
• Capacidade de um corte separando P de S:
c(C) = ∑u∈C c(u)
51
Problema do Fluxo Máximo
" Teorema:
52
fSP
fPS
S P
Y Y
f(P,S) ≤ c(C) fluxo viável f corte C
)()(
)(),(0
),(
Ccuc
uffSPff
SPfff
Cu
Cuspps
pssp
=≤
=≤⇒≥
+=
∑
∑
∈
∈
Problema do Fluxo Máximo
• Corolário: Quando o algoritmo de rotulação termina com um fluxo f sem que seja possível marcar o nó P, f é a solução ótima do problema de fluxo máximo de S a P.
53
P ∉ Y
f(u) = c(u),
senão a extremidade u estaria marcada
u T(u)
u I(u)
Y Y
f(u) = 0,
senão a extremidade u estaria marcada
Y Y
Problema do Fluxo Máximo
• Corolário: Se as capacidades são inteiras, então o algoritmo de Ford e Fulkerson obtém em um número finito de iterações uma solução ótima do problema de fluxo máximo.
54
Problema do Fluxo Máximo
• Teorema:
O valor do fluxo máximo é igual à capacidade do corte mínimo separando P de S.
55
Ao final do procedimento de rotulação:
fSP = fPS + f*(P,S)
fPS = 0
fSP = c(C)
f*(P,S) = c(C)
f(P,S) ≤ c(C)
corte é mínimo. f*(P,S)
S P
Y Y
fSP
fPS
Problema do Fluxo Máximo
56
7 7
10
30
20 Exemplo:
1 5
2
3 4 8
7
6
10
20
12
8
9 12
6
8
8
15 4
5
15
∞
Y = {1} δ(1) = +∞
15
15
8 8
8 5
δ = 0, P ∉ Y FIM
Corte mínimo Capacidade = 30
Fluxo máximo = 30
Introdução
• Árvore Geradora Mínima – AGM (Minimum Spanning Tree – MST)
• Um dos problemas de otimização mais simples e mais bem estudados em Ciência da Computação e Teoria dos Grafos
• Objetivos
• Obtenção de uma árvore em um grafo conexo, com arestas valoradas, de tal forma que a soma dos custos das arestas seja mínimo
Principais Algoritmos
• Algoritmo de Boruvka (1926)
O. Boruvka. O jistém problému minimálním. Práca Moravské Prirodovedecké Spolecnosi, 3 (1926), 37-58. (In Czech.)
• Algoritmo de Kruskal (1956)
J.B. Kruskal. On the shortest spanning tree of a graph and the traveling salesman problem. Proceedings of the American Mathematical Society, 7:48-50, 1956.
• Algoritmo de Prim (1957)
R.C. Prim. Shortest connection networks and some generalizations. Bell Systems Technology Journal, 36:1389-1401, 1957.
Algoritmo de Boruvka
• Primeiro algoritmo proposto para resolução do Problema da Árvore Geradora Mínima
• Surgiu em 1926 antes dos primeiros computadores e da publicação do primeiro livro sobre teoria dos grafos (1936)
• Seu propósito era fornecer uma cobertura elétrica eficiente para a cidade de Bohemia
• Método ideal para implementação em computadores paralelos
Algoritmo de Boruvka
• Seja um grafo G(N, A), onde N é o conjunto de nós e A o conjunto de arestas
Passo 1: Para cada i ∈ N faça Ni ← { i }
Passo 2: T* ← {}
Passo 3: Enquanto |T*| < (n-1) faça
Ø Para cada árvore Nk faça min(Nk, ik, jk) Ø Para cada árvore Nk faça
Se os nós ik e jk pertencem a árvores diferentes então unir(ik, jk) e atualizar T* ← T* ∪ {(ik, jk)}
∈
Algoritmo de Kruskal
• Idéia do algoritmo:
• Aresta de menor peso sempre pertence à árvore geradora de peso mínimo
• Complexidade: O(A * log A)
• Gargalo: ordenação das arestas
Algoritmo de Kruskal
Criar uma lista L com as arestas ordenadas em ordem crescente de pesos. Criar |V| subárvores contendo cada uma um nó isolado. F ← ∅ contador ← 0 Enquanto contador < |V|-1 e L ≠ ∅ faça Seja (u,v) o próximo arco de L. L ← L – {(u,v)} Se u e v não estão na mesma subárvore então F ← F ∪ {(u,v)} Unir as subárvores que contêm u e v. contador ← contador + 1 fim-se fim-enquanto
Variação do Algoritmo de Kruskal
• Idéia do algoritmo:
• Se a aresta de menor peso sempre pertence à árvore geradora de peso mínimo, então a aresta de maior peso não pertence, se o número de arestas for maior que n-1
• Complexidade: O(A*log A)
• Gargalo: ordenação das arestas
Variação do Algoritmo de Kruskal
Criar uma lista L com as arestas ordenadas em ordem decrescente de pesos. F ← L contador ← 0 Enquanto contador < |A|-|V|-1 e L ≠ ∅ faça Seja (u,v) o próximo arco de L. L ← L – {(u,v)} Se (u,v) não é ponte então F ← F - {(u,v)}
contador ← contador + 1 fim-se fim-enquanto
Algoritmo de Kruskal
• Principais desvantagens:
• O método exige uma “etapa preparação”, por exemplo, em caso de representação por listas de adjacência
• Grande consumo de memória
Algoritmo de Prim
• Idéia do algoritmo:
• Inicia com uma árvore formada apenas por um nó qualquer do grafo, ou pela aresta de peso mínimo.
• A cada iteração, adiciona a aresta de menor peso que conecta um nó já conectado a um nó ainda não conectado
• Complexidade: O(A*log N) = O(A*log A)
• Usando Heap de Fibonacci: O(A + N*log N)
Algoritmo de Prim
Seja (u,v) a aresta de menor peso. F ← {(u,v)} Para i = 1,...,n faça Se c(i,u) < c(i,v) então prox(i) ← u Senão prox(i) ← v fim-para prox(u), prox(v) ← 0, contador ← 0 Enquanto contador < n-2 faça Seja j tal que prox(j)≠0 e c(j,prox(j)) é mínimo. F ← F ∪ {(j,prox(j))} prox(j) ← 0 Para i = 1,...,n faça Se prox(i) ≠ 0 e c(i,prox(i)) > c(i,j) então prox(i) ← j fim-para contador ← contador + 1 fim-enquanto
Implementações
• Variação na estrutura de dados utilizada:
• Prim usando Pairing Heap
• Prim usando Fibonacci Heap
• Prim usando Binary Heap
Pairing Heap x Fibonacci Heap
Operação Complex. “Real”
Complexidade Amortizada
Pairing Heap Fibonacci Heap
isEmpty O(1) O(1) O(1)
size O(1) O(1) O(1)
getMax O(1) O(1) O(1)
put O(1) O(log n) ** O(1)
removeMax O(n) O(log n) O(log n)
meld O(1) O(log n) ** O(1)
remove O(n) O(log n) O(log n)
increaseKey O(n) O(log n) ** O(1)
Resultados de Moret e Shapiro (1991)
• Grafos esparsos
1) Binary Heap 2) Fibonacci Heap 3) Slay tree 4) Rank-relaxed Heap 5) Pairing Heap
Resultados de Moret e Shapiro (1991)
• Grafos com A = N * log N
1) Binary Heap 2) Fibonacci Heap 3) Slay tree 4) Rank-relaxed Heap 5) Pairing Heap
Resultados de Moret e Shapiro (1991)
• Grafos com A = N3/2 (grafos densos)
1) Binary Heap 2) Fibonacci Heap 3) Slay tree 4) Rank-relaxed Heap 5) Pairing Heap
Resultados da Literatura
• Moret e Shapiro (1991) fazem uma série de experimentos envolvendo vários algoritmos e estruturas de dados para gerar uma AGM.
• Nos testes foram utilizadas diferentes estruturas e densidades de grafos
• Foi feita uma análise tanto de desempenho quanto de consumo de espaço em memória
Recommended