Está en la página 1de 6

ALGORITMIA ALGO+ - Algoritmos y Estructuras de Datos

http://www.algoritmia.net/articles.php?id=18

Martes, 26 de Mayo de 2015


Nombre

Password

Entrar [ Regstrate ]

Grafos

Definicin
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.

La conexin se
reinici

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
La conexin al servidor se reinici mientras se
conecta dos ciudades, determinar si es posible llegar de una ciudad a otra, si desde cualquier
cargaba la pgina.
ciudad existe un camino que llegue a cualquier otra, etc.

El sitio podra estar temporalmente


fuera de
El estudio de grafos es una rama de la algoritmia muy importante. Estudiaremos primero sus
servicio o muy ocupado. Intenta
nuevamente
rasgos generales y sus recorridos fundamentales, para tener una buena base que permita
en un momento.
comprender los algoritmos que se pueden aplicar.
Si no puedes cargar ninguna pgina, verica
la conexin de red de tu computadora.
Si la red o tu computadora estn protegidas
Glosario
por un rewall o proxy, asegrate que
Firefox pueda acceder a internet.
Reintentar

Un grafo consta de vrtices (o nodos) y aristas. Los vrtices son objetos que contienen
informacin y las aristas son conexiones entre vrtices. Para representarlos, se suelen utilizar
puntos para los vrtices y lneas para las conexiones, aunque hay que recordar siempre que la
definicin de un grafo no depende de su representacin.
Un camino entre dos vrtices es una lista de vrtices en la que dos elementos sucesivos estn
conectados por una arista del grafo. As, el camino AJLOE es un camino que comienza en el
vrtice A y pasa por los vrtices J,L y O (en ese orden) y al final va del O al E. El grafo ser
conexo si existe un camino desde cualquier nodo del grafo hasta cualquier otro. Si no es conexo
constar de varias componentes conexas.

Un camino simple es un camino desde un nodo a otro en el que ningn nodo se repite (no se
pasa dos veces). Si el camino simple tiene como primer y ltimo elemento al mismo nodo se
denomina ciclo. Cuando el grafo no tiene ciclos tenemos un rbol (ver rboles). Varios rboles
independientes forman un bosque. Un rbol de expansin de un grafo es una reduccin del grafo
en el que solo entran a formar parte el nmero mnimo de aristas que forman un rbol y
conectan a todos los nodos.
Segn el nmero de aristas que contiene, un grafo es completo si cuenta con todas las aristas
posibles (es decir, todos los nodos estn conectados con todos), disperso si tiene relativamente
pocas aristas y denso si le faltan pocas para ser completo.
Las aristas son la mayor parte de las veces bidireccionales, es decir, si una arista conecta dos
nodos A y B se puede recorrer tanto en sentido hacia B como en sentido hacia A: estos son
llamados grafos no dirigidos. Sin embargo, en ocasiones tenemos que las uniones son
unidireccionales. Estas uniones se suelen dibujar con una flecha y definen un grafo dirigido.
Cuando las aristas llevan un coste asociado (un entero al que se denomina peso) el grafo es
ponderado. Una red es un grafo dirigido y ponderado.

1 de 6

26/05/15 17:11

ALGORITMIA ALGO+ - Algoritmos y Estructuras de Datos

http://www.algoritmia.net/articles.php?id=18

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.

Representacin por matriz de adyacencia


Es la forma ms comn de representacin y la ms directa. Consiste en una tabla de tamao V x
V, en que la que a[i][j] tendr como valor 1 si existe una arista del nodo i al nodo j. En caso
contrario, el valor ser 0. Cuando se trata de grafos ponderados en lugar de 1 el valor que
tomar ser el peso de la arista. Si el grafo es no dirigido hay que asegurarse de que se marca
con un 1 (o con el peso) tanto la entrada a[i][j] como la entrada a[j][i], puesto que se puede
recorrer en ambos sentidos.
int V,A;
int a[maxV][maxV];
void inicializar()
{
int i,x,y,p;
char v1,v2;
// Leer V y A
memset(a,0,sizeof(a));
for (i=1; i<=A; i++)
{
scanf("%c %c %d\n",&v1,&v2,&p);
x=v1-'A'; y=v2-'A';
a[x][y]=p; a[y][x]=p;
}
}
En esta implementacin se ha supuesto que los vrtices se nombran con una letra mayscula y
no hay errores en la entrada. Evidentemente, cada problema tendr una forma de entrada
distinta y la inicializacin ser conveniente adaptarla a cada situacin. En todo caso, esta
operacin es sencilla si el nmero de nodos es pequeo. Si, por el contrario, la entrada fuese
muy grande se pueden almacenar los nombres de nodos en un rbol binario de bsqueda o
utilizar una tabla de dispersin, asignando un entero a cada nodo, que ser el utilizado en la
matriz de adyacencia.
Como se puede apreciar, la matriz de adyacencia siempre ocupa un espacio de V*V, es decir,
depende solamente del nmero de nodos y no del de aristas, por lo que ser til para
representar grafos densos.

Representacin por lista de adyacencia


Otra forma de representar un grafo es por medio de listas que definen las aristas que conectan

2 de 6

26/05/15 17:11

ALGORITMIA ALGO+ - Algoritmos y Estructuras de Datos

http://www.algoritmia.net/articles.php?id=18

los nodos. Lo que se hace es definir una lista enlazada para cada nodo, que contendr los nodos
a los cuales es posible acceder. Es decir, un nodo A tendr una lista enlazada asociada en la que
aparecer un elemento con una referencia al nodo B si A y B tienen una arista que los une.
Obviamente, si el grafo es no dirigido, en la lista enlazada de B aparecer la correspondiente
referencia al nodo A.
Las listas de adyacencia sern estructuras que contendrn un valor entero (el nmero que
identifica al nodo destino), as como otro entero que indica el coste en el caso de que el grafo
sea ponderado. En el ejemplo se ha utilizado un nodo z ficticio en la cola (ver listas, apartado
cabeceras y centinelas).
struct nodo
{
int v;
int p;
nodo *sig;
};
int V,A; // vrtices y aristas del grafo
struct nodo *a[maxV], *z;
void inicializar()
{
int i,x,y,peso;
char v1,v2;
struct nodo *t;
z=(struct nodo *)malloc(sizeof(struct nodo));
z->sig=z;
for (i=0; i<V; i++)
a[i]=z;
for (i=0; i<A; i++)
{
scanf("%c %c %d\n",&v1,&v2,&peso);
x=v1-'A'; y=v2-'A';
t=(struct nodo *)malloc(sizeof(struct nodo));
t->v=y; t->p=peso; t->sig=a[x]; a[x]=t;
t=(struct nodo *)malloc(sizeof(struct nodo));
t->v=x; t->p=peso; t->sig=a[y]; a[y]=t;
}
}
En este caso el espacio ocupado es O(V + A), muy distinto del necesario en la matriz de
adyacencia, que era de O(V2). La representacin por listas de adyacencia, por tanto, ser ms
adecuada para grafos dispersos.
Hay que tener en cuenta un aspecto importante y es que la implementacin con listas enlazadas
determina fuertemente el tratamiento del grafo posterior. Como se puede ver en el cdigo, los
nodos se van aadiendo a las listas segn se leen las aristas, por lo que nos encontramos que
un mismo grafo con un orden distinto de las aristas en la entrada producir listas de adyacencia
diferentes y por ello el orden en que los nodos se procesen variar. Una consecuencia de esto es
que si un problema tiene varias soluciones la primera que se encuentre depender de la entrada
dada. Podra presentarse el caso de tener varias soluciones y tener que mostrarlas siguiendo un
determinado orden. Ante una situacin as podra ser muy conveniente modificar la forma de
meter los nodos en la lista (por ejemplo, hacerlo al final y no al principio, o incluso insertarlo en
una posicin adecuada), de manera que el algoritmo mismo diera las soluciones ya ordenadas.

3 de 6

26/05/15 17:11

ALGORITMIA ALGO+ - Algoritmos y Estructuras de Datos

http://www.algoritmia.net/articles.php?id=18

Exploracin de grafos
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 decir, en el primer caso se exploran primero los verdes y luego los marrones, pasando
primero por los de mayor intensidad de color. En el segundo caso se exploran primero los
verdes, despus los rojos, los naranjas y, por ltimo, el rosa.
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.

Bsqueda 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.
La siguiente funcin realiza un mximo de V (el nmero total de vrtices) llamadas a la funcin

4 de 6

26/05/15 17:11

ALGORITMIA ALGO+ - Algoritmos y Estructuras de Datos

http://www.algoritmia.net/articles.php?id=18

visitar, que implementamos aqu en sus dos variantes: representacin por matriz de
adyacencia y por listas de adyacencia.
int id=0;
int val[V];
void buscar()
{
int k;
for (k=1; k<=V; k++)
val[k]=0;
for (k=1; k<=V; k++)
if (val[k]==0) visitar(k);
}
void visitar(int k) // matriz de adyacencia
{
int t;
val[k]=++id;
for (t=1; t<=V; t++)
if (a[k][t] && val[t]==0) visitar(t);
}
void visitar(int k) // listas de adyacencia
{
struct nodo *t;
val[k]=++id;
for (t=a[k]; t!=z; t=t->sig)
if (val[t->v]==0) visitar(t->v);
}

El resultado es que el array val contendr en su i-sima entrada el orden en el que el vrtice
i-simo fue explorado. Es decir, si tenemos un grafo con cuatro nodos y fueron explorados en el
orden 3-1-2-4, el array val quedar como sigue:
val[1]=2; // el primer nodo fue visto en segundo lugar
val[2]=3; // el segundo nodo fue visto en tercer lugar
val[3]=1; // etc.
val[4]=4;
Una modificacin que puede resultar especialmente til es la creacin de un array "inverso" al
array val que contenga los datos anteriores "al revs". Esto es, un array en el que la entrada
i-sima contiene el vrtice que se explor en i-simo lugar. Basta modificar la lnea
val[k]=++id;
sustituyndola por
val[++id]=k;
Para el orden de exploracin de ejemplo anterior los valores seran los siguientes:
val[1]=3;
val[2]=1;
val[3]=2;
val[4]=4;

Bsqueda en amplitud o anchura

5 de 6

26/05/15 17:11

ALGORITMIA ALGO+ - Algoritmos y Estructuras de Datos

http://www.algoritmia.net/articles.php?id=18

La diferencia fundamental respecto a la bsqueda en profundidad es el cambio de estructura de


datos: una cola en lugar de una pila. En esta implementacin, la funcin del array val y la
variable id es la misma que en el mtodo anterior.
struct tcola *cola;
void visitar(int k) // listas de adyacencia
{
struct nodo *t;
encolar(&cola,k);
while (!vacia(cola))
{
desencolar(&cola,&k);
val[k]=++id;
for (t=a[k]; t!=z; t=t->sig)
{
if (val[t->v]==0)
{
encolar(&cola,t->v);
val[t->v]=-1;
}
}
}
}

( ALGORITMIA # 07/01/2003 00:00:00 )

(2001-2008) ALGORITMIA.NET - Poltica de privacidad

6 de 6

26/05/15 17:11