Algoritmo de Dijkstra. Motivação Encontrar o caminho mínimo, de única origem, entre essa origem...
-
Upload
ester-lagos-borja -
Category
Documents
-
view
219 -
download
1
Transcript of Algoritmo de Dijkstra. Motivação Encontrar o caminho mínimo, de única origem, entre essa origem...
Algoritmo de Dijkstra
Motivação
• Encontrar o caminho mínimo, de única origem, entre essa origem e os demais vértices, num grafo dirigido ou não dirigido com arestas de peso não negativo.
Exemplo
• alguém precisa se deslocar de uma cidade para outra. Para isso, ela dispõe de várias estradas, que passam por diversas cidades. Qual delas oferece uma trajetória de menor caminho?
Restrições
• Todas as arestas do grafo devem ter custos não negativos;
• O algoritmo que serve para resolver o mesmo problema em um grafo com pesos negativos é o algoritmo de Bellman-Ford.
Exemplo• Uma distribuidora de jornais está se instalando na cidade 0(zero) e gostaria
de saber qual a menor distância até cada uma das cidades próximas (1,2,3,4):
0
1
2
3
4
10
1
5
9 64
8
2 3
Pseudocódigo Dijkstra
Fonte: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
Fila de prioridade Q• Fila de prioridade é uma estrutura de dado que mantém uma coleção de
elementos, cada um com uma prioridade associada;• Utilizaremos uma fila de prioridade Q que inicialmente conterá todos os
vértices de G;• A prioridade de um vértice v é dada por dist[v],então para o nosso grafo:
0
1
2
3
4
10
1
5
9 64
8
2 3
(0,0)
(1, ∞)
(2, ∞),
(3, ∞),
(4, ∞),
Q:
Voltando ao exemplo
Inicialização:
-----------------------------------------• dist[0] = 0;• dist[1:4] = ∞ ;• Q = { (0,0), (1, ∞), (2, ∞), (3, ∞), (4,
∞) }
0
1
2
3
4
10
1
5
9 64
8
2 3
0
∞
∞∞
∞
Voltando ao exemplo
Laço principal:
-----------------------------------------• Q = { 0, 1, 2, 3, 4 }
0
1
2
3
4
10
1
5
9 64
8
2 3
0
∞
∞∞
∞
Voltando ao exemplo
Laço principal:
-----------------------------------------• u = 0 ; v = 1;• Q = { 1, 2, 3, 4 }
0
1
2
3
4
10
1
5
9 64
8
2 3
0
∞
∞∞
∞
Voltando ao exemplo
Laço principal:
-----------------------------------------• u = 0 ; v = 1;• Q = { 1, 2, 3, 4 }
0
1
2
3
4
10
1
5
9 64
8
2 3
0
∞
∞∞
∞
0 + 10 < ∞ ? Sim!
Voltando ao exemplo
Laço principal:
-----------------------------------------• Q = { 1, 2, 3, 4 }
0
1
2
3
4
10
1
5
9 64
8
2 3
0
10
∞∞
∞
Voltando ao exemplo
Laço principal:
-----------------------------------------• Q = { 1, 2, 3, 4 } , se mantem no lugar
0
1
2
3
4
10
1
5
9 64
8
2 3
0
10
∞∞
∞
Voltando ao exemplo
Laço principal:
-----------------------------------------• u = 0 ; v = 2;• Q = { 1, 2, 3, 4 }
0
1
2
3
4
10
1
5
9 64
8
2 3
0
10
∞∞
∞
0 + 5 < ∞ ? Sim!
Voltando ao exemplo
Laço principal:
-----------------------------------------• u = 0 ; v = 2;• Q = { 1, 2, 3, 4 }
0
1
2
3
4
10
1
5
9 64
8
2 3
0
10
∞5
∞
Voltando ao exemplo
Laço principal:
-----------------------------------------• u = 0 ; • Q = { 2, 1, 3, 4 }
0
1
2
3
4
10
1
5
9 64
8
2 3
0
10
∞5
∞
0 não tem mais vizinhos!
Funcionamento• Enquanto Q.size() != 0{
u = extrai_min( Q ); Para cada vizinho “v “ de “u”{
Se dist[u] + length(u, v) < dist[v] {dist[v] ← dist[u] + length(u, v)
Q.decrease_priority(v, alt) }
}}
• A técnica de relaxamento para um arco (u, v) consiste em testar se é possível melhorar o caminho mais curto para v passando por u, e em caso afirmativo, atualizar dist[v].
Voltando ao exemplo
Enquanto Q.size() != 0{u = extrai_min( Q = {2, 1, 3, 4} );Para cada vizinho “v “ de “u”{
Se dist[u] + length(u, v) < dist[v] {dist[v] ← dist[u] + length(u, v) Q.decrease_priority(v, alt)
} }
}
0
1
2
3
4
10
1
5
9 64
8
2 3
0
10
∞5
∞
Voltando ao exemplo
Enquanto Q.size() != 0{u = extrai_min( Q = {1, 4, 3} );Para cada vizinho “v “ de “u”{
Se dist[u] + length(u, v) < dist[v] {dist[v] ← dist[u] + length(u, v) Q.decrease_priority(v, alt)
} }
}
0
1
2
3
4
10
1
5
9 64
8
2 3
0
7
135
14
Voltando ao exemplo
Enquanto Q.size() != 0{u = extrai_min( Q = {3, 4} );Para cada vizinho “v “ de “u”{
Se dist[u] + length(u, v) < dist[v] {dist[v] ← dist[u] + length(u, v) Q.decrease_priority(v, alt)
} }
}
0
1
2
3
4
10
1
5
9 64
8
2 3
0
7
135
8
Voltando ao exemplo
Enquanto Q.size() != 0{u = extrai_min( Q = {4} );Para cada vizinho “v “ de “u”{
Se dist[u] + length(u, v) < dist[v] {dist[v] ← dist[u] + length(u, v) Q.decrease_priority(v, alt)
} }
}
0
1
2
3
4
10
1
5
9 64
8
2 3
0
7
125
8
Voltando ao exemplo
Enquanto Q.size() != 0{u = extrai_min( Q = {} );Para cada vizinho “v “ de “u”{
Se dist[u] + length(u, v) < dist[v] {dist[v] ← dist[u] + length(u, v) Q.decrease_priority(v, alt)
} }
}
0
1
2
3
4
10
1
5
9 64
8
2 3
0
7
125
8
Voltando ao exemplo
-Agora sabemos os trajetos de custo mínimo
partindo de 0 até qualquer outro vértice!• d[0] = 0 distancia de 0 até 0• d[1] = 7 distância de 0 até 1• d[2] = 5 distância de 0 até 2• d[3] = 8 distância de 0 até 3• d[4] = 12 distância de 0 até 4
0
1
2
3
4
10
1
5
9 64
8
2 3
0
7
125
8
Complexidade
• Para qualquer implementação do conjunto Q, o tempo de execução é:
• O(|E|.Tdk + |V|.Tem)– Onde Tdk = complexidade das operações decrease_key– e Tem = complexidade das operações extract_minimum
Complexidade• Caso Q seja um simples vetor, temos: O(m + n²) = O(n²)• Caso Q seja um min heap, temos: O((m+n)log n)• Caso Q seja uma fibonacci heap, temos: O( m + n log n )
Lembre-se que o
algoritmo de Floyd warshal
descobre o caminho
mínimo em O(|V|³)
Dijkstra em c++
Exemplos de problemas que utilizam Dijkstra:
• URI - 1148– https://www.urionlinejudge.com.br/judge/pt/problems/view/1148
• UVA - 929– http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=11&page=show_problem&problem=870
• UVA - 10806– http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=
show_problem&problem=1747
• UVA - 11813– http://uva.onlinejudge.org/index.php?
option=com_onlinejudge&Itemid=8&page=show_problem&problem=2913
FIM