Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Bellman
Bellman
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
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.
1 mtodo BellmanFord(Grafo,origen):
2
inicializamos las distancias con un valor grande
3
distancia[ origen ] = 0
4
para i = 1 hasta |V| - 1:
5
para cada arista E del Grafo:
6
sea ( u , v ) vrtices que unen la arista E
7
sea w el peso entre vrtices ( u , v )
8
Relajacion( u , v , w )
9
para cada arista E del Grafo:
10
sea ( u , v ) vrtices que unen la arista E
11
sea w el peso entre vrtices ( u , v )
12
si Relajacion( u , v , w )
13
Imprimir Existe ciclo negativo
15
Terminar Algoritmo
1 Relajacion( actual , adyacente , peso ):
2
si distancia[ actual ] + peso < distancia[ adyacente ]
3
distancia[ adyacente ] = distancia[ actual ] + peso
Tengamos 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
Algunas consideraciones para entender el cdigo que se explicara junto con el funcionamiento
del algoritmo.
Cdigo
#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
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 infini
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.
Ahora segn Bellman-Ford debemos realizar el paso de relajacin |V| 1 = 5 1 = 4 veces para
cada arista:
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 ver
int adyacente = ady[ actual ][ j ].v;
//id del vertice adyacente
int peso = ady[ actual ][ j ].w;
//peso de la arista que une actual con
}
}
vrtices que unen la arista e (en este caso seran los vrtices 2 y 4) y pesoson los pesos de cada
arista (en este caso tendramos 7 y 2).
Evaluamos primero para vrtice 2:
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 ver
int adyacente = ady[ actual ][ j ].v;
//id del vertice adyacente
int peso = ady[ actual ][ j ].w;
//peso de la arista que une actual con
//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
if( distancia[ actual ] + peso < distancia[ adyacente ] ){
distancia[ adyacente ] = distancia[ actual ] + peso; //relajamos el vertice
previo[ adyacente ] = actual;
//a su vez actualizamo
Q.push( Node( adyacente , distancia[ adyacente ] ) ); //agregamos adyacente
}
}
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
Por lo tanto no actualizamos valores en la tabla. Ahora el siguiente vrtice a evaluar es el vrtice
3 que posee una sola arista:
2+3<7
->
5<7
2+8<8
->
10 < 8
2 + 5 < 13
->
7 < 13
Segunda Iteracin:
Luego de la segunda iteracin obtendremos lo siguiente:
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
Primera Iteracin
Segunda Iteracin
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: