Está en la página 1de 32

UNIVERSIDAD NACIONAL MAYOR DE SAN MARCOS

FACULTAD DE ING. DE SISTEMAS E INFORMATICA


ESTRUCTURA DE DATOS. SEMESTRE: 2020-II
PROFESOR: ANA MARIA HUAYNA D.
TRABAJO DOMICILIARIO NRO 5
GRAFOS
Observación: En cada uno de los siguientes ejercicios especificar: Diagrama de
entrada/salida, Precondiciones y Postcondiciones, Explicación breve del algoritmo (3-4
líneas), Algoritmos (Pseudocódigos) y su respectivo dibujo. De los 6 problemas, escoger 5,
Tres para desarrollar y 2 en Pseudocódigo y el problema 5 en Java

1. (Desarrollo) Desarrolle los siguientes ejercicios:


a) Recorrido en Profundidad y amplitud de los 2 grafos siguientes:

SOLUCIÓN:
RECORRIDO EN PROFUNDIDAD
 GRAFO 1
Tomamos el nodo A, luego marcamos el nodo adyacente y repetimos el procedimiento
mientras que existan nodos adyacentes en el camino. Lo que obtendremos al final es el
recorrido y el árbol generado a partir de este.
 GRAFO 2
Se sigue el mismo procedimiento que se tomó en el grado anterior.

RECORRIDO EN AMPLITUD
 GRAFO 1
Este recorrido es equivalente al recorrido por niveles, la diferencia con el recorrido anterior es
que en este caso se utiliza una Cola. Se empieza por el nodo A, se encolan todos sus nodos
adyacentes, si ya no existen nodos adyacentes, entonces se desencola y se repite el proceso con
el primero de cola. Este proceso se repetirá mientras existan nodos en el grafo que no han sido
recorridos. Lo que obtendremos al final es el árbol generado y el recorrido.
 GRAFO 2
Se sigue el mismo procedimiento que en el GRAFO 1.

b) Halle la ordenación topológica de los 2 grafos siguientes:


Figura A Figura B
Solución:
Explicación del procedimiento.
Lo que se procede a hacer en cada iteración es:
1.- Marcar el nodo que tiene menos entradas.
2.- Eliminamos dicho nodo y sus aristas de salida.
3.- Actualizamos los grados de los vértices restantes.
4.- Si existen nodos en el grado, regresamos al Paso 1, si no, terminamos.

Figura A

Figura B
c) Son grafos isomorfos? Justifique su respuesta

Figura A

Figura B
Solución
Recordemos que:
Es decir, que para todo nodo en un grafo debe haber una correspondencia en el otro grafo.
Además, estos deben cumplir ciertos corolarios:
1.- Ambos grafos deben tener la misma cantidad de nodos.
2.- Ambos grafos deben tener la misma SUMA DE GRADOS DE TODOS LOS
VÉRTICES)
 FIGURA A: SÍ SON ISOMORFOS

Justificación:
Ambos grafos tienen la misma cantidad de vértices, así que se cumple la primera condición:
No. Vértices (G) = 4
No. Vértices (H) = 4
Además, ambos grafos poseen la misma suma de los grados:
G(G) = 8
G(H) = 8
Ahora establecemos la correspondencia: F(G) = H
F(u1) = v1
F(u2) = v2
F(u3) = v3
F(u4) = v4
Por lo tanto, concluimos que los grafos de la FIGURA A SON ISOMORFOS.
 FIGURA B: NO SON ISOMORFOS

Figura B
Justificación:
Ambos grafos tienen la misma cantidad de vértices, así que se cumple la primera condición:
No. Vértices (G) = 5
No. Vértices (H) = 5
Además, ambos grafos no poseen la misma suma de todos los vértices:
G(G) = 13
G(H) = 14
Como podemos observar, el grado de los grafos es distinto, así que no se cumple el segundo
corolario.
Por lo tanto, concluimos que los grafos de la FIGURA B NO SON ISOMORFOS.

2. (Pseudcódigo)

Implemente el grado del grafo dirigido representado mediante su matriz de adyacencias.

Solución
Diagrama de entrada y Salida:

Explicación:
Recordemos que:

Además, el grado de un vértice en un grafo dirigido es la suma de las aristas salientes y


entrantes.
Sea v un nodo del Grafo g, entonces:

grado(v) = Aristas salientes(v) + Aristas entrantes(v)

Entonces el algoritmo consiste en hallar la máxima suma de aristas de todos los vértices, el
cual será el grado del Grafo.
Dibujo:
Para entender el pseudocódigo, primero lo explicaré gráficamente el funcionamiento del
algoritmo.
Se tiene el siguiente grado dirigido.

Fuente: Elaboración propia


Con el cual se realizó la matriz de adyacencia del grado dirigido. En la matriz podremos notar
que las filas representan a las aristas salientes del vértice; y las columnas, a las aristas entrantes
de los vértices.

Fuente: Elaboración propia


Lo que hará primero el algoritmo es sumar las aristas de salida de cada nodo. Así
obtendremos:

Fuente: Elaboración propia

Luego se suma las aristas de entrada, obteniendo.

Fuente: Elaboración propia

Sumando las aristas entrantes y las salientes obtenemos el grado total de cada vértice.

Fuente: Elaboración propia

El máximo grado es 3 del vértice 0, entonces el grado del grafo es 3.


Función Grado_Grafo (Entero Matriz [N][N], Entero Vector[N])
*Se recibe como parámetros la matriz de adyacencia y el vector donde se guardarán los
vértices y sus grados.
*N es el número de vértices.

grado_salida0

//En el primer bucle para evaluar las aristas salientes al nodo.


Para i = 0 hasta N-1
Para j= 0 hasta N-1
grado_salida  grado_salida +matriz[i][j]
Fin para
Vector[i] Grado_salida
Grado_salida  0//Se reinicia el contador para el siguiente nod
Fin_para

//En el primer bucle para evaluar las aristas entrantes al nodo y se sumarán al número de
aristas salientes.
Grado_entrada0
Para i = 0 hasta N-1
Para j= 0 hasta N-1
Grado_entrada Grado_entrada +matriz[j][i]
Fin Para
Vector[i]Vector[i]+ Grado_entrada
Grado_entrada  0//Se reinicia el contador para el siguiente nodo
Fin Para

Max_grado=0
//En este último bucle se hallará el nodo que tiene el máximo grado
Para i=0 hasta N-1
Si(max<Vector[i])
Max_grado Vector[i]//Se guardará el máximo grado.
Fin Si
Fin Para
Retornar Max_grado
Fin Funcion

3. (Pseudocódigo)
Un ABM es un árbol binario que en su raíz guarda el menor valor (y los árboles izquierdo
y derecho tienen la misma propiedad). Por ejemplo como se muestra la figura.

Se le pide hacer un método que entregue true si el árbol binario de raíz x corresponde a
un ABM (o false si no).
Hágalo en
a) forma recursiva
b) forma tradicional.
Solución
Diagrama de entrada y salida

a) Forma Recursiva
Para entender el método recursivo, explicaré este algoritmo gráficamente
con el siguiente grafo.
PSEUDOCÓDIGO
//El registro nodo representará al árbol que vamos a evaluar en algoritmo.
Registro Arbol
Entero info // valor
Árbol Hd // Hijo derecho
Árbol Hi // Hijo izquierdo
Fin_registro
Árbol raíz

Predicado ABM (Árbol raiz)


*Se recibe como parámetros al Árbol que se evaluará.
*mediante llamadas recursivas se irán evaluando a todos los hijos izquierdos y derechos de la
raíz.
booleano BTRUE
Si (raiz<>NULL) // Si la raíz no es nula, entonces continuamos, si no es así, entonces
retornamos FALSE

Si (raiz.Hi<>NULL)//Si el hijo izquierdo no es NULL, entonces lo evaluamos


BABM (raiz.Hi)//Llamamos recursivamente a la función
Si (raiz.info > raiz.Hi.info y B=TRUE) //Si no cumple las propiedades
del ABM, devolveremos FALSE
BFALSE
Fin Si
Fin Si

Si(B<>FALSE) //Si el hijo izquierdo cumplió las propiedades, entonces


evaluamos al hijo derecho, sino devolveremos FALSE.
Si(raíz.Hd<> NULL) //Si el hijo derecho no es NULL, entonces lo
evaluamos
BABM (raiz.Hd)//Llamamos recursivamente a la función
Si (raiz.info > raiz.Hd.info y B=TRUE) //Si no cumple las
propiedades del ABM, devolveremos FALSE
Bfalse
Fin Si
Fin Si
Fin Si
Retornar B
Si No
Retornar FALSE
Fin Si
Fin_Predicado
b) Forma Tradicional
Para entender el método en su forma tradicional, explicaré este algoritmo
gráficamente con el mismo grafo con el que expliqué el método recursivo.
PSEUDOCÓDIGO
//El registro nodo estará como información en los nodos de una Cola.
Registro Arbol
Entero inf // valor
Árbol Hd // Hijo derecho
Árbol Hi // Hijo izquierdo
Fin_registro
Árbol inf
Registro NodoCola
Árbol info
NodoCola siguiente
Fin_registro
NodoCola primero, siguiente
//La cola nos sirve para poder llegar a evaluar todos los nodos del árbol, ya que no
podemos trabajar recursivamente en la forma tradicional.
Registro Cola
NodoCola Primero
NodoCola Ultimo
Fin Registro
Cola C

Predicado ABM (Árbol raiz)


Si(raiz!=null) // Si la raíz no es nula, entonces continuamos, si no es así, entonces
retornamos FALSE
C→Encolar(raiz) //Encolamos la raíz en la Cola.

Mientras (!Cola.Vacio())//Mientras que la cola contiene algún Nodo.


Arbol Q=C→Desencolar()//Guardamos en un nuevo árbol a la raíz.
//Verificamos si el Nodo cumple propiedades condiciones del ABM
Si (Q.info > Q.Hi.info ó Q.info>raiz→Hd.info)
Retornar FALSE// Si no cumple, devolvemos FALSE
//Si cumple las propiedades, entonces encolamos a sus hijos para seguir evaluando.
Sino
C→Encolar(Q→Hi)
C→Encolar(Q→Hd)
Fin Si
Fin_mientras
//Si ya se evaluaron a todos los nodos, entonces Devolvemos TRUE.
Retornar TRUE
Si No
Retornar TRUE
Fin Si
Fin_Predicado

4. (Desarrollo)
Dado el siguiente grafo, encontrar:
a) Matríz de adyacencia
b) Matríz de incidencia
c) Es conexo? Justifique su respuesta
d) Es simple? Justifique su respuesta
e) Es regular? Justifique su respuesta
f) Es completo? Justifique su respuesta
g) Es fuertemente conexo? Justifique su respuesta
h) Es unilateralmente conexo? Justifique su respuesta
i) Una cadena simple no elemental de grado 6
j) Un ciclo no simple de grado 5
k) Grafo recubridor. Muestre 3 de ellos

Solución:
a) Matriz de adyacencia
Recordemos que:

Observamos que el grafo es No Dirigido, además de que posee 8 Vértices o


Nodos. Ahora armamos nuestra tabla.
Vértices V1 V2 V3 V4 V5 V6 V7 V8 Grado
V1 0 1 1 1 0 0 1 1 5
V2 1 0 1 0 1 1 0 1 5
V3 1 1 0 1 1 1 1 0 6
V4 1 0 1 0 1 0 1 0 4
V5 0 1 1 1 0 1 1 1 6
V6 0 1 1 0 1 0 0 1 4
V7 1 0 1 1 1 0 0 1 5
V8 1 1 0 0 1 1 1 0 5
b) Matriz de incidencia
Recordemos que:
Matriz de Incidencia

Observamos que el grafo es no dirigido, posee 8 vértices y 20 aristas.

Nodo a a a a a1 a1 a1 a1 a1 a1
a2 a3 a5 a6 a8 a10 a13 a16 a19 a20
s 1 4 7 9 1 2 4 5 7 8
V1 1 1   1 1 1               1            
V2 1   1         1 1 1                    
V3   1 1       1       1 1 1              
V4       1             1       1          
V5               1         1     1 1   1  
V6             1     1           1       1
V7         1             1   1 1   1 1    
V8           1     1                 1 1 1

c) ¿Es conexo?
SÍ ES CONEXO
Recordemos que:

Para verificar si un grafo es Conexo podemos realizar tanto el algoritmo DFS o el BFS. En
esta ocasión realizaremos el recorrido DFS (Primera Búsqueda en Profundidad).
Tenemos el grafo:
Aplicando el algoritmo DFS (Recorrido en profundidad)
Empezamos el RECORRIDO EN PROFUNDIDAD.
Obtenemos:

Cómo podemos observar el grafo posee camino alcanzable desde cualquier vértice hacia
cualquier vértice, por lo tanto, se cumple lo necesario para decir que el grafo sí es Conexo.

d) ¿Es simple? Justifique su respuesta


SÍ ES UN GRAFO SIMPLE.
Recordemos que:
Si observamos la matriz de incidencia, podremos observar que en cada arista inciden
únicamente dos vértices, por lo tanto, sí es un grafo simple.

Nodo a a a a a1 a1 a1 a1 a1 a1
a2 a3 a5 a6 a8 a10 a13 a16 a19 a20
s 1 4 7 9 1 2 4 5 7 8
V1 1 1   1 1 1               1            
V2 1   1         1 1 1                    
V3   1 1       1       1 1 1              
V4       1             1       1          
V5               1         1     1 1   1  
V6             1     1           1       1
V7         1             1   1 1   1 1    
V8           1     1                 1 1 1
Suma 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

e) ¿Es regular? Justifique su respuesta


NO ES UN GRAFO REGULAR.
Recordemos que:

En cambio, si revisamos la matriz de adyacencia, podremos observar que no todos los vértices
comparten el mismo grado, cantidad de nodos adyacentes.
Vértices V1 V2 V3 V4 V5 V6 V7 V8 Grado
V1 0 1 1 1 0 0 1 1 5
V2 1 0 1 0 1 1 0 1 5
V3 1 1 0 1 1 1 1 0 6
V4 1 0 1 0 1 0 1 0 4
V5 0 1 1 1 0 1 1 1 6
V6 0 1 1 0 1 0 0 1 4
V7 1 0 1 1 1 0 0 1 5
V8 1 1 0 0 1 1 1 0 5
Por lo tanto, el grafo NO ES REGULAR.

f) ¿Es completo? Justifique su respuesta


NO ES UN GRAFO COMPLETO.
Recordemos que:

Sin embargo, si observamos la matriz de adyacencia podremos notar que existen vértices que
no están unidos por aristas directamente. Como, por ejemplo, los vértices 1 y 5, 1 y 6, 2 y 7.
Por lo tanto, el grafo NO ES COMPLETO.
g) ¿Es fuertemente conexo? Justifique su respuesta
NO APLICA PARA ESTE GRAFO.
Recordemos que:

El término Fuertemente conexo es aplicable para grafos dirigidos. En este problema se


considera un grafo NO DIRIGIDO, por lo tanto, este concepto NO APLICA.

h) ¿Es unilateralmente conexo? Justifique su respuesta


SÍ ES UNILATERALMENTE CONEXO.
Recordemos que:

Como evidenciamos con anterioridad en el recorrido en profundidad (DFS), el grafo es


conexo, por lo tanto, al ser un grafo no dirigido, también es UNILATERALMENTE
CONEXO, ya que existen caminos alcanzables desde todos los nodos y hacia todos los nodos.
i) Una cadena simple no elemental de grado 6
j) Un ciclo no simple de grado 5

Del grafo podemos obtener el ciclo no simple de grado 5.


El ciclo quedaría de la siguiente forma:

k) Grafo recubridor. Muestre 3 de ellos


Recordemos que:
Un grafo recubridor es aquel que permite recorrer todos lo vértices del grafo original, sin
generar ciclos.
1er GRAFO
2do GRAFO

3er GRAFO
5. (Desarrollo en Java)
Construya una aplicación para hallar la matriz de adyacencia y la matriz de caminos en un
grafo.
SOLUCIÓN
Explicación del código:
Al programa se le ingresa el grafo, especificando sus aristas. En la función principal se está
representando el siguiente grafo.

Con este grafo se construirá la matriz de adyacencia y matriz de caminos.


El algoritmo de la matriz de caminos está basando en el Algoritmo de Warshall, ya que este
funciona como una cerradura, ayudándonos a encontrar todos los caminos posibles.
Código:

/**

* @author Sierra Cordova, Paul Alexander


* Trabajo Domiciliario 5.
* Estructura de Datos - 2020 - II
* Docente: Huayna Dueñas, Ana María
*/
public class Mat_adyacencia {

private int n;//número de vértices del grafo.


private int[][] matriz;//Matriz será nuestra matriz de adyacencia.
private int[][] matriz_caminos;//Será nuestra matriz de caminos.

//Método constructor, este inicia toda la matriz con ceros.


public Mat_adyacencia(int n) {
this.n = n;
matriz = new int[this.n][this.n];
//se inicializa matriz en 0
for(int i=0; i< n; i++){
for(int j=0; j< n; j++){
matriz[i][j] = 0;
}
}
}
//Este método nos permitirá agregar nuevas aristas a nuestro grafo.
public void agregar(int i, int j){
matriz[i][j] += 1;
}

//Aquí generamos la matriz de caminos a partir de nuestra matriz de adyacencia.


//Este algoritmo está basado en el agoritmo de Warshall para encontrar todas los
caminos posibles.
public void hacer_tabla()
{
matriz_caminos = matriz;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (matriz_caminos[j][i]==1)
for (int k = 0; k < n; k++)
if (matriz_caminos[j][i]==1 && matriz_caminos[i][k]==1)
matriz_caminos[j][k] =1;
}
}
}
//Este método nos permitirá visualizar la matriz.
//Se utilizará tanto para la matriz de adyacencia como la matriz de
public void mostrar_tabla(int [][]matriz_caminos)
{
System.out.print(" ");
for (int v = 0; v < n; v++)
System.out.print(" " + v );
System.out.println();
for (int v = 0; v < n; v++)
{
System.out.print(v +" ");
for (int w = 0; w < n; w++)
{
System.out.print(" "+matriz_caminos[v][w]+" ");

}
System.out.println();
}
}

public static void main(String[] args) {

Mat_adyacencia matriz = new Mat_adyacencia(5);


//Ahora agregamos las aristas del grafo.
matriz.agregar(0, 3);

matriz.agregar(1, 0);
matriz.agregar(1, 4);

matriz.agregar(2, 0);
matriz.agregar(2, 3);
matriz.agregar(2, 4);

matriz.agregar(3, 2);

//Ahora mostraremos en pantalla ambas matrices generadas.


System.out.println("\n Matriz de Adyacencia :\n");
matriz.mostrar_tabla(matriz.matriz);

matriz.hacer_tabla();//Haremos la tabla de caminos.


System.out.println("\n Matriz de Caminos :\n");
matriz.mostrar_tabla(matriz.matriz_caminos);
}

También podría gustarte