Algoritmos de grafos
Universidad DaVinci Dr. Vicente Cubells (vcubells@iudavinci.edu.mx)
Temario Algoritmos de grafos Algoritmos de Kruskal y Prim
Árbol de expansión mínimo
Búsqueda en profundidad Algoritmo de Dijkstra
Camino mínimo
Algoritmos de grafos Árbol de expansión mínimo Kruskal Prim Búsqueda Primero en profundidad (DFS) Primero en anchura (BFS) A estrella Camino más corto Dijkstra (Caminos mínimos) Bellman-‐Ford
Algoritmo de Kruskal… 1
1
12
8 1
5
3
3
5 3
3 6 2
3 2
7
6
8 10
10
7
11
8
14
3
6 4
2
8
9
13
Algoritmo de Kruskal… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Algoritmo de Kruskal… 1
1
5
12
7 10
3
2
11
14
6
4
8
9
13
Algoritmo de Kruskal… 1
1
5
1
12
7 10
3
2
11
14
6
4
8
9
13
Algoritmo de Kruskal… 1
1
5
1
12
7 10
3
2
11
14
6
2
4
8
9
13
Algoritmo de Kruskal… 1
1
5
1
12
7 10
3
2
11
14
6
2
4
2
8
9
13
Algoritmo de Kruskal… 1
1
5
3
1
12
7 10
3
2
11
14
6
2
4
2
8
9
13
Algoritmo de Kruskal… 1
1
5
3
1
7 3
3
2
12
10
11
14
6
2
4
2
8
9
13
Algoritmo de Kruskal… 1
1
5
3
1
7 3
3
2
12
10
6
2
4
2
8
11
14
3
9
13
Algoritmo de Kruskal… 1
1 1
5
3
7 3
3
3
2
2
4
12
10
6
2
8
11
14
3
9
13
Algoritmo de Kruskal… 1
1 1
5
3
7 3
3
3
12
10
6
11
14
3
3 2
2
4
2
8
9
13
Algoritmo de Kruskal… 1
1 1
5
3
3
3
7 3
5
12
10
6
11
14
3
3 2
2
4
2
8
9
13
Algoritmo de Kruskal… 1
1 1
5
3
3
3 3 2
2
7 3
5
12
10
6
11
14
3
6 4
2
8
9
13
Algoritmo de Kruskal… 1
1 1
5
3
3
3 6 2
3 2
7 3
5
12
10
6
11
14
3
6 4
2
8
9
13
Algoritmo de Kruskal… 1
1 1
5
3
3
3 6 2
3 2
7 3
5
12
10
6
7
11
14
3
6 4
2
8
9
13
Algoritmo de Kruskal… 1
1 1
5
3
3
5 3
3 6 2
3 2
7
12
8 10
6
7
11
14
3
6 4
2
8
9
13
Algoritmo de Kruskal… 1
1 1
5
3
3
5 3
3 6 2
3 2
7
12
8 10
6
7
11
8
14
3
6 4
2
8
9
13
Algoritmo de Kruskal… 1
1
12
8 1
5
3
3
5 3
3 6 2
3 2
7
8 10
6
7
11
8
14
3
6 4
2
8
9
13
Algoritmo de Kruskal… 1
1
12
8 1
5
3
3
5 3
3 6 2
3 2
7
6
8 10
10
7
11
8
14
3
6 4
2
8
9
13
Algoritmo de Kruskal… 1
1 1
5
3
7 3
3
3
6
12
8 10
10
7
11
8
14
3
3 2
2
4
2
8
9
13
Algoritmo de Kruskal… Un cluster es un conjunto de vértices, por lo tanto el
cluster[x] es el conjunto en donde se encuentra el vértice x Los cluster va a ayudar a detectar cuando hay ciclos
(x,y,w) es una arista que une al vértice x con el vértice
y y el peso de la arista es w Suponemos que el grafo G tiene n vértices Se tiene un conjunto T de aristas que van a formar el árbol de expansión mínimo
Algoritmo de Kruskal… Conjunto Aristas Kruskal (Grafo G con n vértices) { Para cada vértice V de G: Definir clúster[v] = { V } es decir un clúster por cada vértice Inicializar el conjunto de aristas del árbol T con conjunto vacío Introducir en una lista Q todas las aristas del grafo con su peso while ( Q != vacío) { (x, y, w) = sacar arista con menor peso en la lista Q if (cluster[x] != cluster[y] ) { Añadir arista (x,y,w) al conjunto T Unir cluster[x] y cluster[y] en un solo clúster } } return T }
Algoritmo de Kruskal… 1
1
12
8 1
5
3
3
5 3
3 6 2
3 2
7
6
8 10
10
7
11
8
14
3
6 4
2
8
9
13
Algoritmo de Kruskal Clusters iniciales: {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9} , {10}, {11}, {12}, {13}, {14} Conjunto de aristas T = { } Lista con todas las aristas: Q = {(1,12,1) (1,5,8) (1,3,3) ...
Algoritmo de Prim… 1
1
12
8 1
5
3
3
5 3
3 6 2
3 2
7
6
8 10
10
7
11
8
14
3
6 4
2
8
9
13
Algoritmo de Prim… 1
1
12
8 1
5
3
3
5 3
3 6 2
3 2
7
6
8 10
10
7
11
8
14
3
6 4
2
8
9
13
Algoritmo de Prim… 1
1
12
8 1
5
3
3
5 3
3 6 2
3 2
7
6
8 10
10
7
11
8
14
3
6 4
2
8
9
13
Algoritmo de Prim… 1
1
12
8 1
5
3
3
5 3
3 6 2
3 2
7
6
8 10
10
7
11
8
14
3
6 4
2
8
9
13
Algoritmo de Prim… 1
1
12
8 1
5
3
3
5 3
3 6 2
3 2
7
6
8 10
10
7
11
8
14
3
6 4
2
8
9
13
Algoritmo de Prim… 1
1
12
8 1
5
3
3
5 Ambos vértices visitados, el arco ya no se analiza
3
3 6 2
3 2
7
6
8 10
10
7
11
8
14
3
6 4
2
8
9
13
Algoritmo de Prim… 1
1
12
8 1
5
3
3
5 3
3 3 2
2
7
6
8 10
10
7
11
8
14
3
6 4
2
8
9
13
Algoritmo de Prim… 1
1
12
8 1
5
3
3 3
2
2
10
6
6 4
8
3
5 3
7
2
8
Ambos vértices visitados, el arco ya no se analiza
10
9
7
11
8
14
3 13
Algoritmo de Prim… 1
1
12
8 1
5
3
3
5 3
3
7
6
8 10
10
7
11
8
14
3
3 2
2
4
2
8
9
13
Algoritmo de Prim… Ambos vértices visitados, el arco ya no se analiza
1
1
12
8 Ambos vértices visitados, el arco ya no se analiza
1
5
3
3
5 3
3
7
6
8 10
10
7
11
8
14
3
3 2
2
4
2
8
9
13
Algoritmo de Prim… 1
1 1
5
3
7 3
3
3
6
12
8 10
10
7
11
8
14
3
3 2
2
4
2
8
9
13
Algoritmo de Prim… 1
1 1
5
3
7 3
3
3
6
12
8 10
10
7
11
8
14
3
3 2
2
4
2
8
9
13
Algoritmo de Prim… 1
1 1
5
3
7 3
3
3
6
12
8 10
10
7
11
8
14
3
3 2
2
4
2
8
9
13
Algoritmo de Prim… 1
1 1
5
3
7 3
3
3
6
12
8 10
10
7
11
8
14
3
3 2
2
4
2
8
9
13
Algoritmo de Prim… 1
1 1
5
3
7 3
3
3
6
12
8 10
10
7
11
8
14
3
3 2
2
4
2
8
9
13
Algoritmo de Prim Algoritmo Prim(Grafo G, nodo_fuente s)! {! por cada u en V[G] hacer! !distancia[u] = INFINITO! !padre[u] = NULL! !Añadir(cola,<u,distancia[u]>)! distancia[s]=0! mientras cola != vacía do! !u = extraer_minimo(cola)! !por cada v adyacente a 'u' hacer! ! si ((v ∈ cola) && (distancia[v] > peso(u, v)) entonces! ! !padre[v] = u! ! !distancia[v] = peso(u, v)! ! !Actualizar(cola,<v,distancia[v]>)! }!
Búsqueda en profundidad… Depth First Search Sirve para hacer un recorrido de todos los nodos y
aristas de un grafo Sirve para determinar si un grafo está conectado
Búsqueda en profundidad… Para búsqueda en profundidad primero, se puede pensar
en recorrer el grafo con un hilo y pintura para marcar.
Se comienza en un vértice del grafo al cuál se amarra un hilo
1.
El vértice inicial se le denomina el vértice actual u
2.
Se pinta u como nodo visitado
3.
Se camina sobre G, seleccionando alguna arista (u,v). Se tiene el hilo en el camino de u a v Se llega al nodo v:
4.
Si v ya está visitado, se regresa a u. Se enrolla el hilo al regreso Si v no está visitado, se pinta v como visitado y ahora el nodo actual u = v. Regresar al paso 3
Búsqueda en profundidad…
Continuación… 5. Se puede llegar a un punto ciego en donde todas aristas del vértice actual u, conducen a nodos ya visitados 6. Cuando se llega a un punto ciego, se va enrollando el hilo de regreso para llegar al vértice v que condujo a u. 7. Se regresa hasta un vértice que tenga aristas que conduzcan a nodos no visitados 8. El proceso termina cuando el “regreso” llega hasta el vértice inicial
Búsqueda en profundidad… DFS(grafo G, nodo u) Para todas las arista e incidentes en u: Si la arista e no se ha recorrido w = nodo al que llega e Si w no se ha visitado Marca e con línea sólida. Arista de descubrimiento. DFS(G, w) sino Marcar e con línea punteada. Arista en retroceso
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad… 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Búsqueda en profundidad 1
12
5
7 10
3
2
11
14
6
4
8
9
13
Algoritmo de Dijkstra… Problema: G = (V , E) grafo dirigido y ponderado con
pesos no negativos; dado un vértice origen s, obtener los caminos más cortos al resto de vértices de V Si existen aristas con pesos negativos, la solución podría ser errónea Otros algoritmos permiten pesos negativos, siempre que no existan ciclos de peso negativo Idea: explotar la propiedad de que el camino más corto entre dos vértices contiene caminos más cortos entre los vértices que forman el camino
Algoritmo de Dijkstra… Un conjunto de vértices S que contiene los vértices para los que la
distancia más corta desde el origen ya es conocida. Inicialmente S = ∅.
Un conjunto de vértices Q = V −S que mantiene, para cada vértice, la
distancia más corta desde el origen pasando a través de vértices que pertenecen a S (Distancia provisional).
Para guardar las distancias provisionales usaremos un vector D[1..|V |],
donde D[i] indicará la distancia provisional desde el origen s al vértice i. Inicialmente, D[u] =∞ ∀u ∈ V− {s} y D[s]= 0. Además: Un vector P[1..|V |] para recuperar los caminos mínimos calculados. P[i] almacena el índice del vértice que precede al vértice i en el camino más corto desde s hasta i.
Algoritmo de Dijkstra… 1.
Extraer de Q el vértice u cuya distancia provisional D[u] sea menor.
→ esta distancia es la menor posible entre el vértice origen s y u. La distancia provisional se correspondía con el camino más corto utilizando vértices de S. ⇒ ya no es posible encontrar un camino más corto desde s hasta u utilizando algún otro vértice del grafo
2.
Insertar u, para el que se ha calculado el camino más corto desde s, en S (S = S ∪ {u}).
Actualizar las distancias provisionales de los vértices de Q adyacentes a u que mejoren usando el nuevo camino.
3.
Repetir 1 y 2 hasta que Q quede vacío
⇒ en D se tendrá, para cada vértice, la distancia más corta desde el origen.
Algoritmo de Dijkstra… Algoritmo Dijkstra(G,w, s) { para cada vértice v ∈ V hacer D[v] = ∞; P[v] = NULO; fin para D[s] = 0; S = ∅; Q = V ; mientras Q != ∅ hacer u = extract min(Q); /∗ según D ∗/ S = S ∪ {u}; para cada vértice v ∈ V adyacente a u hacer si D[v] > D[u] + w(u,v) entonces D[v] = D[u] + w(u,v); P[v] = u; fin si fin para fin mientras }
Algoritmo de Dijkstra… Vértice origen 1. Aristas con trazo discontinuo = caminos provisionales
desde el origen a los vértices Aristas con trazo grueso = caminos mínimos ya calculados Resto de aristas con trazo fino