Modulo II Algoritmo de Grafos Andres Perdomo CI 28164082
Modulo II Algoritmo de Grafos Andres Perdomo CI 28164082
Modulo II Algoritmo de Grafos Andres Perdomo CI 28164082
Autor:
Br. Perdomo, Andrés C.I. 28.164.082
Sección: M01
INTRODUCCION
Contenido
1. Recorrido en grafos.
a. Modelo general de etiquetamiento:
b. Algoritmo de Búsqueda en Profundidad (DFS) y Búsqueda en
Amplitud (BSF).
c. Aplicaciones.
3. Grafos de precedencia.
a. Partición en Niveles, Ordenamiento Topológico,
b. PERT.
4. Caminos de longitud k.
El algoritmo de recorrido de grafos consiste básicamente en visitar un nodo del grafo y luego
ir visitando los nodos conectados a este. Este principio se aplica recursivamente comenzando
desde un nodo inicial cualquiera del grafo.
Lo que diferencia un algoritmo de recorrido de otro es, una vez ubicado en un nodo en
particular, la forma en que se visitan los nodos conectados a este. Por supuesto, estos
algoritmos pueden ser aplicados en grafos dirigidos o no dirigidos.
Los etiquetamientos de grafos han sido una herramienta poderosa en el estudio de las
propiedades de grafos y sus aplicaciones. Algunos ejemplos de etiquetamiento son los
coloramiento de los vértices y aristas, flujos, etiquetamientos elegantes, etc. Los grafos
etiquetamiento han servido como modelo para una variada cantidad de aplicaciones como:
flujos en redes, teoría de códigos, cristalografía con rayos-x, radares, astronomía, diseño de
circuitos. Comunicación en redes, manejo de base de datos. etc.
Podemos decir que hay dos tipos de etiquetados garbosos, el garboso y el garboso "perfecto":
5
Etiquetado Garboso
Dado un grafo con n vértices y q aristas, un etiquetado garboso sería aquel en el que se
etiqueta a las aristas con los números comprendidos entre 1 y q y los vértices con los números
comprendidos entre 0 y q y se tiene que cumplir que las diferencias de las etiquetas de los
vértices que delimitan cada arista es el mismo valor de la etiqueta de la arista.
Dado un grafo con n vértices y q aristas, un etiquetado garboso perfecto sería aquel en el que
se etiqueta a las aristas con los números comprendidos entre 1 y q y los vértices con los
números comprendidos entre 1 y n y se tiene que cumplir que las diferencias Etiquetado
Garboso Perfecto
Dado un grafo con n vértices y q aristas, un etiquetado garboso perfecto sería aquel en el que
se etiqueta a las aristas con los números comprendidos entre 1 y q y los vértices con los
números comprendidos entre 1 y n y se tiene que cumplir que las diferencias de las etiquetas
de los vértices que delimitan cada arista es el mismo valor de la etiqueta de la arista.
6
de las etiquetas de los vértices que delimitan cada arista es el mismo valor de la etiqueta de
la arista.
Para efectuar un recorrido en profundidad de un grafo (DFS por sus siglas en inglés), se
selecciona cualquier nodo como punto de partida (por lo general el primer nodo del grafo) y
se marcan todos los nodos del grafo como “no visitados”. El nodo inicial se marca como
“visitado” y si hay un nodo adyacente a este que no haya sido “visitado”, se toma este nodo
7
como nuevo punto de partida del recorrido. El recorrido culmina cuando todos los nodos
hayan sido visitados.
Se dice que el recorrido es en profundidad, porque para visitar otro nodo adyacente del nodo
inicial, primero se deben visitar TODOS los nodos adyacentes al que se eligió antes. Es así,
como el número de ambientes recursivos varía dependiendo de la profundidad que alcance
el algoritmo.
Este algoritmo recorre todos los nodos del grafo, pero fácilmente puede modificarse para que
sea una función que encuentre un nodo en particular dentro de grafo. Este algoritmo se
conoce como el algoritmo DFS (Depth-First Search).
Una bondad de este algoritmo es que los nodos solo se vistan una vez. Esto implica que si se
salvan en alguna estructura las aristas que se van recorriendo se obtiene un conjunto de aristas
de cubrimiento mínimo del grafo, lo cual se utiliza frecuentemente se utiliza para reducir la
complejidad del grafo cuando la perdida de información de algunas aristas no es importante.
Este resultado se conoce como árbol DFS (DFS Tree).
El algoritmo de recorrido en profundidad tiene orden O (máx. (A, N)) donde N es el número
de nodos y A es el número de aristas. Esto es porque un grafo de N nodos puede tener más
de N aristas, en cuyo caso se ejecutan más de N ciclos en DFS_R, pero si por el contrario hay
menos aristas que nodos, de cualquier manera, se visitaran todos los nodos en DFS.
El DFS puede modificarse fácilmente y utilizarse para resolver problemas sencillos como los
de conectividad simple, detección de ciclos y camino simple. Por ejemplo, el número de
veces que se invoca a la acción DFS_R desde la acción DFS en el algoritmo anterior es
exactamente el número de componentes conexas del grafo, lo cual representa la solución al
problema de conectividad simple.
9
En este algoritmo también se utiliza la estrategia de marcas los nodos como “visitados” para
detectar la culminación del recorrido, pero los nodos se recorren de una manera ligeramente
distinta.
De nuevo, se selecciona cualquier nodo como punto de partida (por lo general el primer nodo
del grafo) y se marcan todos los nodos del grafo como “no visitados”. El nodo inicial se
marca como “visitado” y luego se visitan TODOS los nodos adyacentes a este, al finalizar
este proceso se busca visitar nodos más lejanos visitando los nodos adyacentes a los nodos
adyacentes del nodo inicial.
Este algoritmo puede crear menos ambientes recursivos que el anterior porque visita más
nodos en un mismo ambiente, pero esto depende de cómo este construido el grafo. El
algoritmo se conoce como el algoritmo de BFS (Breadth-First Search).
Este algoritmo tiene exactamente el mismo orden en tiempo de ejecución del algoritmo de
recorrido en profundidad y también se puede obtener el conjunto de aristas de cubrimiento
mínimo del grafo.
Una diferencia notable entre el DFS y el BFS es que este último necesita de una estructura
auxiliar, que por lo general es una cola, para el almacenamiento de las aristas que se van a
visitar durante el recorrido.
El siguiente ejemplo ilustra el funcionamiento del algoritmo BFS sobre un grafo de ejemplo.
La secuencia de ilustraciones va de izquierda a derecha y de arriba hacia abajo
10
Comenzamos introduciendo a la cola C todas las aristas adyacentes al nodo inicial (el nodo
0). Luego, extraemos la arista 0-2 de la cola y procesamos las aristas adyacentes a 2, la 0-2 y
la 2-6. No colocamos la arista 0-2 en la cola porque el vértice 0 ya fue visitado.
Luego, extraemos la arista 0-5 de la cola y procesamos las aristas adyacentes a 5. De manera
similar a la anterior, no se toma en cuenta la arista 0-5, pero si se encolan las aristas 5-3 y 5-
4. Seguidamente, extraemos la arista 0-7 y encolamos la arista 7-1. La arista 7-4 está impresa
en color gris porque si bien es un enlace adyacente a 7, podríamos evitar encolarla debido a
que ya existe una arista en la cola que nos lleva hasta el nodo 4.
Para completar el recorrido, tomamos las aristas que quedan en la cola, ignorando aquellas
que están impresas en color gris cuando queden de primeras en la cola. Las aristas entran y
salen de la cola en el orden de su distancia del vértice 0.
Al igual que en el DFS, usando el BFS se puede obtener un conjunto de aristas de cubrimiento
mínimo del grafo, conocido como el árbol (BFS Tree).
11
También puede modificarse fácilmente y utilizarse para resolver problemas sencillos como
los de conectividad simple, detección de ciclos y camino simple.
El BFS es el algoritmo clásico para encontrar el camino más corto entre dos nodos específicos
en un grafo, mientras que DFS nos ofrece muy poca ayuda para esta tarea debido a que el
orden en el que se visitan los nodos no tiene absolutamente ninguna relación con la longitud
de los caminos.
d.- APLICACIONES
Aplicación BFS y DFS
Se tienen dos sapos en la esquina derecha y dos ranas en la esquina izquierda con un espacio
intermedio que los separa, el objetivo es que los sapos queden en la esquina izquierda y las
ranas en la esquina derecha, las reglas son que solo se pueden mover hacia adelante y pueden
pasar una sobre la otra.
Para la resolución de este problema, se utilizan dos algoritmos Búsqueda en anchura (BFS)
y Búsqueda en profundidad (DFS).
Se modela el árbol que representa las posibles soluciones y se enumeran los nodos teniendo
en cuenta el algoritmo de Búsqueda en profundidad.
a) GRAFOS CONEXOS Un grafo es conexo si cada par de vértices está conectado por un
camino; es decir, si para cualquier par de vértices (a, b), existe al menos un camino
posible desde a hacia b. Un grafo es doblemente conexo si cada par de vértices está
conectado por al menos dos caminos disjuntos; es decir, es conexo y no existe un vértice
tal que al sacarlo el grafo resultante sea disconexo.
Es sencillo desarrollar una solución de fuerza bruta para este problema. Solo se debe
comprobar para cada par de nodos u y v, si u es alcanzable desde v y viceversa. Sin embargo,
se puede utilizar el DFS para determinar con eficiencia las componentes fuertemente conexas
de una dígrafo.
· Método de Kosaraju
El método de Kosaraju es simple de explicar y de implementar. Sea G un dígrafo, a
continuación, se presenta una descripción del algoritmo de Kosaraju, a saber:
15
- Se ejecuta un DFS y se construye un dígrafo nuevo Gr, invirtiendo las direcciones de todos
los arcos de G. Esto es, se permutan los nodos del grafo en el orden definido por el recorrido
en post orden del mismo (para un dígrafo acíclico este proceso es equivalente a un
ordenamiento topológico)
. Se deben enumerar los nodos en el orden de terminación de las llamadas recursivas del DFS.
- Luego se ejecuta un DFS en Gr, partiendo del nodo con numeración más alta de acuerdo
con la numeración asignada en el paso anterior. Si el DFS no llega a todos los nodos, se inicia
la siguiente búsqueda a partir del nodo restante con numeración más alta.
- Cada árbol del conjunto de árboles DFS resultante es una componente fuertemente conexa
de G.
Se puede observar que en Gr las aristas estas invertidas. Los números que pueden verse a los
lados de los nodos son los asignados durante la terminación de las llamadas del DFS, donde
el nodo A fue el nodo inicial. La modificación del algoritmo original de DFS para lograr esta
numeración es sumamente sencilla.
Un grafo de precedencia es un grafo dirigido sin circuitos. Muchas son las aplicaciones
donde encontramos grafos de precedencia. El concepto de orden entre los elementos de un
conjunto aparece con frecuencia en Computación.
(1) Podemos representar una expresión aritmética:
((a+b)*c + ((a+b)+e) * (e+f)) * ((a+b) * c)
(2) El grafo reducido de un grafo dirigido
(3) El grafo de una relación de orden parcial (eliminando los bucles).
(4) El grafo que representa un proceso de decisión secuencial como el de la figura V.6.
(5) Planificación de proyectos: un proyecto se puede dividir en actividades que deben
realizarse en un cierto orden. Tal es el caso de un pensum de estudios de una carrera
universitaria, donde ciertas materias son requisitos de otras. En este caso podemos
representar las materias por vértices de un grafo donde los arcos son los requisitos inmediatos
entre materias.
PROPIEDADES
Empezamos por dar dos propiedades sencillas pero importantes de grafos sin circuitos:
(a) Un grafo G no posee circuitos si y sólo sí todo subgrafo de G no posee circuitos.
(b) Principio de dualidad de grafos sin circuitos: Un grafo G no posee circuitos si y sólo si el
grafo inverso de G, G-1, obtenido a partir de G invirtiendo la orientación de todos los arcos,
no posee circuitos.
El estudio de grafos sin circuitos se fundamenta esencialmente en las propiedades siguientes:
Proposición
Sea G un dígrafo sin bucles. G no posee circuitos si y sólo si toda componente fuertemente
conexa es un vértice aislado.
Demostración:
Al haber una componente fuertemente conexa con más de un vértice es evidente que habrá
un circuito. Recíprocamente, si G posee un circuito, éste estará en una componente
fuertemente conexa.
Proposición
18
Un vértice fuente de un dígrafo es un vértice con grado interior igual a cero, es decir, el
vértice es extremo inicial de todos los arcos incidentes en él. Un vértice sumidero es un
vértice con grado exterior igual a cero, es decir, el vértice es extremo terminal de todo arco
incidente en él.
Proposición
Todo grafo de precedencia G contiene un vértice fuente y un vértice sumidero.
Demostración:
Supongamos que G no contiene un vértice fuente. Entonces d-(G)³1 y la proposición nos dice
que G posee un circuito.
Por otro lado, si G es de precedencia, entonces el grafo inverso de G, G-1, es de precedencia
y por lo tanto G-1 posee una fuente, la cual es sumidero de G.
a. PARTICIÓN EN NIVELES
El problema de dividir un grafo es diversas particiones del mismo tamaño tiene muchas
utilidades en el área de la electrónica, así como en el desarrollo de sistemas operativos.
Este problema ha sido demostrado como un problema NP-difícil, lo que implica que
soluciones para él no pueden ser encontradas en tiempos razonables. El particionamiento
de grafos es un problema importante que tiene aplicaciones extensas en muchas áreas,
incluida la informática científica, el diseño de VLSI y la programación de tareas.
La clase P describe el conjunto de todos los problemas de decisión que se pueden resolver a
tiempo.
b. ORDENAMIENTO TOPOLÓGICO
Hay dos maneras naturales de definir esta operación básica, aunque son esencialmente la
misma, a saber:
– Reetiquetado: Dado un DAG, reetiquetar sus nodos de tal forma que cada arista dirigida
vaya de un nodo con un identificador bajo en numero a un nodo con un identificador cuyo
identificador sea mayor.
– Reposicionado: Dado un DAG, reposicionar sus nodos en una línea horizontal de tal forma
de que todas sus aristas dirigidas apunte de izquierda a derecha.
OBSERVACIÓN
Los dígrafos son usados generalmente en aplicaciones para indicar la precedencia de eventos,
el ordenamiento topológico devuelve la posible secuencia válida en la deben realizarse dichos
eventos.
Gráficamente se trata de poner todos los nodos en una línea de manera que sólo haya arcos
hacia adelante.
Una forma de encontrar un ordenamiento topológico es examinando todos los nodos del
dígrafo y aquellos nodos que no tengan aristas incidentes sobre ellos son eliminados del grafo
e introducidos en una cola (o lista), se repite este proceso hasta que no queden nodos en el
grafo.
Escogemos el vértice 1, lo eliminamos del grafo. (al eliminar este vértice, se eliminan todos
los lados que salen de él)
2) Del grafo resultante, se escoge un vértice que no tenga lados incidentes en él, se quita del
grafo y se coloca en la cola. Escogemos el vértice 3, La cola es 1 3
3) Del grafo resultante, se escoge un vértice que no tenga lados incidentes en él, se quita del
grafo y se coloca en la cola 2, La cola es 1 3 2
22
Ahora sólo quedan los vértices 4, 5 de los cuales se escoge el vértice 4 ya que no tiene lados
incidentes en él y se coloca en la cola. Finalmente, el orden topológico queda: 1 3 2
c. PERT.
El grafo PERT se utiliza para calcular la duración del proyecto y para evaluar la importancia
de las diferentes tareas: Tiempo "early" = tiempo mínimo necesario para alcanzar un nudo.
Tiempo "last" = tiempo máximo que podemos tardar en alcanzar un nudo sin que el proyecto
sufra un retraso.
El método el PERT es un instrumento de programación temporal y toda programación
temporal requiere:
1 - Relacionar el conjunto de actividades que se ha de realizar.
2 - Estimar el tiempo que requiere cada una de ellas.
3 - Determinar el orden en el que han de realizarse las actividades, es decir, determinar las
precedencias existentes entre ellas.
Precisamente, una de las aportaciones del método es que obliga a identificar las actividades
que integran el proyecto, resaltando las dependencias y condicionamientos existentes entre
ellas, así como sus duraciones.
4.- CAMINOS DE LONGITUD K
En términos más formales, se dice que un camino de longitud k desde u hasta w en G = (V,
E) es una secuencia de vértices 〈 v0, v1, …, vn 〉tal que v0 = u y vn = w, y que para todos
los vértices desde v0 hasta vn todas las aristas sean de la forma (vi-1, vi) ∈ E. Si esa trayectoria
existe, se dice que w es alcanzable desde u por dicho camino.
5.- CAMINOS DE LONGITUD MÍNIMA
Todo camino en un dígrafo pesado tiene un peso asociado, el cual es la suma de los pesos de
las aristas del camino. Esta medida esencial nos permite formular problemas como el de
encontrar el camino con el menor peso entre dos vértices. El tópico de esta sección es el
cálculo de este tipo de camino, donde la longitud del camino no se mide en base al número
de aristas del mismo, sino en base al peso del camino.
Con esto último en mente, definiremos al camino más corto entre dos nodos de un dígrafo
pesado, como el camino dirigido que tenga la propiedad de tener el peso mínimo entre todos
los caminos que existan entre dicho par de nodos.
· Algoritmo de Dijkstra
El algoritmo de Dijkstra resuelve el problema de encontrar los caminos más cortos a partir
de un origen, en grafos pesados que no tengan pesos negativos.
todos los nodos, todos los caminos son “especiales”, así que D contendrá la distancia más
corta del origen a cada vértice. Se puede utilizar un arreglo P, para ir almacenando los
caminos más cortos.
Al final de la ejecución, cada posición del arreglo P contiene el nodo inmediato anterior a v
en el camino más corto a partir del nodo inicial. Dado el grafo:
nodo 5, por ejemplo, se siguen los predecesores en orden inverso comenzando en 5. Así, es
sencillo encontrar que el camino más corto del nodo 1 al 5, es el 1, 4, 3, 5.
Usando el arreglo P, o bien mediante alguna otra heurística, se puede construir fácilmente un
SPT, tomando el nodo inicial del recorrido como raíz del árbol y luego añadiendo una arista
y un nodo a la vez, siempre tomando la próxima arista que pertenezca al camino más corto a
un nodo que no esté en el SPT.
Aunque se puede ejecutar Dijkstra N veces para resolver el problema de caminos cortos entre
cada par de nodos, el Algoritmo de Floyd [5] también resuelve este problema, con una
complejidad en tiempo similar.
a. RUTA CRÍTICA
Cuando estás gestionando un proyecto complejo con muchas piezas en juego y plazos que
cambian constantemente, puede ser difícil entregar un producto a tiempo y dentro del
presupuesto. Hay una amplia gama de herramientas de gestión de proyectos que pueden
ayudarte a lograr estos objetivos, una de ellas es el método de la ruta crítica.
El método de la ruta crítica es una técnica de modelado de proyectos que puedes usar para
analizar, planificar y programar proyectos complejos. Básicamente, el método de la ruta
crítica le exige que enumere todas las actividades que deben terminarse para completar un
proyecto, el tiempo que llevará realizar cada actividad y las dependencias entre estas
27
El método de la ruta crítica fue desarrollado a fines de la década de 1950 por James E. Kelley
de Remington Rand y Morgan R. Walker de DuPont. Estaban intentando encontrar maneras
de reducir los costos asociados con los cierres y reinicios de plantas, causados por
programaciones ineficientes. Al garantizar que las tareas correctas se realizaran en los
tiempos adecuados, en lugar de simplemente saturar el problema con mano de obra adicional,
encontraron que se podían evitar los costos excesivos.
Si bien el interés de DuPont por el método de la ruta crítica había disminuido a principios de
la década del 60, algunas otras empresas comenzaron a usarlo para supervisar proyectos
grandes, incluidas Mauchly Associates y Catalytic Construction. Al principio, para usar el
método de la ruta crítica se necesitaba acceder a grandes computadoras centrales y
especializadas. Por este motivo, el costo de la gestión de proyectos con ruta crítica era un
obstáculo significativo para adoptar su uso. No obstante, después de la revolución de las
computadoras y las innovaciones en hardware/software informático que hicieron posible
realizar la gestión de programas en una computadora de escritorio estándar, el uso de la ruta
crítica se extendió mucho más
6.- ÁRBOL MÍNIMO DE EXPANSIÓN
Dado un grafo conexo, no dirigido G. Un árbol de expansión es un árbol compuesto por todos los
vértices y algunas (posiblemente todas) de las aristas de G. Al ser creado un árbol no existirán
ciclos, además debe existir una ruta entre cada par de vértices.
Un grafo puede tener muchos árboles de expansión, veamos un ejemplo con el siguiente
grafo:
En la imagen anterior se puede observar que el grafo dado posee 3 árboles de expansión,
dichos arboles cumplen con las propiedades antes mencionadas como son unir todos los
vértices usando algunas aristas.
Con un grafo conexo, no dirigido y con pesos en las aristas, un árbol de expansión mínima
es un árbol compuesto por todos los vértices y cuya suma de sus aristas es la de menor peso.
Al ejemplo anterior le agregamos pesos a sus aristas y obtenemos los arboles de expansiones
siguientes:
29
De la imagen anterior el árbol de expansión mínima sería el primer árbol de expansión cuyo
peso total es 6.
El problema de hallar el Árbol de Expansión Mínima (MST) puede ser resuelto con varios
algoritmos, los más conocidos con Prim y Kruskal ambos usan técnicas voraces (greedy).
Algoritmo de Kruskal
Para poder comprender el algoritmo de kruskal será necesario revisar primer el tutorial
de Union-Find.
Como trabaja:
Primeramente, ordenaremos las aristas del grafo por su peso de menor a mayor. Mediante la
técnica greedy Kruskal intentara unir cada arista siempre y cuando no se forme un ciclo, ello
se realizará mediante Union-Find. Como hemos ordenado las aristas por peso comenzaremos
con la arista de menor peso, si los vértices que contienen dicha arista no están en la misma
componente conexa entonces los unimos para formar una sola componente mediante Unión
(x , y), para revisar si están o no en la misma componente conexa usamos la función
30
SameComponent(x , y) al hacer esto estamos evitando que se creen ciclos y que la arista que
une dos vértices siempre sea la mínima posible.
Algoritmo en Pseudocódigo
1 método Kruskal(Grafo):
2 inicializamos MST como vacío
3 inicializamos estructura unión-find
4 ordenamos las aristas del grafo por peso de menor a mayor.
5 para cada arista e que une los vértices u y v
6 si u y v no están en la misma componente
7 agregamos la arista e al MST
8 realizamos la unión de las componentes de u y v
Como podemos ver en la imagen anterior la definición de nuestro grafo en código sería:
31
1
struct Edge{
2 int origen; //Vértice origen
3 int destino; //Vértice destino
4 int peso; //Peso entre el vértice origen y destino
5 Edge(){}
…
6 }arista[ MAX ]; //Arreglo de aristas para el uso en kruskal
7
Ahora el siguiente paso es ordenar las aristas del grafo en orden ascendente:
32
Para el ordenamiento podemos usar las librerías predefinidas de Java y C++ como estamos
ordenando estructuras necesitamos un comparador, en este caso estamos ordenando por peso
por lo tanto dentro de la estructura antes definida agregamos:
1 struct Edge{
2 …
3 //Comparador por peso, me servira al momento de ordenar lo realizara en orden ascendente
4 //Cambiar signo a > para obtener el arbol de expansion maxima
5 bool operator<( const Edge &e ) const {
6 return peso < e.peso;
7 }
8 }arista[ MAX ]; //Arreglo de aristas para el uso en kruskal
Ordenamos el arreglo de aristas mediante lo siguiente:
Lo siguiente será recorrer todas las aristas ya ordenadas y verificar si sus vértices están o no
en la misma componente.
En la imagen podemos observar que ambos vértices no están en la misma componente, por
tanto realizamos la Union( 6 , 7 ):
Realizamos la Union(1,2):
35
Al observar la
imagen los vértices 3 y 4 no están en la misma componente conexa por lo tanto realizamos
la Union(3,4) en el grafo:
37
Los vértices 8 y 9 están en la misma componente conexa por lo tanto no realizamos Unión
de vértices. Continuemos con la siguiente arista:
Los vértices 2
y 3 están en la misma componente conexa por lo tanto no realizamos Union de componentes.
Continuamos con la siguiente arista:
Como podemos observar ya están todos los vértices del grafo conectados así que al momento
de continuar viendo las demás aristas ordenadas siempre tendremos e l caso de que ya están
39
en la misma componente conexa por lo tanto el Árbol de Expansión Mínima para el grafo es
el siguiente:
El peso total del árbol de expansión mínima para el grafo mostrado es 39.
1 for( int i = 0 ; i < E ; ++i ){ //Recorremos las aristas ya ordenadas por peso
2 origen = arista[ i ].origen; //Vértice origen de la arista actual
3 destino = arista[ i ].destino; //Vértice destino de la arista actual
4 peso = arista[ i ].peso; //Peso de la arista actual
5 //Verificamos si estan o no en la misma componente conexa
6 if( !sameComponent( origen , destino ) ){ //Evito ciclos
7 total += peso; //Incremento el peso total del MST
8 MST[ numAristas++ ] = arista[ i ]; //Agrego al MST la arista actual
9 Union( origen , destino ); //Union de ambas componentes en una sola
10 }
11 }
Verificación de MST
Para que sea un MST válido el número de aristas debe ser igual al número de vértices – 1.
Esto se cumple debido a que el MST debe poseer todos los vértices del grafo ingresado y
además no deben existir ciclos. Si vemos el ejemplo antes explicado tenemos en el MST:
Número de Aristas = 8
Número de Vértices = 9
40
Cumple con lo dicho -> 9 – 1 = 8 por tanto tenemos un MST válido. Veamos otro ejemplo
teniendo como grafo ingresado lo siguiente:
Como podemos observar el grafo ingresado posee 2 componentes conexas, al aplicar kruskal
obtendremos los siguientes MST:
En la imagen podemos observar el MST luego de aplicar kruskal, sin embargo, no es un MST
válido porque no tiene 1 componente conexa que posea todos los vértices, comprobemos:
Número de Aristas = 7
Número de Vértices = 9
No cumple lo dicho inicialmente 9 – 1 ≠ 7 por lo tanto tenemos un MST invalido
CONCLUSION
Luego de realizar la investigación del contenido del Módulo II, podemos concluir que:
a) Que los Grafos son Abstracciones matemáticas muy útiles para la resolución de
problemas de ingeniería.
b) Que existen diversas técnicas para determinar la mejor ruta o la más eficiente, así
como la determinación de la ruta crítica, muy útil en el control de la ejecución de
proyectos de diversas índoles.
c) Que podemos utilizar diversos softwares en la implementación de los algoritmos para
el recorrido de Grafos y de grafos dirigidos, tales como Java, JavaScript y HTML,
Python etc.
REFERENCIAS BIBLIOGRAFICAS
1. http://fernandavia.blogspot.com/2018/08/aplicacion-bfs-y-dfs_26.html
2. https://jariasf.wordpress.com/2012/04/19/arbol-de-expansion-minima-
algoritmo-de-kruskal/
3. https://webs.um.es/pacovera/miwiki/lib/exe/fetch.php?id=inicio&cache=
cache&media=grafos.pdf.
4. https://www.editdiazdesantos.com/libros/marquez-garcia-alfonso-
miguel-guia-para-dibujar-los-grafos-pert-mas-complejos-sin-dificultad-
L30002200109.html.
5. https://compdiscretas.wordpress.com/2012/11/18/3-3-ordenamientos-
topologicos/
6. https://mathenki.wordpress.com/2018/06/07/problema-de-
particionamiento-de-grafos-algoritmos-heuristicos/
43
7. http://usandojava.blogspot.com/2012/02/escribiendo-y-leyendo-en-un-
archivo-
de.html#:~:text=Recorrido%20o%20b%C3%BAsqueda%20en%20profun
didad,manera%20ordenada%2C%20pero%20no%20uniforme.
8. http://usandojava.blogspot.com/2012/02/escribiendo-y-leyendo-en-un-
archivo-
de.html#:~:text=Recorrido%20o%20b%C3%BAsqueda%20en%20profun
didad,manera%20ordenada%2C%20pero%20no%20uniforme.