Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Descripcin
El algoritmo de Bellman-Ford determina la ruta ms corta desde un nodo origen hacia
los dems nodos para ello es requerido como entrada un grafo cuyas aristas posean
pesos. La diferencia de este algoritmo con los dems es que los pesos pueden tener
valores negativos ya que Bellman-Ford me permite detectar la existencia de un ciclo
negativo.
Como trabaja
El algoritmo parte de un vrtice origen que ser ingresado, Bellman-Ford simplemente
relaja todas las aristas y lo hace |V| 1 veces, siendo |V| el nmero de vrtices del
grafo.
Para la deteccin de ciclos negativos realizamos el paso de relajacin una vez ms y si
se obtuvieron mejores resultados es porque existe un ciclo negativo, para verificar
porque tenemos un ciclo podemos seguir relajando las veces que queramos y
seguiremos obteniendo mejores resultados.
Algoritmo en pseudocdigo
Considerar distancia[ i ] como la distancia ms corta del vrtice origen ingresado al
vrtice i y |V| el nmero de vrtices del grafo.
1mtodoBellmanFord(Grafo,origen):
2inicializamoslasdistanciasconunvalorgrande
3distancia[origen]=0
4para i = 1 hasta |V| - 1:
5para cada aristaEdelGrafo:
6sea(u,v)vrticesqueunenlaaristaE
7seawelpesoentrevrtices(u,v)
8Relajacion(u,v,w)
9para cada aristaEdelGrafo:
10sea(u,v)vrticesqueunenlaaristaE
11seawelpesoentrevrtices(u,v)
12siRelajacion(u,v,w)
13ImprimirExisteciclonegativo
15TerminarAlgoritmo
1 Relajacion(actual,adyacente,peso):
2sidistancia[actual]+peso<distancia[adyacente]
3distancia[adyacente]=distancia[actual]+peso
Dnde:
1
2
3
4
1
2
3
4
5
6
7
//funcin de inicializacin
void init(){
for( int i = 0 ; i <= V ; ++i ){
distancia[ i ] = INF; //inicializamos todas las distancias con valor infinito
previo[ i ] = -1;
//inicializamos el previo del vrtice i con -1
}
}
De acuerdo al vrtice inicial que elijamos cambiara la distancia inicial, por ejemplo la
ruta
ms
corta
partiendo
del
vrtice
todos
los
dems
vrtices.
distancia[ inicial ] = 0;
0
1
2
3
Primera Iteracin
Empezamos con las aristas que parten del vrtice 1:
Como podemos observar tenemos 2 aristas, la que une vrtice 1 con vrtice 2 y vrtice
1 con vrtice 4. Ello en cdigo:
1
2
3
4
5
6
7
for( int actual = 1 ; actual <= V ; ++actual ){ //Estos dos for = O(E)
for( int j = 0 ; j < ady[ actual ].size() ; ++j ){ //reviso sus adyacentes del verti
int adyacente = ady[ actual ][ j ].v;
//id del vertice adyacente
int peso = ady[ actual ][ j ].w;
//peso de la arista que une actual con a
adyacente )
}
}
->
0+7<
->
7<
1
2
3
4
5
6
7
8
for( int actual = 1 ; actual <= V ; ++actual ){ //Estos dos for = O(E)
for( int j = 0 ; j < ady[ actual ].size() ; ++j ){ //reviso sus adyacentes del verti
int adyacente = ady[ actual ][ j ].v;
//id del vertice adyacente
int peso = ady[ actual ][ j ].w;
//peso de la arista que une actual con a
adyacente )
//Realizamos paso de relajacion para la arista actual
relajacion( actual , adyacente , peso );
}
}
1
2
3
4
5
6
7
8
9
//Paso de relajacion
void relajacion( int actual , int adyacente , int peso ){
//Si la distancia del origen al vertice actual + peso de su arista es menor a la di
adyacente
if( distancia[ actual ] + peso < distancia[ adyacente ] ){
distancia[ adyacente ] = distancia[ actual ] + peso; //relajamos el vertice ac
previo[ adyacente ] = actual;
//a su vez actualizamos e
Q.push( Node( adyacente , distancia[ adyacente ] ) ); //agregamos adyacente a l
}
}
De manera similar al anterior vemos que la distancia actual desde el vrtice inicial a 4
es , verifiquemos el paso de relajacin:
distancia[ 1 ] + 2 < distancia[ 4 ]
->
0+2<
->
2<
Hemos terminado las aristas que parten del vrtice 1, continuamos con las aristas que
parten del vrtice 2:
->
7+1<
->
8<
En esta oportunidad hemos encontrado una ruta ms corta partiendo desde el vrtice
inicial al vrtice 3, actualizamos la distancia en el vrtice 3 y actualizamos el vrtice
previo al actual quedando:
->
7+2<2
->
9<2
->
2+3<7
->
2+8<8
->
2 + 5 < 13
->
->
->
5<7
10 < 8
7 < 13
En esta iteracin solamente se realiz el paso de relajacin en la arista que une vrtices
2 y 3. Para el grafo dado en la segunda iteracin ya habremos obtenido la ruta ms
corta partiendo del vrtice 1 a todos los dems vrtices. Sin embargo no siempre
obtendremos el ptimo en la 2da iteracin, todo depender del grafo ingresado.
Impresin del Camino Ms Corto
La impresin del camino ms corto dado un vrtice destino es de la misma forma como
se explic en el tutorial del Algoritmo de Dijkstra.
Deteccin de Ciclo Negativo
Para la deteccin de ciclo negativo tomaremos como ejemplo el grafo siguiente:
Segunda Iteracin
En esta ltima iteracin se relajan vrtices 2 y 3:
Hemos terminado el nmero de iteraciones que tenamos que realizar. Para verificar la
existencia de un ciclo negativo, segn el algoritmo de Bellman-Ford, realizamos el paso
de relajacin sobre todas las aristas una vez ms:
1
2
3
4
5
6
7
8
9
10
11
12