Post on 05-Jan-2016
description
GRAFOS
ESTRUCTURAS DE DATOS
COMPONENTES CONEXAS De un grafo no dirigido
Se pude saber si es conexo Si no lo es se pueden conocer sus
Componentes Conexas Conjunto W, de vértices del grafo En el cual hay camino desde cualquier V1 a cualquier V2 Donde V1 y V2 pertenecen a W
A
C
B
D
EA
C
B
D
E
CONEXO
No CONEXO
Componentes conexas: entre ellas
son conexas
ALGORTIMO: DETERMINAR CONEXIÓN Si entre todos los vértices, hay camino
Un recorrido desde cualquier vértice Visitara a TODOS los vértices del grafo
Si no Tendremos una componente conexa
Conjunto de vértices recorrido
Para descubrir otras Repetir recorrido desde un vértice no visitado Hasta que todos los vértices hayan sido visitados
EJEMPLO
A
C
B
D
EA
C
B
D
E
Recorrido desde E
E C D A B
Conjunto recorridos = Conjunto de Vertices
Es CONEXO
Recorrido desde E
E C D
Componente Conexa
W1
Recorrido desde B
B A
Componente Conexa
W2
IMPLEMENTACION
bool ComponentesConexas(Grafo G, LSE *LComponentes){Vertice *V;LSE *LRecorrido;while(TRUE){
V = BuscarVerticeNoVisitado(G);if(!V) break;LRecorrido = RecorrerAnchura(G,*V);LSE_InsertarNodoFin(LComponentes,
LSE_CrearNodo(LRecorrido));}if(LComponentes->header == LComponentes->last) return TRUE;return FALSE;
}
No olvidar: Luego de recorrer,
obtendremos un conjunto de vertices
LRecorrido
Las componentes forman una Lista
de Listas
COMPONENTES FUERTEMENTE CONEXAS De un grafo DIRIGIDO
Se puede saber si es FUERTEMENTE CONEXO Si no lo es se pueden conocer sus
Componentes Fuertemente Conexas Conjunto W, de vertices del grafo En el cual hay camino desde cualquier V1 a cualquier V2 Donde V1 y V2 pertenecen a W
4
5
6
8
No CONEXO
CONEXO
C
F
H
B
S
Componentes
ALGORITMO Dado un Vo, se desea conocer
Los vertices a los que se puede llegar (D) Los vertices que llegan a Vo (A)
Si D interseccion A = V entonces Hay camino entre cualquier par de vertices Fuertemente conexo
Si no Tendremos una componente conexa
Conjunto de vertices recorrido Para descubrir otras
Repetir recorrido desde vertice que no sea elemento de una C.F.C. Hasta que todos los vertices esten en C.F.C
EJEMPLO
C
F
H
B
S
1) Recorrer desde B (Descendientes)
B S CD =
2) Invertir Direcciones3) Recorrer desde B (Ascendientes)
B C FA = H S
W = D A
W1 = {B, C, S}
W <> V, Componente F.C.
1) Recorrer desde H (Descendientes)
H F CD = B S
3) Recorrer desde H (Ascendientes)
HA =
W2 = {H}
1) Recorrer desde F (Descendientes)
D = F C B S
3) Recorrer desde F (Ascendientes)
F HA =
W3 = {F}
C
F
H
B
S
PUNTOS DE ARTICULACION En un grafo no dirigido conexo Existen vertices que si se eliminan
“Desconectan” al Grafo Lo dividen en componentes conexas
Estos vertices “clave” Son puntos de articulacion
Si un grafo no tiene P.A. Es biconexo
La conectividad de un grafo Es el numero de nodos que se necesitan eliminar Para dejar a un grafo “desconectado”
EJEMPLO
A
D
C
B
E
F
Puntos de Articulacion
ARBOL DE EXPANSION
Para poder calcular los P.A. de un grafo Hay que obtener el arbol de expansion
Este se obtiene A partir del Recorrido en Profundidad
EjemploA
D
C
B
E
F
A
C
F
E
B
D
Arco en Retroceso: Cuando se quiere visitar un nodo que ya ha sido visitado y no es el padre
COMO REPRESENTAR EL ARBOL DE EXPANSION
Un arbol en expansion No es un arbol binario Cada Vertice puede tener 0, 1 o n hijos Si sabemos que CADA VERTICESOLO TIENE UN PADRE
Si no tomamos en cuenta los Arcos en Retroceso
La representacion depende del Grafo Matriz de Ady -> Usar un arreglo o Lista de Ady -> Una lista
La representacion mostrará Quien es el padre de cada nodo
ARBOL DE EXPANSIONCON MATRIZ DE ADY. Los vertices del grafo
Se encuentran en un arreglo Cada indice del arreglo
Representa un vertice Ej: A – 0, B – 1, etc
Al representar el arbol de expansion El padre(indice) de cada nodo Puede almacenarse en un arreglo
Que tambien represente a los vertices
A
D
C
B
E
F
0 4 0 0 5 2
0
A
1
B
2
C
3
D
4
E
5
Ftypedef struct TVertices{
Generico V[MAX];
int Padres[MAX];
int nvertices;
}Vertices;
ARBOL DE EXP. CON LISTA DE ADYACENCIA Los vertices del grafo
Se encuentran en una lista Cada nodo
Representa un vertice
Al representar el arbol de expansion De cada nodo de esta lista
Solo nos interesa conocer al padre
Se puede añadir un dato al nodo vertice Un enlace con el padre
A
D
C
B
E
F
A
B
C
D
E
F
typedef struct Vertice{
Generico Informacion;
Vertice *padre;
Lista *LArcos;
}Vertice;
ALGORITMO: ENCONTRAR P.A. A cada vertice numerarlo
De acuerdo al recorrido Se obtiene Num(v)
A c/vertice, calcular Bajo(v) Minimo entre
Num(v) Num(arco_retroceso de v) Bajo(hijos de v)
P.A. son La raiz si tiene >= 2 hijos Vertices para los cuales
Algun Bajo(hijo de v) >= Num(v)
A
C
F
E
B
D
1
2 3
4
5
6
Num(v) se calcula a medida que se genera el Arbol de Expansion
Para calcular Bajo(v), se
necesita bajar hasta conocer los Bajos(hijos de v)
Min(6, 3, ----)
,3Min(5, ---, 3)
,3Min(4, ---, 3)
,3
Min(3, --, 3)
,3
Min(2, --, --)
,2
Min(1, --, 2),1
C es P.A.
A es P.A.
CAMBIOS EN EL ARBOL Tanto Num(v) como Bajo(v)
Deben ser parte ahora de la estructura Del arbol
typedef struct TVertices{
Generico V[MAX];
int Padres[MAX];
int Num[MAX];
int Bajo[MAX];
int nvertices;
}Vertices;
typedef struct Vertice{
Generico Informacion;
int Num, Bajo;
Vertice *padre;
Lista *LArcos;
}Vertice;
COMO IMPLEMENTAR?? Primero
Que representacion se usara? Si es M.A.
Usar Arbol de Expansion como un tipo aparte Si es L.A.
Usar Grafo para trabajar con Arbol de Exp. Luego
Recorrer el grafo Para llenar Num y enlazar a los padres
Calcular Bajo Y con esta informacion decidir cual es punto de art.
IMPLEMENTACIONCALCULAR NUM y PADRES
//Al recorrer, llenar Num y enlazar con los padres
void RecorrerParaArbol(Grafo G, Vertice *V, int *vez){
int i;
LSE_nodo *p;
V->visitado = TRUE;
*vez++;
((Vertice *)(p->G))->Num = *vez;
for(p = V->LA->header; p!=NULL; p= p->sig){
if(!((Vertice *)(p->G))->Visitado){
RecorrerParaArbol(G, p->G, vez);((Vertice *)p->G)->padre = V;
}
}
Al vertice de origen, marcar como vistado y contarlo, hay que llevar rastreo del aumento del contador
IMPLEMENTACION CALCULAR BAJO
//Para calcular el Bajo de Vorigen, calcular Bajo de los hijos(en recorrido9//Es decir, recorrer otra vez el grafo para poder “bajar” x el mismovoid CalcularBajo(Grafo G, Vertice *V ){
int i;LSE_nodo *p;Vertice *Ad;V->visitado = TRUE;V->Bajo = V->Num;for(p = V->LA->header; p!=NULL; p= p->sig){
Ad = Generico_ObtenerVertice(p->G);if(!Ad->Visitado){
CalcularBajo(G, Ad);if(Ad->Bajo < V->Bajo) V->Bajo = A->Bajo;
}else if(V->padre!=Ad)if(Ad->Num < V->Bajo) V->Bajo = Ad-
>Num;}
}
Antes de llamar a esta funcion, el grafo debe de volver a quedar como si
no se hubiese recorrido antes
Calcular el bajo del hijo, si es menor
que el actual, cambiarlo
Si ya fue visitado y no es el padre: arco en retroceso
EJERCICIO Escriba una funcion que dado un Grafo permita
conocer los puntos de Articulacion del mismo Recuerde que los P.A. son vertices