algoritmo de bellman

16
ALGORITMO DE BELLMAN-KALABA (FORD) Descripción El algoritmo de Bellman-Ford determina la ruta más corta desde un nodo origen hacia los demás nodos para ello es requerido como entrada un grafo cuyas aristas posean pesos. La diferencia de este algoritmo con los demás 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 vértice origen que será ingresado, Bellman-Ford simplemente relaja todas las aristas y lo hace |V| – 1 veces, siendo |V| el número de vértices del grafo. Para la detección de ciclos negativos realizamos el paso de relajación una vez más 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 pseudocódigo Considerar distancia[ i ] como la distancia más corta del vértice origen ingresado al vértice i y |V| el número de vértices del grafo. 1 método 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 ) vértices que unen la arista E 7 sea w el peso entre vértices ( u , v ) 8 Relajacion( u , v , w ) 9 para cada arista E del Grafo: 10 sea ( u , v ) vértices que unen la arista E 11 sea w el peso entre vértices ( u , v ) 12 si Relajacion( u , v , w ) 13 Imprimir “Existe ciclo negativo”

Upload: irvin-perez-herrera

Post on 06-Nov-2015

256 views

Category:

Documents


7 download

DESCRIPTION

Bellman

TRANSCRIPT

ALGORITMO DEBELLMAN-KALABA (FORD)DescripcinEl 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 trabajaEl 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 pseudocdigoConsiderar 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 grande3 distancia[ origen ] = 04 para i = 1 hasta |V| - 1:5 para cada arista E del Grafo:6 sea ( u , v ) vrtices que unen la arista E7 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 E11 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

Ejemplo y Cdigo paso a pasoTengamos 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. Inicializamos los valores de nuestros arreglos:

Dnde: Vrtices:ID de los vrtices. Distancia[ u ]:Distancia ms corta desde vrtice inicial a vrtice con ID = u. Previo[ u ]:Almacenara el ID del vrtice anterior al vrtice con ID = u, me servir para impresin del camino ms corto.En cuanto al cdigo los declaramos de la siguiente manera:1234vector< Node > ady[ MAX ]; //lista de adyacenciaint distancia[ MAX ]; //distancia[ u ] distancia de vrtice inicial a vrtice con ID = uint previo[ MAX ]; //para la impresion de caminosint V; //numero de vrtices

Y la funcin de inicializacin ser simplemente lo siguiente:1234567//funcin de inicializacinvoid init(){for( int i = 0 ; i vrtice 1 es 0 por estar en el mismo lugar.1distancia[ inicial ] = 0; //Este paso es importante, inicializamos la distancia del inicial como 0

Hasta este momento la tabla quedara de la siguiente manera:

Ahora segn Bellman-Ford debemos realizar el paso de relajacin |V| 1 = 5 1 = 4 veces para cada arista:123for( int i = 1 ; i 7 < El paso de relajacin es posible realizarlo entonces actualizamos la distancia en el vrtice 2 quedando:

El paso de relajacin se dara en la siguiente parte:12345678for( int actual = 1 ; actual 0 + 2 < -> 2 < El paso de relajacin es posible realizarlo entonces actualizamos la distancia en el vrtice 4 quedando:

Hemos terminado las aristas que parten del vrtice 1, continuamos con las aristas que parten del vrtice 2:

Comenzamos por el vrtice 3 y realizamos paso de relajacin:distancia[ 2 ] + 1 < distancia[ 3 ] -> 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:

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:distancia[ 2 ] + 2 < distancia[ 4 ] -> 7 + 2 < 2 -> 9 < 2Por lo tanto no actualizamos valores en la tabla. Ahora el siguiente vrtice a evaluar es el vrtice 3 que posee una sola arista:

Como el peso de su vrtice adyacente es infinito actualizamos la distancia:

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

Realizamos paso de relajacin para cada vrtice adyacente:Con vrtice 2: distancia[ 4 ] + 3 < distancia[ 2 ] -> 2 + 3 < 7 -> 5 < 7Con vrtice 3: distancia[ 4 ] + 8 < distancia[ 3 ] -> 2 + 8 < 8 -> 10 < 8Con vrtice 5: distancia[ 4 ] + 5 < distancia[ 5 ] -> 2 + 5 < 13 -> 7 < 13Actualizamos distancias para los vrtices 2 y 5:

Ahora continuamos con vrtice 5:

En este caso no actualizamos las distancias. Hemos terminado la primera iteracin, continuemos: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 CortoLa impresin del camino ms corto dado un vrtice destino es de la misma forma como se explic en el tutorial delAlgoritmo de Dijkstra.Deteccin de Ciclo NegativoPara la deteccin de ciclo negativo tomaremos como ejemplo el grafo siguiente:

Asumimos que el vrtice inicial es el vrtice 1, tendremos que realizar 2 iteraciones.Primera IteracinEmpezamos por el vrtice 1:

Continuamos con el vrtice 2:

Continuamos con el vrtice 3:

Segunda IteracinEn 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:

Como se pudo realizar el paso de relajacin entonces existe un ciclo negativo:123456789101112//Comprobamos si hay ciclo negativo en el grafo ingresadofor( int actual = 1 ; actual