Documentos de Académico
Documentos de Profesional
Documentos de Cultura
2022 - 05 - Greedy - Parte - 2 (Dijkstra Prim Kuskal)
2022 - 05 - Greedy - Parte - 2 (Dijkstra Prim Kuskal)
Grafos
Ejercicios propuestos
Programación III
Ricardo Wehbe
UADE
11 de septiembre de 2022
Programa
2 Grafos
Caminos más cortos en grafos: Dijkstra
Árboles de recubrimiento mínimo
El algoritmo de Prim
El algoritmo de Kruskal
3 Ejercicios propuestos
2 Grafos
Caminos más cortos en grafos: Dijkstra
Árboles de recubrimiento mínimo
El algoritmo de Prim
El algoritmo de Kruskal
3 Ejercicios propuestos
Algoritmos greedy
Algoritmos greedy
Algoritmos greedy
Algoritmos greedy
Algoritmos greedy
2 Grafos
Caminos más cortos en grafos: Dijkstra
Árboles de recubrimiento mínimo
El algoritmo de Prim
El algoritmo de Kruskal
3 Ejercicios propuestos
Kneiphof (K)
puente 7
Lomse (L)
puente 3 puente 4
puente 6
Rivera sur (S)
p2
p1 N p5
K p7 L
p3 p6
p4
p2
p1 N p5
K p7 L
p3 p6
p4
Antes de la guerra
p1 N p5
K p7 L
p3 p6
Después de la guerra
p1 N p5
K p7 L
p3 p6
Un camino Euleriano
Grafos. Un souvenir
Grafos. Un souvenir
Grafos. Un souvenir
2 Grafos
Caminos más cortos en grafos: Dijkstra
Árboles de recubrimiento mínimo
El algoritmo de Prim
El algoritmo de Kruskal
3 Ejercicios propuestos
6 2 15 3
2 4
3 6
3
2 1
3
5
1 1
6 2 15 3 6 2 ∞ 15 3
2 4 2 4
3 6
3 3
2 1
3
5 5
6 6
1 1
6 2 15 3 6 2 ∞ 15 3
2 4 2 4
3 6 3
3 3
2 1 2
3
5 5
6 6
1 1
6 2 15 3 4 2 5 15 3
2 4 2 4
3 6
3 3
2 1
3
5 5
6 6
1 1
6 2 15 3 4 2 5 15 3
2 4 2 4
3 6
3 3
2 1 1
3
5 5
6 6
1 1
6 2 15 3 4 2 5 4 3
2 4 2 4
3 6
3 3
2 1
3
5 5
6 6
1 1
6 2 15 3 4 2 5 4 3
2 4 2 4
3 6
3 3
2 1
3
5 5
6 6
1 1
6 2 15 3 4 2 5 4 3
2 4 2 4
3 6
3 3
2 1
3 3
5 5
1 1
6 6
1 1
6 2 15 3 4 2 5 4 3
2 4 2 4
3 6
3 3
2 1
3
5 5
6 6
1 1
6 2 15 3 4 2 5 4 3
2 4 2 4
3 6 6
3 3
2 1
3
5 5
6 6
1 1
6 2 15 3 4 2 5 4 3
2 4 2 4
3 6
3 3
2 1
3
5 5
6 6
6 2 15 3
2 4
3 6
3
2 1
3
5
1 1
6 2 15 3 6 2 ∞ 15 3
2 4 2 4
3 6
3 3
2 1
3
5 5
6 6
1 1
6 2 15 3 6 2 ∞ 15 3
2 4 2 4
3 6 3
3 3
2 1 2
3
5 5
6 6
1 1
6 2 15 3 2 15 3
2 4 2 4
3 6 3
3 3
2 1 2
3
5 5
6 6
1 1
6 2 15 3 2 15 3
2 4 2 4
3 6 3
3 3
2 1 2 1
3
5 5
6 6
1 1
6 2 15 3 2 3
2 4 2 4
3 6 3
3 3
2 1 2 1
3
5 5
6 6
1 1
6 2 15 3 2 3
2 4 2 4
3 6 3
3 3
2 1 2 1
3
5 5
6 6
1 1
6 2 15 3 2 3
2 4 2 4
3 6 3
3 3
2 1 2 1
3 3
5 5
1 1
6 6
1 1
6 2 15 3 2 3
2 4 2 4
3 6 3
3 3
2 1 2 1
3
5 5
6 6
1 1
6 2 15 3 2 3
2 4 2 4
3 6 3 6
3 3
2 1 2 1
3
5 5
6 6
1 1
6 2 15 3 2 3
2 4 2 4
3 6 3
3 3
2 1 2 1
3
5 5
6 6
Asumimos que tenemos una clase grafo con los métodos InicializarGrafo,
que crea un grafo vacío, AgregarVertice, AgregarArista y ELiminarArista,
que hacen exactamente lo que anuncian.
Asumimos que tenemos una clase grafo con los métodos InicializarGrafo,
que crea un grafo vacío, AgregarVertice, AgregarArista y ELiminarArista,
que hacen exactamente lo que anuncian.
Asumimos además un método Vecindario que, para un nodo v , devuelve
el conjunto de todos los nodos adyacentes de v en G. Es decir, los nodos
w tales que existe una arista de v a w (los vecinos de v .) Observe que
aquí nos estamos tomando libertades con el tipo de datos abstracto que
habíamos visto en Programación II.
Asumimos que tenemos una clase grafo con los métodos InicializarGrafo,
que crea un grafo vacío, AgregarVertice, AgregarArista y ELiminarArista,
que hacen exactamente lo que anuncian.
Asumimos además un método Vecindario que, para un nodo v , devuelve
el conjunto de todos los nodos adyacentes de v en G. Es decir, los nodos
w tales que existe una arista de v a w (los vecinos de v .) Observe que
aquí nos estamos tomando libertades con el tipo de datos abstracto que
habíamos visto en Programación II.
Tenemos además los métodos del tipo de datos abstracto Conjunto tal
como se lo vio en Programación II ¿recuerdan?
Asumimos que tenemos una clase grafo con los métodos InicializarGrafo,
que crea un grafo vacío, AgregarVertice, AgregarArista y ELiminarArista,
que hacen exactamente lo que anuncian.
Asumimos además un método Vecindario que, para un nodo v , devuelve
el conjunto de todos los nodos adyacentes de v en G. Es decir, los nodos
w tales que existe una arista de v a w (los vecinos de v .) Observe que
aquí nos estamos tomando libertades con el tipo de datos abstracto que
habíamos visto en Programación II.
Tenemos además los métodos del tipo de datos abstracto Conjunto tal
como se lo vio en Programación II ¿recuerdan?
Finalmente, asumimos la existencia de una operación de resta de
conjuntos con el operador \ y CopiarConjunto.
Θ(n) 1.
2.
algoritmo Dijkstra (G : GrafoTDA, v : int)
Visitados = {v }
3. Dijkstra.InicializarGrafo()
4. foreach w ∈ G.vertices {
Θ(n) 5. Dijkstra.AgregarVertice(w )
6. }
7. foreach w ∈ G.Vecindario(v ) {
Θ(n) 8. Dijkstra.AgregarArista(v , w , G.Peso(v , w ))
9. }
10. Candidatos.InicializarConjunto()
11. Candidatos = G.vertices\Visitados
Θ(n) 1.
2.
algoritmo Dijkstra (G : GrafoTDA, v : int)
Visitados = {v }
3. Dijkstra.InicializarGrafo()
4. foreach w ∈ G.vertices {
Θ(n) 5. Dijkstra.AgregarVertice(w )
6. }
7. foreach w ∈ G.Vecindario(v ) {
Θ(n) 8. Dijkstra.AgregarArista(v , w , G.Peso(v , w ))
9. }
10. Candidatos.InicializarConjunto()
11. Candidatos = G.vertices\Visitados
2 Grafos
Caminos más cortos en grafos: Dijkstra
Árboles de recubrimiento mínimo
El algoritmo de Prim
El algoritmo de Kruskal
3 Ejercicios propuestos
e
9 6
f 2 11 d
c
14 9
10 15
a 1
b
2 Grafos
Caminos más cortos en grafos: Dijkstra
Árboles de recubrimiento mínimo
El algoritmo de Prim
El algoritmo de Kruskal
3 Ejercicios propuestos
7 d 5
e 4 9 3 c
8 2
g 3
7
f 1 b
5 a 4
7 d 5 7 d 5
e 4 9 3 c e 4 9 3 c
8 2
g 3 8 2
g 3
7 7
f 1 b f 1 b
5 a 4 5 a 4
visitados candidatos
∅ {a, b, c, d, e, f , g}
7 d 5 7 d 5
e 4 9 3 c e 4 9 3 c
8 2
g 3 8 2
g 3
7 7
f 1 b f 1 b
5 a 4 5 a 4
visitados candidatos
{d} {a,b,c,e,f ,g}
7 d 5 7 d 5
e 4 9 3 c e 4 9 3 c
8 2
g 3 8 2
g 3
7 7
f 1 b f 1 b
5 a 4 5 a 4
visitados candidatos
{c,d} {a,b,e,f ,g}
7 d 5 7 d 5
e 4 9 3 c e 4 9 3 c
8 2
g 3 8 2
g 3
7 7
f 1 b f 1 b
5 a 4 5 a 4
visitados candidatos
{b,c,d} {a,e,f ,g}
7 d 5 7 d 5
e 4 9 3 c e 4 9
3 c
8 2
g 3 8 2
g 3
7 7
f 1 b f 1 b
5 a 4 5 a 4
visitados candidatos
{b,c,d,g} {a,e,f }
7 d 5 7 d 5
e 4 9 3 c e 4 9
3 c
8 2
g 3 8 2
g 3
7 7
f 1 b f 1 b
5 a 4 5 a 4
visitados candidatos
{a,b,c,d,g} {e,f }
7 d 5 7 d 5
e 4 9 3 c e 4 9
3 c
8 2
g 3 8 2
g 3
7 7
f 1 b f 1 b
5 a 4 5 a 4
visitados candidatos
{a,b,c,d,f ,g} {e}
7 d 5 7 d 5
e 4 9 3 c e 4 9
3 c
8 2
g 3 8 2
g 3
7 7
f 1 b f 1 b
5 a 4 5 a 4
visitados candidatos
{a,b,c,d,e,f ,g} {}
El algoritmo de Prim
2 Grafos
Caminos más cortos en grafos: Dijkstra
Árboles de recubrimiento mínimo
El algoritmo de Prim
El algoritmo de Kruskal
3 Ejercicios propuestos
7 d 5
e 4 9 3 c
8 2
g 3
7
f 1 b
5 a 4
(a,g):1
(f ,g):2
(b,c):3
7 d 5 d
(c,g):3
(a,b):4 e 4 9 3 c e c
(e,g):4 8 g 3 g
2
(a,f ):5 7
(c,d):5 f 1 b f b
(a,c):7 5 a 4 a
(d,e):7
(e,f ):8
(d,g):9
X (a,g):1
(f ,g):2
(b,c):3
7 d 5 d
(c,g):3
(a,b):4 e 4 9 3 c e c
(e,g):4 8 g 3 g
2
(a,f ):5 7
(c,d):5 f 1 b f 1 b
(a,c):7 5 a 4 a
(d,e):7
(e,f ):8
(d,g):9
X (a,g):1
X (f ,g):2
(b,c):3
7 d 5 d
(c,g):3
(a,b):4 e 4 9 3 c e c
(e,g):4 8 g 3 g
2 2
(a,f ):5 7
(c,d):5 f 1 b f 1 b
(a,c):7 5 a 4 a
(d,e):7
(e,f ):8
(d,g):9
X (a,g):1
X (f ,g):2
X (b,c):3 7 d 5 d
(c,g):3
(a,b):4 e 4 9 3 c e c
(e,g):4 8 g 3 g 3
2 2
(a,f ):5 7
(c,d):5 f 1 b f 1 b
(a,c):7 5 a 4 a
(d,e):7
(e,f ):8
(d,g):9
X (a,g):1
X (f ,g):2
X (b,c):3 7 d 5 d
X (c,g):3
(a,b):4 e 4 9 3 c e 3 c
(e,g):4 8 g 3 g 3
2 2
(a,f ):5 7
(c,d):5 f 1 b f 1 b
(a,c):7 5 a 4 a
(d,e):7
(e,f ):8
(d,g):9
X (a,g):1
X (f ,g):2
X (b,c):3 7 d 5 d
X (c,g):3
7 (a,b):4 e 4 9 3 c e 3 c
(e,g):4 8 g 3 g 3
2 2
(a,f ):5 7
(c,d):5 f 1 b f 1 b
(a,c):7 5 a 4 a
(d,e):7
(e,f ):8
(d,g):9
X (a,g):1
X (f ,g):2
X (b,c):3 7 d 5 d
X (c,g):3
7 (a,b):4 e 4 9 3 c e 4 3 c
X (e,g):4 8 2
g 3 2
g 3
(a,f ):5 7
(c,d):5 f 1 b f 1 b
(a,c):7 5 a 4 a
(d,e):7
(e,f ):8
(d,g):9
X (a,g):1
X (f ,g):2
X (b,c):3 7 d 5 d
X (c,g):3
7 (a,b):4 e 4 9 3 c e 4 3 c
X (e,g):4 8 2
g 3 2
g 3
7 (a,f ):5 7
(c,d):5 f 1 b f 1 b
(a,c):7 5 a 4 a
(d,e):7
(e,f ):8
(d,g):9
X (a,g):1
X (f ,g):2
X (b,c):3 7 d 5 d 5
X (c,g):3
7 (a,b):4 e 4 9 3 c e 4 3 c
X (e,g):4 8 2
g 3 2
g 3
7 (a,f ):5 7
X (c,d):5 f 1 b f 1 b
(a,c):7 5 a 4 a
(d,e):7
(e,f ):8
(d,g):9
El algoritmo de Kruskal
1. Algoritmo Kruskal
2. input: grafo G = (V , E )
3. output T : Conjunto Devuelve el conjunto de aristas del árbol
4. T .InicializarConjunto()
5. Q.InicializarCola() // Cola de prioridad para las aristas
6. Q =E // Las claves son los pesos; O(|E |e log |E |)
7. n = V .length
8. foreach v ∈ V {
9. inicializar un Conjunto {v } // Los árboles de un elemento
10. }
11. repeat until (T .length = n − 1) // El ciclo greedy
12. (u, v ) = Q.Primero() // El candidato de menor costo
13. uset = buscar (u) // ID de u
14. vset = buscar (v ) // ID de v
15. if (uset 6= vset) // La arista une árboles separados
16. combinar (uset, vset)
17. T = T ∪ {(u, v )}
18. }
19. }
20. return T
1. Algoritmo Kruskal
2. input: grafo G = (V , E )
3. output T : Conjunto
4. T .InicializarConjunto()
5. Q.InicializarCola()
6. Q =E
7. n = V .length
8. foreach v ∈ V {
9. inicializar un Conjunto {v }
10. }
11. repeat until (T .length = n − 1)
12. (u, v ) = Q.Primero()
13. uset = buscar (u)
14. vset = buscar (v )
15. if (uset 6= vset)
16. combinar (uset, vset)
17. T = T ∪ {(u, v )}
18. }
19. }
20. return T
1. Algoritmo Kruskal
2. input: grafo G = (V , E )
3. output T : Conjunto
4. T .InicializarConjunto()
5. Q.InicializarCola()
Θ(|E | log |E |) 6. Q =E
7. n = V .length
Θ(n) 8. foreach v ∈ V {
9. inicializar un Conjunto {v }
10. }
11. repeat until (T .length = n − 1)
Θ(n) 12. (u, v ) = Q.Primero()
13. uset = buscar (u)
14. vset = buscar (v )
15. if (uset 6= vset)
16. combinar (uset, vset)
17. T = T ∪ {(u, v )}
18. }
19. }
20. return T
1. Algoritmo Kruskal
2. input: grafo G = (V , E )
3. output T : Conjunto
4. T .InicializarConjunto()
5. Q.InicializarCola()
Θ(|E | log |E |) 6. Q =E
7. n = V .length
Θ(n) 8. foreach v ∈ V {
9. inicializar un Conjunto {v }
10. }
11. repeat until (T .length = n − 1)
Θ(n) 12. (u, v ) = Q.Primero()
13. uset = buscar (u)
14. vset = buscar (v )
15. if (uset 6= vset)
16. combinar (uset, vset)
17. T = T ∪ {(u, v )}
18. }
19. }
20. return T
n o
Θ(|V |2 )(conexión fuerte) ⇒ Θ(log |E |) = 2Θ(log |V |) = Θ(log |V |)
Θ(e) = Θ(|E | log |V |)
Θ(|V |)(árboles) ⇒ Θ(log |E |) = Θ(log n)
Tenemos una complejidad O(n2 ) para Prim y una complejidad O(a log n)
para Kruskal, donde a es el número de aristas.
Tenemos una complejidad O(n2 ) para Prim y una complejidad O(a log n)
para Kruskal, donde a es el número de aristas.
Un grafo conectado oscila entre n − 1 aristas (si es un árbol) y n(n − 1)/2
aristas (si se trata de un grafo fuertemente conectado).
Tenemos una complejidad O(n2 ) para Prim y una complejidad O(a log n)
para Kruskal, donde a es el número de aristas.
Un grafo conectado oscila entre n − 1 aristas (si es un árbol) y n(n − 1)/2
aristas (si se trata de un grafo fuertemente conectado).
Tenemos entonces dos casos límite para Kruskal: O(n log n) (baja
conectividad) y O(n2 log n) (alta conectividad).
Tenemos una complejidad O(n2 ) para Prim y una complejidad O(a log n)
para Kruskal, donde a es el número de aristas.
Un grafo conectado oscila entre n − 1 aristas (si es un árbol) y n(n − 1)/2
aristas (si se trata de un grafo fuertemente conectado).
Tenemos entonces dos casos límite para Kruskal: O(n log n) (baja
conectividad) y O(n2 log n) (alta conectividad).
Dependiendo del tipo de grafo, uno de los dos algoritmos será entonces
más adecuado.
Ejercicios propuestos 1
Ejercicios propuestos 2
3 La propiedad de ciclo: Suponga que G es un grafo no dirigido con pesos.
Suponga que el grafo tiene por lo menos un ciclo y elija alguno. Para ese
ciclo, supongamos que hay una arista e cuyo peso es estrictamente mayor
que el de todas las otras aristas del ciclo. Observe que una arista así no
necesariamente existe, pero supondremos que en este caso sí. Muestre
que e no aparece en ningún árbol de recubrimiento mínimo de G.
4 Pruebe que si un grafo no dirigido con pesos es tal que los pesos son
todos diferentes, entonces su árbol de recubrimiento mínimo es único.
Ayuda: la propiedad de corte dice que, si una arista es la de menor costo
entre dos particiones de los vértices de un grafo, entonces esta arista debe
estar en todos los árboles de recubrimieno mínimo del grafo.
5 Considere el problema de calcular un árbol de recubrimiento máximo, es
decir, un árbol de recubrimiento que maximice la suma de los costos de
las aristas. ¿Pueden los algoritmos de Prim y Kruskal ayudarnos a
solucionar este problema (asumiendo por supuesto que elegimos la arista
de cruce de costo máximo)?
Ejercicios propuestos 3
6 Queremos encontrar el costo mínimo entre dos vértices a y b de un grafo
G y nos dan el árbol de recubrimiento mínimo de este grafo. Entonces
tomamos este árbol derecubrimiento mínimo y seguimos el camino desde
a hasta b sumando los costos de cada arista.
¿Es la respuesta que da este procedimiento correcta?
7 Usted trabaja para una compañía aérea que conecta varias ciudades de la
provincia de Córdoba. Cada aeropuerto cobra una tarifa para su uso; esta
tarifa debe pagarse cuando el avión llega y cuando parte. Usted calculó
las conexiones de costo mínimo utilizando el algoritmo de Dijkstra.
Sucede que ahora, ante la proximidad de las elecciones, los intendentes de
las ciudades tienen una gran necesidad de dinero. Por lo tanto, proponen
incrementar las tarifas de los aeropuertos un 20 %.
La CEO de su compañía le dice que, dado que todas las tarifas se
incrementan en el mismo porcentaje, es innecesario recalcular el algoritmo
de Dijkstra; los trayectos de costo mínimo van a seguir siendo los mismos,
según ella.
¿Está la CEO en lo cierto?
Ricardo Wehbe Programación III - Clase 05
Repaso de la clase anterior
Grafos
Ejercicios propuestos
Ejercicios propuestos 4
8 Considere el grafo siguiente.
3
1 4
3 2 1
1
s 1 3 2 6
3
4 3
2 5
1