Caminho Mínimo
Autor(es): Pedro Henrique Paiola, Rene Pegoraro, Wilson M Yonezawa
Este algoritmo parte de uma estimativa inicial para o custo mínimo e vai, iterativamente, ajustando esta estimativa.
A busca se inicia a partir de um vértice, a qual denominamos origem.
Ele considera que um vértice estará fechado quando já tiver sido obtido um caminho de custo mínimo da origem até ele. Caso contrário, ele é dito aberto.
Pseudocódigo: seja G(V, A) um grafo e 𝑠 um vértice de G(origem):
1. Atribua valor zero à estimativa de custo mínimo do vértice 𝑠 e ∞ às demais.
2. Enquanto houver vértice aberto:
A. Seja 𝑘 um vértice ainda aberto cuja estimativa seja a menor entre
todos os vértices abertos: fechar o vértice 𝑘
B. Para todo o vértice 𝑗 ainda aberto que seja adjacente à 𝑘 faça:
i. Soma a estimativa do vértice 𝑘 com o custo da aresta 𝑘, 𝑗
ii. Caso essa estimativa seja melhor que a anterior para 𝑗,
substitua e anote 𝑘 como precedente (“pai”) de 𝑗
int d[MAX_V]; //d[i] armazena a distância até o vértice i, e as
//estimativas durante as iterações
int p[MAX_V]; //armazena o predecessor de cada vértice
void dijkstra(int inicial, int vertices){
priority_queue< pair<int, int> > heap; //distância, vértice
int s, t, peso;
for(int i = 0; i < vertices; i++)
d[i] = INT_MAX;
memset(p, -1, sizeof(p));
heap.push(make_pair(d[inicial] = 0, inicial));
while(!heap.empty()){
s = heap.top().second;
heap.pop();
for(int i = 0; i < grau[s]; i++){
t = adj[s][i].v;
peso = adj[s][i].w;
if (d[s] + peso < d[t]){
d[t] = d[s] + peso;
p[t] = s;
heap.push(make_pair(-d[t], t));
}
}
}
}
O algoritmo de Dijkstra se baseia em uma estratégia gulosa, e esta falha quando temos arestas com pesos negativos.
Quando fechamos o vértice aberto com menor distância até ele, estamos supondo que nenhum outro caminho até ele é menor.
Quando os pesos são não negativos, isso é verdade porque qualquer outro caminho irá utilizar arestas com peso maior ou igual a zero.
Porém, se existem arcos negativos, podemos ter caminhos que no momento apresentam um custo maior, mas posteriormente terão este custo reduzido pela adição de um arco negativo.
Confira a GIF abaixo:
se d[u] + peso(u, v) < d[v] então
d[v] = d[u] + peso(u,v)
p[v] = u
De forma semelhante ao Dijkstra, isso será feito 𝑉 − 1 vezes, porém considerando TODAS as arestas, e não apenas as incidentes no último vértice “fechado”.
Confira a GIF abaixo:
BellmanFord(G, origem)
d[v] = infinito, para todo v
p[v] = -1, para todo v
d[origem] = 0
para i de 1 até |V(G)| - 1 faça
para cada aresta (u,v) de G faça
relax(u, v, w)
para cada aresta (u,v) de G faça
se d[v] > d[u] + peso(u,v)
retorna FALSE
retorna TRUE
bool bellmanFord(int inicial, int n){
memset(p, -1, sizeof(p));
for(int i=0; i<n; i++)
d[i] = INF;
d[inicial] = 0;
for(int i = 0; i < n-1; i++){ //|V|-1 passos
for(int j = 0; j < n; j++){ //para todas as
if (d[j] == INF)
continue;
for(int k = 0; k < grau[j]; k++){ //arestas (j, k)
if(d[j] + adj[j][k].w < d[adj[j][k].v])
{
d[adj[j][k].v] = d[j] + adj[j][k].w;
p[adj[j][k].v] = j;
}
}
}
}
//Verificando se há ciclo negativo
for(int i=0; i<n; i++){
if (d[i] == INF)
continue;
for(int j = 0; j < grau[i]; j++){
if (d[adj[i][j].v] > d[i] + adj[i][j].w)
return false;
}
}
return true;
}
Aulas de Estrutura de Dados II da Profª Drª Marcia Aparecida Zanoli Meira e Silva.
Matemática Discreta e Suas Aplicações. Kenneth H. Rosen.
Seminário sobre Introdução a Teoria dos Grafos. Davi Neves, Giovani Candido, Luis Morelli e Luiz Sementille.
Biblioteca de códigos de Thiago Alexandre Domingues de Souza.
https://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/graphs.html
http://www.inf.ufsc.br/grafos/definicoes/definicao.html
https://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/shortestpaths.html
https://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/cheapestpaths.html
http://professor.ufabc.edu.br/~leticia.bueno/classes/aa/materiais/caminhominimo.pdf
http://www.inf.ufsc.br/grafos/temas/custo-minimo/dijkstra.html
https://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/dijkstra.html
http://www.deinf.ufma.br/~portela/ed211_Dijkstra.pdf
http://www.facom.ufu.br/~madriana/ED2/6-AlgDijkstra.pdf
https://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/bellman-ford.html
https://www.ic.unicamp.br/~rezende/ensino/mo417/2010s2/Slides/Aula23.pdf
http://www.dt.fee.unicamp.br/~ricfow/IA881/caminhoMinimo.pdf