Está en la página 1de 33

Algoritmo de

Bellman-Ford
FABIO AUGUSTO VANEGAS BOVEA
Caractersticas

Genera el camino ms corto en un grafo dirigido ponderado (en


el que el peso de alguna de las aristas puede ser negativo)
Se utiliza cuando hay aristas con peso negativo
Relaja todas las aristas y lo hace |v| - 1 veces, siendo |v| el
numero de vrtices del grafo.
Halla el camino de todos los vrtices a un nico vrtice de
destino.
Ventajas

Frente al algoritmo de Dijkstra resuelve este mismo problema en


un tiempo menor, pero requiere que los pesos de las aristas no
sean negativos, salvo que el grafo sea dirigido y sin ciclos.
Funcionamiento
En el siguiente ejemplo se explica el funcionamiento del algoritmo:
En el siguiente grafo, cuyos ID estn en color negro encima de cada
vrtice, los pesos esta en color azul y la distancia inicial en cada
vrtice es infinito
La siguiente matriz representa los nombres de los vrtices, las
distancias y previo almacenara el ID del vrtice anterior al
vrtice con ID = u, me servir para impresin del camino ms
corto, al empezar el valor es menos uno.

En el cdigo hacemos las siguientes definiciones para un mejor funcionamiento:


#define MAX 105 //maximo numero de vrtices
#define Node pair< int , int > //definimos el nodo como un par( first , second )
donde first es el vertice adyacente y second el peso de la arista
#define INF 1<<30 //definimos un valor grande que represente la distancia infinita
inicial, basta conque sea superior al maximo valor del peso en alguna de las aristas
Las variables quedaran declaradas de la siguiente manera.

vector< Node > ady[ MAX ]; //lista de adyacencia


int distancia[ MAX ]; //distancia[ u ] distancia de vrtice inicial a vrtice con ID = u
int previo[ MAX ]; //para la impresion de caminos
int V; //numero de vrtices

//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 1 a todos
los dems vrtices.
Inicialmente la distancia de vrtice 1 -> vrtice 1 es 0 por estar
en el mismo lugar.

Colocando el valor cero en la matriz

distancia[ inicial ] = 0; //Este paso es importante,


inicializamos la distancia del inicial como 0
Ahora segn Bellman-Ford debemos realizar el paso de relajacin |V| 1 = 5 1 =
4

for( int i = 1 ; i <= V - 1 ; ++i ){ //Iteramos |V| - 1 veces



}
Primera Iteracin

Empezamos con las aristas que parten del vrtice 1:


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 vertice actual
int adyacente = ady[ actual ][ j ].v; //id del vertice adyacente
int peso = ady[ actual ][ j ].w; //peso de la arista que une
actual con adyacente ( actual , adyacente )

}
}

Las aristas de acuerdo al cdigo serian de la forma e = (actual ,


adyacente , peso)
distancia[ 1 ] + 7 < distancia[ 2 ] -> 0+7<
-> 7<
El paso de relajacin es posible realizarlo entonces actualizamos la
distancia en el vrtice 2 quedando:

Donde se observa que en la matriz se actualiza colocando en valor


de 7 que va a hacer la distancia entre el nodo 1 y el nodo 2 y all se
guarda el valor previo que es el nodo 1.
El grafo se actualiza de la siguiente manera
Se vuelve a ejecutar el ciclo en el siguiente cdigo:

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 vertice actual
int adyacente = ady[ actual ][ j ].v; //id del vertice adyacente
int peso = ady[ actual ][ j ].w; //peso de la arista que une
actual con adyacente ( actual , adyacente )
//Realizamos paso de relajacion para la arista actual
relajacion( actual , adyacente , peso );
}
}
Y se vuelve a calcular el paso de relajacin:
//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 distancia del origen al vertice adyacente
if( distancia[ actual ] + peso < distancia[ adyacente ] ){
distancia[ adyacente ] = distancia[ actual ] + peso;
//relajamos el vertice actualizando la distancia
previo[ adyacente ] = actual; //a su vez
actualizamos el vertice previo
Q.push( Node( adyacente , distancia[ adyacente ] ) );
//agregamos adyacente a la cola de prioridad
}
}
Donde:

distancia[ 1 ] + 2 < distancia[ 4 ] -> 0+2<


-> 2<
Con lo cual la matriz vuelva a actualizar sus valores:

Donde se coloca la distancia en el vrtice 4, y se guarda el valor previo


que es donde proviene ese valor que es 1, que es la conexin entre el
vrtice 1 y el vrtice cuatro
El grafo se actualizara quedando as:
Hemos terminado las aristas que parten del vrtice 1, continuamos
con las aristas que parten del vrtice 2:
distancia[ 2 ] + 1 < distancia[ 3 ] -> 7+1< -> 8
<
Y la matriz se actualiza quedando

Ahora continuamos con la arista que une al vrtice 2 con el vrtice 4:


En este caso vemos que no se lleva acabo el paso de relajacin
ya que:

distancia[ 2 ] + 2 < distancia[ 4 ] -> 7+2<2 ->


9<2
Por lo tanto no actualizamos valores en la tabla. Ahora el siguiente
vrtice a evaluar es el vrtice 3 que posee una sola arista, y el grafo
es:
Como el peso de su vrtice adyacente es infinito actualizamos la
distancia:
Quedando la matriz

Ahora el siguiente vrtice a evaluar es el vrtice 4 que posee cuatro aristas:


Y se vuelven a calcular las distancias
Con vrtice 2: distancia[ 4 ] + 3 < distancia[ 2 ] -> 2+3<7
-> 5<7

Con vrtice 3: distancia[ 4 ] + 8 < distancia[ 3 ] -> 2+8<8


-> 10 < 8

Con vrtice 5: distancia[ 4 ] + 5 < distancia[ 5 ] -> 2 + 5 < 13


-> 7 < 13
Actualizamos distancias para los vrtices 2 y 5:
Quedando la matriz de la siguiente forma:
Donde nos dice como quedaron actualizadas las distancias
Y el valor previo que nos dice de que vrtice provienen.

Por ultimo analizamos el nodo 5 que tiene una arista que


apunta al nodo 4.
No se actualizan distancias y se termina la ejecucin del algoritmo
quedando el siguiente grafo

Segunda Iteracin

Como vemos hay valores de rutas que no quedaron actualizados


como pasa con el vrtice 3 donde hay una distancia de 8.
Nos damos cuenta que la distancia del vrtice 2 que es 5
sumndole la distancia del vrtice 2 al 3 que es 1, dara una
distancia de 6 que debe ir en el vrtice 2. Esta distancia se
actualiza en la segunda iteracin quedando el grafo de la
siguiente manera.
Con su respectiva matriz

También podría gustarte