You are on page 1of 14

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA

PRACTICA 2: RECORRIDOS SOBRE GRAFOS

CLAVE DE LA ASIGNATURA PARA-ES

CUATRIMESTRE 8

NOMBRE DE LA ASIGNATURA PROGRAMACIN AVANZADA

NMERO DE PRCTICA 2

NOMBRE RECORRIDOS SOBRE GRAFOS

DURACIN (HORAS) 4

INTRODUCCIN: Las funciones de recorrido de grafos son extensiones de los recorridos utilizados en las estructuras tipo rbol. El objetivo es visitar todos los nodos del grafo exactamente una vez. Cuando se visita, es con la intencin de realizar algn clculo sobre l, ya sea simplemente imprimir su informacin u obtener algn resultado a partir de los valores de los nodos visitados. Si el objetivo de un recorrido es simplemente pasar por todos los nodos del grafo, basta con hacer una pasada por el conjunto de nodos. Al recorrer se sigue una topologa, es decir, lo recorremos siguiendo los caminos definidos en el por los arcos. Existen dos estrategias de recorrido diferentes: Primero en profundidad. Primero en amplitud o anchura.

OBJETIVO: Implementar los recorridos de un grafo: primero en profundidad y primero en amplitud en la solucin de problemas computables.

ELABORO: M. en D. Bibiana Prez Castillo Prez

REVISO: Pgina | 1

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

TEORA: El algoritmo primero en profundidad (depth firts), tiene el siguiente procedimiento: 1. Inicializar todos los nodos del grafo en el estado: en espera. 2. Para cada nodo del grafo: 2.1. Si el estado es en espera entonces 2.1.1. Insertar el nodo en pila (cambiar su estado a listo). 2.1.2. Mientras la pila de nodos listos no est vaca. Sacar un nodo de la pila y procesarlo. Cambiar su estado ha procesado. Meter en la pila todos los nodos vecinos del nodo recin sacado cuyo estado sea en espera o listo. Nota: si el nodo ya existe en la pila (con estado de listo) se deja slo el que lleg al ltimo (el ms reciente). El pseudocdigo sera el siguiente: Algoritmo PrimeroEnProfundidad(G: Grafo; n: Elemento); Variables p: Pila l, m: Elemento Inicio P:=Crear(); Marcar(n); Apilar(p, n); MIENTRAS NOT Vaca(p) HACER m := Cima(p) Desapilar(c) Marcar(m) Procesar(m) PARA TODO nodo l sin marcar adyacente a m HACER Marcar(l) Apilar(c, l) FIN PARA FIN MIENTRAS Fin PrimeroEnProfundidad

ELABORO: M. en D. Bibiana Prez Castillo Prez

REVISO: Pgina | 2

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

Ejemplo Se tiene el grafo no dirigido mostrado en la figura siguiente


A B

C F G

Supongamos que el elemento inicial es el nodo A. se guarda en la pila, como la pila no est vaca, precisamente contiene el nodo A, se saca el primer elemento. Al no estar marcado, se marca y se procesa. Se puede suponer que en este caso el procesamiento consiste en escribir su valor en pantalla. Los dos elementos adyacentes son B y D, ambos estn sin marcar y se incluyen en la pila.

La pila no est vaca por lo que se saca el elemento de la cima, D, que no est marcado. Se marca y se escribe por pantalla. Los nodos adyacentes a D son C, F y G, ninguno de los cuales est marcado. Por tanto, se apilan los tres. Se saca el elemento de la cima de la pila, G y se escribe por pantalla. El nico nodo adyacente a G sin marcar es E, porque d ya est marcado, por lo que slo se apila e, que pasa a ser la nueva cima. Se saca E de la pila y se procesa. No hay ningn sucesor de E que no haya sido marcado, por tanto no se apila ningn elemento. En este momento, la cima de la pila es F. Se saca y se procesa. Los tres nodos adyacentes a F son D, E, y G que todos estn marcados, por lo que no se apilan. Se saca la cima de la pila, el nodo B, que se procesa. Sus nodos adyacentes, A y E, no se apilan al estar ya marcados. Se vuelve a sacar la cima, que esta vez es C, que est an sin marcar. Pon tanto, se marca y se procesa. Como todos sus nodos adyacentes estn marcados, no se apila ninguno. Y finalmente se saca el nico elemento
ELABORO: M. en D. Bibiana Prez Castillo Prez REVISO: Pgina | 3

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

que queda en la pila. Se procesa B y se acaba el bucle, por estar vaca la pila. El resultado por pantalla sera entonces: A, D, G, E, F, C, B.

El contenido de la pila en el recorrido primero en profundidad es:

El algoritmo primero en anchura (breadth firts) se realiza bajo el siguiente procedimiento: 1. Inicializar todos los nodos del grafo en el estado: en espera. 2. Para cada nodo del grafo: 2.1. Si el estado es en espera entonces 2.1.1. Insertar el nodo en una fila (cambiar su estado a listo). 2.1.2. Mientras la fila de nodos listos no est vaca. Sacar un nodo de la fila y procesarlo. Cambiar su estado a procesado. Meter en la fila todos los nodos vecinos del nodo recin sacado cuyo estado sea en espera. Cambiar el estado de esto nodos a listos.

El recorrido en amplitud es similar al recorrido por niveles de un rbol, si consideramos como un nivel el conjunto de los nodos adyacentes. En este recorrido, tras visitar un nodo, se visitan todos sus nodos adyacentes. Una vez visitados todos los nodos de este primer nivel, se repite el proceso visitando todos los nodos adyacentes del primer vecino de nivel recin recorrido y repitindolo para todos los nodos hasta que no quede ninguno por visitar.

ELABORO: M. en D. Bibiana Prez Castillo Prez

REVISO: Pgina | 4

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

En el recorrido en profundidad usbamos una pila como estructura auxiliar para recorrer el grafo. Aunque en el recorrido en amplitud no hacemos vuelta atrs tambin necesitamos almacenar temporalmente los nodos. Para guardarlos en el orden adecuado, usaremos una estructura tipo cola en vez de una pila. El Pseudocdigo sera el siguiente:

Algoritmo PrimeroEnAmplitud(G: Grafo; n: Elemento); Variables c: Cola l, m: NODO Inicio C := Crear() Marcar(n) Insertar(c, n) MIENTRAS NOT Vaca(c) HACER m := Frente(c) Extraer(c) PARA TODO nodo l sin marcar adyacente a m HACER Marcar(l) Insertar(c, l) FIN PARA FIN MIENTRAS Fin PrimeroEnAmplitud

Si hacemos PrimeroEnAmplitud(G, a), siendo G el nodo del ejemplo anterior tendremos la siguiente secuencia. Se inserta a en la cola. Como la cola no est vaca, se extrae el primer elemento, que es A, por ser el nico. Se inserta los nodos adyacentes a A sin marcar: B y D. Como la cola no est vaca, se saca el primer elemento de la cola, B, y se inserta los nodos adyacentes no visitados. Slo se inserta E. Ahora el frente de la cola es D. Se saca y se guarda sus sucesores: C, F y G. El siguiente elemento que sale de la cola
ELABORO: M. en D. Bibiana Prez Castillo Prez REVISO: Pgina | 5

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

es E, al que no le queda ningn vecino sin marcar. Igual pasa con C, F y finalmente G. Llegados a este punto, la cola se ha quedado vaca y se acaba el algoritmo. El recorrido ha sido: A, B, C, D, E, F, G.

DESARROLLO:

1. Implemente el cdigo de generacin de los nodos del grafo


import java.util.ArrayList; public class Nodo { private Object dato; private ArrayList<Nodo> nodo; public boolean visitado = false; public Nodo(){ this(new Object()); } public Nodo(Object dato){ this.dato = dato; nodo = new ArrayList<Nodo>(); } public void setDato(Object dato){ this.dato = dato; } public Object getDato(){ return this.dato; } public void setNodo(Nodo nodo){ this.nodo.add(nodo); } public ArrayList<Nodo> getHijos(){ return nodo; } }

ELABORO: M. en D. Bibiana Prez Castillo Prez

REVISO: Pgina | 6

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

2. Implemente un grafo por medio de listas de adyacencias, para ello verifique el funcionamiento del siguiente cdigo con el grafo ejemplo de la seccin de teora:
import java.util.ArrayList; public class Grafo { private ArrayList<Nodo> listaNodo; public Grafo(){ listaNodo = new ArrayList<Nodo>(); } public void adjuntarNodo(Nodo nodo){ listaNodo.add(nodo); } public void crearEnlaces(Object nombreNodoPadre,Object nombreNodoHijo){ Nodo padre = buscarNodo(nombreNodoPadre); Nodo hijo = buscarNodo(nombreNodoHijo); if(padre != null && hijo != null){ padre.setNodo(hijo); } } public Nodo buscarNodo(Object nombreNodo) { Nodo temp = null; for(int i = 0;i < listaNodo.size(); i++) { if(((String)nombreNodo).equals((String)listaNodo.get(i).getDato())) { return listaNodo.get(i); } } return temp; } }

ELABORO: M. en D. Bibiana Prez Castillo Prez

REVISO: Pgina | 7

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

3. A continuacin se presenta el procedimiento de implementacin de pila y cola para los recorridos por anchura y amplitud del grafo
import java.util.ArrayList; public class Cola extends ArrayList{ public Cola(){ super(); } public void addNodo(Nodo nodo){ if(!this.contains(nodo) && nodo.visitado != true){ add(nodo); System.out.println(); mostrarContenido(); } } public Nodo getNodo(){ Nodo nodoTemp = null; if(!this.isEmpty() && this != null){ nodoTemp = (Nodo)this.get(0); this.remove(0); } return nodoTemp; } public void mostrarContenido(){ System.out.print("["); for(int i = 0;i < this.size();i++){ System.out.print(((Nodo)this.get(i)).getDato()); } System.out.print("]"); } }

import java.util.ArrayList; public class Pila extends ArrayList{ public Pila() { super(); } public void addNodo(Nodo nodo){ if(!this.contains(nodo) && nodo.visitado != true){ add(nodo); System.out.println(); mostrarContenido(); } }

ELABORO: M. en D. Bibiana Prez Castillo Prez

REVISO: Pgina | 8

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

public Nodo getNodo(){ Nodo nodoTemp = null; if(!this.isEmpty() && this != null){ nodoTemp = (Nodo)this.get(this.size() - 1); this.remove(this.size() - 1); } //mostrarContenido(); return nodoTemp; } public void mostrarContenido(){ System.out.print("["); for(int i = 0;i < this.size();i++){ System.out.print(((Nodo)this.get(i)).getDato()); } System.out.print("]"); } }

4. Implemente los recorridos para el grafo.


public class Recorrido{ private Pila pila; private Cola cola; public Recorrido(){ pila = new Pila(); cola = new Cola(); } private void llenarPilaNodosAdyacentes(Nodo nodo){ for(int i = 0; i < nodo.getHijos().size();i++){ if(!nodo.getHijos().contains(nodo)){ pila.addNodo(nodo.getHijos().get(i)); } } } private void llenarColaNodosAdyacentes(Nodo nodo){ for(int i = 0; i < nodo.getHijos().size();i++){ if(!nodo.getHijos().contains(nodo)){ cola.addNodo(nodo.getHijos().get(i)); } } }

ELABORO: M. en D. Bibiana Prez Castillo Prez

REVISO: Pgina | 9

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

public void recorrerProfundidadIterativo(Grafo grafo,Nodo nodoInicio){ if(grafo != null && nodoInicio != null){ pila.addNodo(nodoInicio); while(pila.size() > 0){ Nodo nodoVisitado = pila.getNodo(); if(nodoVisitado.visitado == false){ nodoVisitado.visitado = true; System.out.print(nodoVisitado.getDato()+","); llenarPilaNodosAdyacentes(nodoVisitado); } } } } public void recorrerAmplitud(Grafo grafo,Nodo nodoInicio){ if(grafo != null && nodoInicio != null){ cola.addNodo(nodoInicio); while(cola.size() > 0){ Nodo nodoVisitado = cola.getNodo(); if(nodoVisitado.visitado == false){ nodoVisitado.visitado = true; System.out.print(nodoVisitado.getDato()+","); llenarColaNodosAdyacentes(nodoVisitado); } } } } }

5. Complete el programa y verifique los recorridos.


public class Main{ static Grafo grafo; public static void llenandoGrafo(){ grafo = new Grafo(); grafo.adjuntarNodo(new Nodo("A")); grafo.adjuntarNodo(new Nodo("B")); grafo.adjuntarNodo(new Nodo("C")); grafo.adjuntarNodo(new Nodo("D")); grafo.adjuntarNodo(new Nodo("F"));

ELABORO: M. en D. Bibiana Prez Castillo Prez

REVISO: Pgina | 10

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

grafo.crearEnlaces("A","B");// de A hacia B grafo.crearEnlaces("B","A");// de B hacia A /* * Lo anterior se realiza por ser un grafo no dirigido... * */ grafo.crearEnlaces("A","C"); grafo.crearEnlaces("C","A"); grafo.crearEnlaces("A","F"); grafo.crearEnlaces("F","A"); // // grafo.crearEnlaces("B","A");//Esta enlace ya existe grafo.crearEnlaces("A","B");//Esta enlace ya existe

grafo.crearEnlaces("B","F"); grafo.crearEnlaces("F","B"); // // grafo.crearEnlaces("C","A");//Esta enlace ya existe grafo.crearEnlaces("A","C");//Esta enlace ya existe

grafo.crearEnlaces("C","D"); grafo.crearEnlaces("D","C"); // // // // // // } grafo.crearEnlaces("D","C");//Esta enlace ya existe grafo.crearEnlaces("C","D");//Esta enlace ya existe grafo.crearEnlaces("F","A");//Esta enlace ya existe grafo.crearEnlaces("A","F");//Esta enlace ya existe grafo.crearEnlaces("F","B");//Esta enlace ya existe grafo.crearEnlaces("B","F");//Esta enlace ya existe

public static void main(String []args){ llenandoGrafo(); Recorrido recorrido = new Recorrido(); System.out.println("----------------------------------------------"); System.out.println("Recorrido en profundidad"); recorrido.recorrerProfundidadIterativo(grafo,grafo.buscarNodo("A")); System.out.println(); llenandoGrafo();
ELABORO: M. en D. Bibiana Prez Castillo Prez REVISO: Pgina | 11

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

System.out.println("----------------------------------------------"); System.out.println("Recorrido en Amplitud"); recorrido.recorrerAmplitud(grafo,grafo.buscarNodo("A")); System.out.println(); System.out.println("----------------------------------------------"); } }

ACTIVIDADES COMPLEMENTARIAS: A. Modifique el cdigo para Genere la salida al terminar la ejecucin de cada recorrido sin los valores intermedios. Construir el grafo a partir de los valores proporcionados por el usuario.

B. Resuelva el siguiente acertijo con teora de grafos, la aplicacin generada deber mostrar el recorrido realizado:

Cada noche, provisto de mi llavero, cruzo todas las puertas de mi casa cerrndolas una vez atravesadas. No vuelvo a abrir una puerta cerrada y duermo con mi llavero. En qu habitacin duermo?

ELABORO: M. en D. Bibiana Prez Castillo Prez

REVISO: Pgina | 12

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

C. Ahora haz lo mismo con esta nueva casa.

CONCLUSIONES:

ELABORO: M. en D. Bibiana Prez Castillo Prez

REVISO: Pgina | 13

UNIVERSIDAD POLITCNICA DEL VALLE DE MXICO INGENIERA EN INFORMTICA


PRACTICA 2: RECORRIDOS SOBRE GRAFOS

BIBLIOGRAFA: 1. Caro, O., & Guardatii, S. (2006). Estructura de datos. Mc Graw Hill. 2. Ceballos, F. J. (2011). Java 2: Curso de Programacin. Mxico: Alfaomega. 3. Franch, X. (2002). Estructura de Datos: Especificacin, Diseo e Implementacin. Alfaomega. 4. Loomis, M. E. (1990). Estructura de datos y Organizacin de archivos. Prentice Hall.

ELABORO: M. en D. Bibiana Prez Castillo Prez

REVISO: Pgina | 14

You might also like