You are on page 1of 42

Grafos: bsqueda y ordenamiento topolgico

Jose Aguilar

Grafos Bsqueda en amplitud

Bsqueda
Criterios
Completitud Complejidad del tiempo Complejidad del espacio Optimalidad

Algoritmo general de bsqueda ciega:


Inicial con un nodo Inicial Si no hay candidato para expandir entonces fallas

de lo contrario escoger nodo hoja para expandir segn estrategia


Si nodo contiene edo. Objetivo entonces es solucin

de lo contrario expandir nodo y aadir el nodo al rbol de bsqueda


3

Bsqueda no informada o ciega


Estrategia de bsqueda (a quien expandir?)
Por extensin o amplitud
Padre, sus hijos, etc. Completa pero no optima

Por Profundidad
Expande un nodo hasta su hoja y regresa. Completa pero no optima

Por Profundidad limitada. Ni completa ni optima Profundidad Iterativa


Prueba diferentes profundidades. Completa y optima

Bidireccional
J. Aguilar 4

Usos:
Para recorridos parciales de grafos infinitos o tan grandes que son inmanejables Encontrar los caminos ms cortos desde un nodo origen hasta los otros nodos
1 1

2 4

13 5 t

2 4 espacio

13 5 Opt Comp

bd bd

no

si

Por extensin

J. Aguilar

bsqueda en amplitud matriz


Versin 1.0

{pre: g (i, j) 0 i,j} 1 " marca( i ) #also $ i %, pos 2 " &i ( ' marca( i ) ) entonces busAmp( i, marca) #si $ i %, pos

recorridoEnAmp( ) {pos: marca ( i ) !erdadero i} (pos: )e#inido en )igra#o*at+ (marca: Arreglo"%00$)e ,-gico+ *arca que indica si el nodo #ue .isitado (!erdadero) o no (/also)+ (i: Entero: !ariable con la posici-n de los nodos en la matriz

T(n) = O(N + A) = (mx(N, A))

bsqueda en amplitud matriz


Versin 1.0

busAmp(Entero0: na, Arreglo"%00$)e ,-gico: mar ) {pre: % 1 na 1 pos} {pos: marca ( i ) !erdadero i} 1 mar( na ) !erdadero (mar: Arreglo"%00$)e ,-gico+ *arca que 2 co+en2ola( na ) indica si el nodo #ue .isitado (!erdadero) o 3 ( ' co+.acia2ola( ) ) " na co+primero( ) no (/also)+ co+desen2ola( ) (i: Entero0: !ariable con la posici-n de los nad3a nodoAd3acente( na ) nodos en la matriz " &i (' mar( nad3a( i )) ) entonces (co: 2ola"Entero0$+ 2ola que mantiene los mar( nad3a( i ) ) !erdadero nodos no tratados+ #si (nad3a: Arreglo"%00$)e Entero0+ !ector co+en2ola( nad3a( i ) ) au4iliar que contiene los nodos ad3acentes $i %, pos (en2ola( ), primero( ), desen2ola( ), .acia2ola( )+ $ 5peraciones de la clase 2ola+

bsqueda en amplitud ,ista


Versin 1.0

recorridoEnAmp( ) {{pre: g+n 0 } 1 " marca( i ) #also $ i %, g+numEle( ) 2 " &i ( ' marca( i ) ) entonces busAmp( i, marca) #si $ i %, g+numEle( ) {pos: marca ( i ) !erdadero i} (g: )e#inido en )igra#o,is (marca: Arreglo"%00$)e ,-gico+ *arca que indica si el nodo #ue .isitado (!erdadero) o no (/also)+ (i: Entero: !ariable au4iliar para los nodos

T(n) = O(N + A) = (mx(N, A))

bsqueda en amplitud lista


Versin 1.0

busAmp(Entero0: na, Arreglo"%00$)e ,-gico: mar ) {pre: g+n 0 } {pos: marca ( i ) !erdadero i} 1 mar( na ) !erdadero (g, nodoAd3acente( ): )e#inidos en 2 co+en2ola( na ) )igra#o,is 3 ( ' co+.acia2ola( ) ) " na co+primero( ) (mar: Arreglo"%00$)e ,-gico+ co+desen2ola( ) *arca que indica si el nodo #ue .isitado nad3a nodoAd3acente( na ) (!erdadero) o no (/also)+ nad3a+cursorAl6nicio( ) (i: Entero0: !ariable con la posici-n de los " &i ('mar(nad3a+con,ista()+6n#o())) nodos en la matriz entonces (co: 2ola"Entero0$+ 2ola que mantiene los mar(nad3a+con,ista()+6n#o()) nodos no tratados+ !erdadero (nad3a: ,ista"Entero0$+ ,ista au4iliar que contiene los nodos ad3acentes #si co+en2ola( nad3a+con,ista()+6n#o()) (en2ola( ), primero( ), desen2ola( nad3a+cursorAl7ro4imo( ) ), .acia2ola( )+ 5peraciones de la clase 2ola+ (cursorAl6nicio( ), numEle( ), $ i %, nad3a+numEle( ) con,ista( ), cursorAl7ro4imo( )+ )e#inidos en $$ ,ista

//algoritmo para grafo completamente conectado void BFS(int v){//v es el nodo de inicio del recorrido list<int> cola;//cola de adyacentes list<int>::iterator nodo_actual, aux, fin; visitado[v] = 1;//marcamos como visitado el nodo de inicio cola.push_back(v);//metemos inicio a la cola while(!cola.empty()){ nodo_actual = cola.front();//sacar nodo de la cola cola.pop_front(); aux = grafo[nodo_actual].begin();//posicionar iteradores para //lista de ady fin = grafo[nodo_actual].end(); while(aux != fin){//recorrer todos los nodos ady a nodo actual if(!visitado[*aux]){//aadir a la cola solo los no visitados visitado[*aux] = 1;//marcarlos como visitados cola.push_back(*aux);//aadirlos a la cola //aqui podriamos aadir codigo para hacer algo mientras //recorremos el grafo } aux++;//avanzar al siguiente adyacente del nodo actual } } } //algoritmo para grafo que no esta completamente conectado void BFS2(){ int i; for(i = 0; i < nvert; i++) if(!visitado[i]) BFS(i); }

BFS(G,s) { /* pseudo-cdigo */ int d[N], p[N], color[N]; /* Arreglos de distancia, de padres, y de color */ QUEUE Q; /* Cola usada como estructura auxiliar */ for ( cada vrtice u V[G] -{s}) { color [u] =Blanco; d[u] = ; /* distancia infinita si el nodo no es alcanzable */ } color[s] =Plomo; d[s] = 0; p [s]=NULL; Enqueue(Q, s); while ( !Queue_Vaca(Q) ) { u = Cabeza(Q); for ( cada v Adj [u] ) { if (color [v] == Blanco) { color[v]=Plomo; d [v]=d [u] +1; p [v] = u; Enqueue(Q, v); } Dequeue(Q); /* se extrae u */ color [u] = Negro; } }

Grafos Bsqueda en profundidad

rboles binarios
Recorridos rboles binarios: Preorden: raz-izquierdo-derecho (RID) Enorden: izquierdo-raz-derecho (IRD) Posorden: izquierdo-derecho-raz (IDR) Pre y posorden Son recursivas por naturaleza Exploracin de izquierda a derecha o viceversa Lema: cada uno de los recorridos, el tiempo T(n) que se necesita para explorar un rbol binario que contiene n nodos se encuentra en (n)

rboles binarios
Sea G={N, A, f} un grafo formado por todos los nodos que se desean visitar. Suponga una forma de marcar los nodos visitados Se selecciona un nodo para comenzar v N (nodo actual) y se marca como visitado Si hay algn nodo adyacente a v que no ha sido visitado an, se toma dicho nodo como nodo actual y se invoca recursivamente el proceso de recorrido en profundidad Cuando estn marcados como visitados todos los nodos adyacentes a v, se termina el recorrido para v. Si queda algn nodo en G que no ha sido visitado, se repite el proceso tomando un nodo cualquiera como v

Usos:
Para recorridos parciales de grafos infinitos o tan grandes que son inmanejables Encontrar los caminos ms cortos desde un nodo origen hasta los otros nodos
1 1

2 4

13 5 t

2 4 espacio

13 5 Opt Comp

bm bm

no

si

Por profundidad

J. Aguilar

18

Por profundidad

J. Aguilar

19

bsqueda en pro#undidad matriz


Versin 1.0

recorridoEn7ro#( ) {pre: g (i, j) 0 i,j} 1 " marca( i ) #also $ i %, pos 2 " &i ( ' marca( i ) ) entonces bus7ro( i, marca) #si $ i %, pos {pos: marca ( i ) !erdadero i} (pos: )e#inido en )igra#o*at+ (marca: Arreglo"%00$)e ,-gico+ *arca que indica si el nodo #ue .isitado (!erdadero) o no (/also)+ (i: Entero: !ariable con la posici-n de los nodos en la matriz

T(n) = (mx(N,A))

bsqueda en pro#undidad matriz


Versin 1.0

bus7ro(Entero0: na, Arreglo"%00$)e ,-gico: mar ) {pre: % 1 na 1 pos} {pos: marca ( i ) !erdadero i} 1 mar( na ) !erdadero (pos, nodoAd3acente( ): )e#inidos en 2 nad3a nodoAd3acente( na ) )igra#o*at+ 3 " &i (' mar( nad3a( i )) ) entonces (mar: Arreglo"%00$)e ,-gico+ *arca que bus7ro( nad3a( i ), mar ) indica si el nodo #ue .isitado (!erdadero) o #si no (/also)+ (i: Entero0: !ariable con la posici-n de los $ i %, pos$ nodos en la matriz (nad3a: Arreglo"%00$)e Entero0+ !ector au4iliar que contiene los nodos ad3acentes

bsqueda en pro#undidad lista


Versin 1.0

recorridoEn7ro#( ) {pre: g+n 0 } {pos: marca ( i ) !erdadero i} 1 " marca( i ) #also $ i %, g+numEle( ) ( g: )e#inido en )igra#o,is 2 " &i ( ' marca( i ) ) entonces (marca: Arreglo"%00$)e ,-gico+ *arca que bus7ro( i, marca) indica si el nodo #ue .isitado (!erdadero) o no (/also)+ #si $ i %, g+numEle( ) (i: Entero: !ariable au4iliar para los nodos

T(n) = (mx(N,A))

bsqueda en pro#undidad lista


Versin 1.0

bus7ro(Entero0: na, Arreglo"%00$)e ,-gico: mar ) {pre: g+n 0 % 1 na 1 g+n} {pos: marca ( i ) !erdadero i} 1 mar( na ) !erdadero (g, nodoAd3acente( ): )e#inidos en 2 nad3a nodoAd3acente( na ) )igra#o,is 3 nad3a+cursorAl6nicio( ) (mar: Arreglo"%00$)e ,-gico+ *arca que "&i('mar(nad3a+con,ista()+6n#o())) indica si el nodo #ue .isitado (!erdadero) o entonces no (/also)+ bus7ro(nad3a+con,ista()+6n#o(), mar (i: Entero0: !ariable au4iliar ) (nad3a: ,ista"Entero0$+ ,ista au4iliar que #si contiene los nodos ad3acentes nad3a+cursorAl7ro4imo( ) (cursorAl6nicio( ), numEle( ), con,ista( ), $ i %, nad3a+numEle( ) cursorAl7ro4imo( )+ )e#inidos en ,ista

// versin recursiva del algoritmo DFS void DFS(int v){ list<int>::iterator aux, fin;//iteradores para lista de ady visitado[v] = 1;//marcar como visitado //aqui se podria marcar el orden en que fueron visitados aux = grafo[v].begin();//posicionar los iteradores para lista de ady fin = grafo[v].end(); while(aux != fin){ if(!visitado[*aux]) DFS(*aux);//no se necesita marcar porque *aux se convierte en v aux++;//avanzar al siguiente adyacente de v } }

// versin para grafos que no estn completamente conectados void DFS2(){ int i; for(i = 0; i < nvert; i++)//buscar un nuevo nodo de inicio que no ha sido visitado if(!visitado[i]) DFS(i); }

int tiempo; /* global */ int d[N], f[N], p[N], color[N]; /* Arreglos de tiempo de entrada, tiempo de salida, padres, y color */ DFS(G) { /* pseudo-cdigo */ for ( cada vrtice u V[G]) { color [u] =Blanco; p[u] = NULL; } tiempo = 0; for (cada vrtice u V[G]) if (color[u] == Blanco) DFS_visit(u); } DFS_visit (u) /* pseudo-cdigo */ color [u]= Plomo; /* Vrtice Blanco u es visitado, ingresamos a su subrbol */ d[u] = ++tiempo; /* el tiempo avanza cada vez que entramos o salimos de un nodo*/ for ( cada v Adj [u] ) { /* explora arcos (u,v) */ if (color [v] == Blanco) { p [v] = u; DFS_visit(v); } } color [u] = Negro; /* ennegrezca u, salimos de su sub-rbol */ f [u] = ++tiempo; }

bsqueda en profundidad
Si el grafo es conexo, se tendr un nico rbol de recorrido en profundidad Si el grafo no es conexo, se tendr un bosque de rboles, uno por cada componente conexo Un nodo v es un punto de articulacin si el subgrafo obtenido al borrar todas las aristas que incidan en v ya no es conexo
1

2 4

13 5

Grafo biconexo y bicoherente


Un grafo G es biconexo si es conexo y no tiene puntos de articulacin Ejemplo: si G representa una red de telecomunicaciones, entonces G asegura que la red puede seguir funcionando aunque falle uno de los equipos de los nodos. Un grafo G es bicoherente si todo punto de articulacin est unido mediante al menos 2 aristas con cada componente del subgrafo restante Si adems de biconexo, G es bicoherente, se tiene la seguridad que la red seguir funcionando aunque falle una lnea de transmisin

bsqueda en pro#undidad lista


Versin 1.0

puntos)eArticulacion( ) {pre: 898 : 0 } {pos: 898 : 0 ;< ; padre bosque en pro#undidad } 1 recorridoEn7ro#() (na, 4: Entero+ 9odo actual 3 2 =ecorrer > en posorden 3 para cada nodo nodo @ijo del actual+ 3 na se calcula masalto(na) (recorridoEn7ro#()+ =ealiza la bsqueda en " &i (na ra?z na no tiene mas de % @ijo ) pro#undidad calculando prenum de cada entonces nodo na es un punto de articulaci-n ( &e numeran los nodos de ; con prenum sino &i (na A ra?z na tiene un @ijo 4 B @aciendo el recorrido en pro#undidad masalto(4) prenum(na)) entonces (preorden) na es un punto de articulaci-n (calcula el .alor de masalto para cBnodo masalto(.) m?n(prenum(.), prenum(C), #si $ na 9 masalto(4)) )onde, .) es el nodo actualD (C) Es el nodo antecesor de . alcanzable por una arista que no pertenece a las aristas del Erbol del recorrido en pro#undidadD (4) >odo @ijo de . desde los cuales se puede recorrer @asta un antecesor de .

Algoritmo para determinar grafo conexo usando bsqueda en profundidad


bool Graph::is_connected() { If (_n <= 1) return true; vector<bool> visit(_n); vector<bool>::iterator iter; for(iter = visit.begin(); iter != visit.end(); iter++) *iter = false; set<int> forvisit; set<int>::iterator current; forvisit.insert(0); while (!forvisit.empty()) { current = forvisit.begin(); if (!visit[*current]) { for (int i = 0; i < _n; i++) { if (_graph[*current][i] == 1 && !visit[i]) forvisit.insert(i); } } visit[*current] = true; forvisit.erase(current); } bool result; for (iter = visit.begin(); iter != visit.end(); iter++) result = result && *iter; return result;

Grafos Ordenamiento topolgico

Ordenamiento topolgico
Resuelve el problema de encontrar el orden en que se deben llevar a cabo una serie de actividades cuando existen requisitos de actividades previas a realizar como puede ser la currculo de materias a estudiar en una universidad. Muchas actividades requieren de dicha planeacin

Ordenacin
El orden topolgico tiene sentido slo en grafos acclicos dirigidos (DAG). Orden topolgico de un DAG G=(V,E) es un orden lineal de todos los vrtices tal que si G contiene el arco (u,v), entonces u aparece antes que v en el orden. Cuando se tienen muchas actividades que dependen parcialmente unas de otras, este orden permite definir un orden de ejecucin sin conflictos. Grficamente se trata de poner todos los nodos en una lnea de manera que slo haya arcos hacia delante. Algoritmo:
1. Llamar a DFS(G) para calcular el tiempo de trmino f[v] para cada vrtice. 2. Insertar cada nodo en una lista enlazada segn su orden de trmino. 3. Retornar la lista enlazada

Ordenacin
Orden parcial es una relacin reflexiva, antisimtrica y transitiva.

Dominio: es un conjunto de valores Ejm: D1 = {rojo, verde, negro, azul} D2 = {ford, chevrolet, fiat`, toyota, renault}

Relacin: es un subconjunto del producto cartesiano de una lista de dominios, no necesariamente disjuntos. Ejm: R1 = {(rojo, ford), (verde, ford), (negro, chevrolet), (azul, toyota)} R2 = {(fiat, verde)} R3 = { }

Ordenacin
Reflexividad: Una relacin R es reflexiva si X R X para todo X en S. Simetra: Una relacin R es simtrica si X R Y implica Y R X para todo X y Y. Antisimetra: Una relacin R es antisimtrica, si X R Y y Y R X implica X = Y, para todo X y Y. La relacin es antisimtrica, x p y p x implica que x=p Transitividad: Una relacin R es transitiva si X R Y y Y R Z implica que X R Z, para todo X, Y, Z.

Un orden parcial (toda relacin antisimtrica y transitiva) tiene un digrafo acclico

Ordenacin
Un orden topolgico de los nodos de un digrafo G={N, A} es una secuencia (n1, n2, , nk) tal que N= {n1, n2, , nk} y para todo (ni, nj) en N, ni precede a nj en la secuencia.

Aplicaciones:
Modelado de actividades para resolver problemas de planificacin o programacin de las mismas siguiendo un criterio de minimizacin o maximizacin. Evaluacin de expresiones aritmticas (- b + sqrt( b * b - 4 * a * c)) / 2 * a ( - b - sqrt(b * b - 4 * a * c)) / 2 * a

Cul es el orden topolgico?

Es ste el nico orden topolgico?

Algoritmo genrico de ordenamiento topolgico


Versin 1.0

orden>opologico( ): ,ista {pre: n : 0 } {pos: n 0 } 1 ( n : 0 ) " . nodo con gin 0 (.: Entero+ 9odo del digra#o+ 2 elimine . 3 todas las aristas que salen (inser,ista()+ )e#inida en ,ista+ 3 de . (s+ ,ista+ ,ista que contiene el s+inser,ista(.) $ orden topol-gico de los nodos del gra#o+ regrese s ( gin: grado de incidencia negati.o

b a c

d f e

d f e c

d f e

v=a, s={ }, n=6

v=b, s={a}, n=5

v=c, s={a, b}, n=4

ORDENAMIENTO_TOPOLOGICO(G) DFS(G) y calcular f[v] para cada v en G Conforme se termina de visitar un vrtice insertar al frente de una lista Devolver la lista como resultado DFS(G) Para cada nodo u en G color[u] = blanco padre[u] = NULO tiempo = 0 Para cada nodo u en G Si color[u] = blanco DFS-VISIT(u) DFS-VISIT(u) color[u] = gris //se acaba de visitar el nodo u por primera vez tiempo = tiempo + 1 d[u] = tiempo Para cada nodo v que se adyacente a u //explorar aristas (u,v) si color[v] = blanco padre[v] = u DFS-VISIT(v) color[u] = negro //se termino de visitar al nodo u y todos sus adyacentes tiempo = tiempo + 1 f[u] = tiempo

Componentes fuertemente Conexas


Un componente fuertemente conexo de un grafo G=(V,E) es el mximo conjunto de vrtices U subconjunto de V tal que para cada par de vrtices u, v en U, existan caminos desde u a v y viceversa. Algoritmo que descubre todos las componentes fuertemente conexos. Para ello define el grafo traspuesto de G, GT= (V,ET), donde ET={(u,v) tal que (v,u) pertenece a E}. En otras palabras, invierte el sentido de todas los arcos.

Algoritmo Strongly_Connected_Components(G) 1.- Llamar a DFS(G) para obtener el tiempo de trmino f[u], para cada vrtice u; 2.- Calcular GT; 3.- Llamar a DFS(GT), pero en el lazo principal de DFS, considerar los vrtices en orden decreciente de f[u]. 4.- La salida son los vrtices de cada rbol del paso 3. Cada rbol es una componente fuertemente conexo separada.

You might also like