Documente Academic
Documente Profesional
Documente Cultură
GRAFOS
1.1.Introduccin
Analiza: Entre las principales aplicaciones de los grafos tenemos:
Circuitos electrnicos, Tarjetas impresas, Circuitos inte
integrados,
grados,
Redes de transporte, Autopistas, Vuelos, Redes de ordenadores,
LANs, Internet, Web, Bases de datos, Diagramas
entidad/relacin, entre otros
Un grafo es un objeto matemtico que se utiliza para representar circuitos, redes, etc. Los
grafos son muy utilizados en computacin, ya que permiten resolver problemas muy
complejos.
Aplicacin
Imaginemos que disponemos de una serie de ciudades y de carreteras que las unen. De cada
ciudad saldrn varias carreteras, por lo que para ir de una ciudad a otra se podrn tomar
diversos caminos. Cada carretera tendr un coste asociado (por ejemplo, la longitud de la
misma). Gracias a la representacin por grafos podremos elegir el camino ms corto que
conecta dos ciudades, determinar si es posible llegar de una ciudad a otra, si desde
cualquier
alquier ciudad existe un camino que llegue a cualquier otra, etc.
Representacin de grafos
Una caracterstica especial en los grafos es que podemos representarlos utilizando dos
estructuras de datos distintas. En los algoritmos que se aplican sobre ellos veremos que
adoptarn tiempos distintos dependiendo de la forma de representacin elegida. En
particular, los tiempos de ejecucin variarn en funcin del nmero de vrtices y el de
aristas, por lo que la utilizacin de una representacin u otra depender en gran medida de
si el grafo es denso o disperso.
Para nombrar los nodos utilizaremos letras maysculas, aunque en el cdigo deberemos
hacer corresponder cada nodo con un entero entre 1 y V (nmero de vrtices) de cara a la
manipulacin de los mismos.
Conceptos Elementales
1.
2.
3.
4.
5.
6.
Son matrices cuadradas de tantas filas y columnas como vrtices tenga el grafo a
representar. En las celdas de la matriz se indica si existe un arco entre los vrtices que
determinan la celda.
Un grafo G = (V;A) se representa como G: matriz[V; V ] de bolanos. La
componente G [u; v] es 1 si (u; v) 2 A; sino G[u; v] = 0.
Memoria
Tiempo de acceso:
grafos densos
Lista adyacentes:
Lista incidentes:
2. Listas de adyacencia
Partiendo de los nodos de cada vrtice, evoluciona una lista que informa los nodos
que son adyacentes del inicial.
Un grafo G = (V;A) se representa como un vector de listas de vrtices indexado por
vrtices; es decir, G: vector[V ] de V . Cada componente G[v] es una lista de
los vrtices emergentes y/o incidentes de/a v 2 V.
Memoria:
grafos dispersos
A la hora de explorar un grafo, nos encontramos con dos mtodos distintos. Ambos
conducen al mismo destino (la exploracin de todos los vrtices o hasta que se encuentra
uno determinado), si bien el orden en que stos son "visitados" decide radicalmente el
tiempo de ejecucin de un algoritmo, como se ver posteriormente.
En primer lugar, una forma sencilla de recorrer los vrtices es mediante una funcin
recursiva, lo que se denomina bsqueda en profundidad. La sustitucin de la recursin
(cuya base es la estructura de datos pila) por una cola nos proporciona el segundo mtodo
de bsqueda o recorrido, la bsqueda en amplitud o anchura.
Suponiendo que el orden en que estn almacenados los nodos en la estructura de datos
correspondiente es A-B-C-D-E-F... (el orden alfabtico), tenemos que el orden que seguira
el recorrido en profundidad sera el siguiente:
A-B-E-I-F-C-G-J-K-H-D
En un recorrido en anchura el orden sera, por contra:
A-B-C-D-E-G-H-I-J-K-F
Es destacable que el nodo D es el ltimo en explorarse en la bsqueda en profundidad pese
a ser adyacente al nodo de origen (el A). Esto es debido a que primero se explora la rama
del nodo C, que tambin conduce al nodo D.
En estos ejemplos hay que tener en cuenta que es fundamental el orden en que los nodos
estn almacenados en las estructuras de datos. Si, por ejemplo, el nodo D estuviera antes
que el C, en la bsqueda en profundidad se tomara primero la rama del D (con lo que el
ltimo en visitarse sera el C), y en la bsqueda en anchura se explorara antes el H que el
G.
Recorrido y Bsqueda Primero en Profundidad
Se implementa de forma recursiva, aunque tambin puede realizarse con una pila. Se
utiliza un array val para almacenar el orden en que fueron explorados los vrtices.
Para ello se incrementa una variable global id (inicializada a 0) cada vez que se visita un
nuevo vrtice y se almacena id en la entrada del array val correspondiente al vrtice que se
est explorando.
Sus pasos a seguir seran:
/**
* Mtodo que recorre un vector para comprobar si se encuentra en l un valor
* recibido.
* @param Vector de enteros donde va almacenando la solucin.
* @param i Nmero a buscar dentro del vector.
* @return Devuelve true si lo encuentra.
*/
private boolean estaRepetido(int vector[], int i) {
for (int j = 0; j < vector.length; j++) {
if (vector[j] == i) {
return true;
}
}
return false;
}
/**
* Mtodo que recorre el grafo y almacena el camino mnimo en un vector.
* @param inicio Valor que representa el nodo donde comienza el recorrido.
* @return El camino minimo en un vector de enteros.
*/
public int[] caminoMinimo(int inicio) {
int numNodos = grafo.length;
int minimo[] = new int[numNodos];
// Inicializar el vector de mnimos a -1 (para el caso del nodo cero).
for (int i = 0; i < minimo.length; i++) {
minimo[i] = -1;
}
int longitudCamino = 0;
int menor = 0;
int actual = inicio;
minimo[0] = inicio;
while (longitudCamino < (numNodos - 1)) {
// Encontrar el camino mnimo al siguiente nodo
for (int i = 0; i < numNodos; i++) {
if ( (grafo[actual][i] < grafo[actual][menor]) &&
(!estaRepetido(minimo, i))) { // Para evitar repetir nodos.
menor = i;
// Ahora, el nodo siguiente es el del camino mnimo anterior.
}
}
longitudCamino++;
actual = menor;
minimo[longitudCamino] = actual;
}
return minimo;
}
/**
* Mtodo main de la clase Camino donde se crea el grafo utilizado para el
* ejemplo.
* @param args String Parametros de la clase
*/
public static void main(String args[]) {
// Vector de soluciones:
int solucion[];
// Crear un grafo de cinco vrtices representado por una matriz:
int grafo[][] = new int[5][5];
// Inicializar la matriz representando el grafo:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
grafo[i][j] = Integer.MAX_VALUE;
}
}
// Rellenar el grafo con las siguientes aristas con sus respectivos pesos:
grafo[0][1] = 30;
grafo[1][0] = 30;
grafo[0][2] = 15;
grafo[2][0] = 15;
grafo[0][3] = 80;
grafo[3][0] = 80;
grafo[1][2] = 10;
grafo[2][1] = 10;
grafo[1][3] = 60;
grafo[3][1] = 60;
grafo[1][4] = 45;
grafo[4][1] = 45;
grafo[2][3] = 50;
grafo[3][2] = 50;
grafo[2][4] = 25;
grafo[4][2] = 25;
grafo[4][3] = 40;
grafo[3][4] = 40;
// Instancia de la clase camino.
Camino c = new Camino(grafo);
// Encontrar el camino mnimo (empieza desde el nodo 0).
solucion = c.caminoMinimo(0);
// Mostrar el rbol mnimo abarcador.
System.out.print("\nRBOL MNIMO ABARCADOR --> Solucin: ");
for (int i = 0; i < 5; i++) { // n-1 aristas entre n nodos.
System.out.print(solucion[i] + " ");
}
}
}
Tiempo de ejecucin
Para calcular la complejidad del algoritmo lo que hicimos fue obtener el Tiempo de
Ejecucin (T(n)), separando las operaciones bsicas (de duracin constante) obtenindose:
T(n) = 11 n + 8.
Por lo tanto, eliminando las constantes sabemos que la complejidad del algoritmo es O(n).
Exposicin Nro. 6: Investigar un problema del mundo real que se pueda resolver con la
estructura grafo, adems investigar otros algoritmos para la solucin y para la
implementacin debe utilizar listas de adyacencia. No olvide realizar un programa
demostrativo.
Nota: Se tomar en cuenta el material de apoyo utilizado para la exposicin y debe
entregar una copia digital a cada grupo, adems una copia impresa y digital a la profesora
el da de la exposicin.