Strutture dati per grafi Visita di un grafo Laboratorio di Algoritmi e Strutture Dati Ingegneria e Scienze Informatiche - Cesena A.A. 2013-2014 Pietro Di Lena [email protected], [email protected] Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Lista di adiacenza Matrice di adiacenza Lista di adiacenza Struttura dati per la rappresentazione in memoria di grafi (diretti e pesati) Occupazione in spazio: O(|V | + |E |) (|V | = numero di vertici, |E | = numero di archi) Verifica dell’esistenza di un arco tra due vertici v 1, v 2: O(outdegree(v 1)) Visita dei vertici adiacenti ad un vertice v : O(outdegree(v )) b 0 1 d a a,0 b d,1 c e,4 d e,1 e b,5 b,1 1 5 a 2 1 3 c 4 e Pietro Di Lena d,2 Laboratorio di Algoritmi e Strutture Dati c,3 Strutture dati per grafi Visita di un grafo Lista di adiacenza Matrice di adiacenza Nota: formato di un grafo in file di testo Possibile formato di testo per un grafo: Prima riga: numero di vertici nel grafo. Righe successive alla seconda: <id vertice1> <id vertice2> <peso dell’arco diretto tra vertice1 e vertice2> Per semplicit` a utilizziamo valori interi tra 0 e n − 1 per le label dei vertici. 5 0 0 0 1 2 3 4 4 2 1 0 3 4 4 3 1 3 1 0 1 4 2 2 5 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Lista di adiacenza Matrice di adiacenza Nota: lettura di un grafo da file in lista di adiacenza 1/2 Definizione della struttura vertice per una lista di adiacenza. typedef struct VERTEX { int id ; int dist ; struct VERTEX * next ; } VERTEX ; VERTEX * VertexAlloc ( int id , int dist ) { VERTEX * v = ( VERTEX *) malloc ( sizeof ( VERTEX ) ) ; v - > id = id ; v - > dist = dist ; v - > next = NULL ; return v ; } Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Lista di adiacenza Matrice di adiacenza Nota: lettura di un grafo da file in lista di adiacenza 2/2 Lettura di un grafo da file in lista di adiacenza. VERTEX ** AdjListRead ( char * file , int * n ) { FILE * in = fopen ( file ," r ") ; VERTEX ** AdjList ; int i ,j , dist ; if ( in == NULL ) return NULL ; if ( fscanf ( in ,"% d " , n ) == EOF ) return NULL ; AdjList = ( VERTEX **) calloc (* n , sizeof ( VERTEX *) ) ; while ( fscanf ( in ,"% d % d % d \ n " ,&i ,& j ,& dist ) != EOF ) if (i >=0 && i <* n && j >=0 && j <* n ) { VERTEX * tmp = VertexAlloc (j , dist ) ; tmp - > next = AdjList [ i ]; AdjList [ i ] = tmp ; } fclose ( in ) ; return AdjList ; } Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Lista di adiacenza Matrice di adiacenza Matrice di adiacenza Struttura dati per la rappresentazione in memoria di grafi (diretti e pesati) Occupazione in spazio: O(|V |2 ) (|V | = numero di vertici) Verifica dell’esistenza di un arco tra due vertici v 1, v 2: O(1) Visita dei vertici adiacenti ad un vertice v : O(|V |) b 0 1 b c d e 0 1 3 - - b - - - 1 - c - - - - 4 d - - - - 1 e - 5 - 2 - d 1 5 a a a 2 1 3 c 4 e Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Lista di adiacenza Matrice di adiacenza Nota: lettura di un grafo da file in matrice di adiacenza 1/2 Definizione della struttura dati matrice di adiacenza. Adottiamo, come possibile scelta implementativa, il valore INT MIN per indicare un arco non esistente. # include < limits .h > # define NIL INT_MIN int ** MatrixAlloc ( int n ) { int i ,j ,** m =( int **) calloc (n , sizeof ( int *) ) ; m [0]=( int *) calloc ( n *n , sizeof ( int ) ) ; for ( i =0; i < n ; i ++) m [ i ]=& m [0][ n * i ]; for ( i =0; i < n ; i ++) for ( j =0; j < n ; j ++) m [ i ][ j ]= NIL ; return m ; } Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Lista di adiacenza Matrice di adiacenza Nota: lettura di un grafo da file in matrice di adiacenza 2/2 Lettura di un grafo da file in matrice di adiacenza. int ** AdjMatrixRead ( char * file , int * n ) { FILE * in = fopen ( file ," r ") ; int ** AdjMatrix ; int i ,j , dist ; if ( in == NULL ) return NULL ; if ( fscanf ( in ,"% d " , n ) == EOF ) return NULL ; AdjMatrix = MatrixAlloc (* n ) ; while ( fscanf ( in ,"% d % d % d \ n " ,&i ,& j ,& dist ) != EOF ) if (i >=0 && i <* n && j >=0 && j <* n ) AdjMatrix [ i ][ j ]= dist ; fclose ( in ) ; return AdjMatrix ; } Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Lista di adiacenza Matrice di adiacenza Nota: struttura dati generica per grafi typedef struct GRAPH { VERTEX ** AdjList ; // Lista di adiacenza int ** AdjMatrix ; // Matrice di adiacenza int n ; // Numero di vertici nel grafo int * c ; // Colore int * p ; // Predecessore ( DFS ) int * s ; // Inizio visita ( DFS ) int * t ; // Fine visita ( DFS ) int * d ; // Distanza ( BFS ) } GRAPH ; GRAPH * GraphAlloc ( int n ) { GRAPH * G = ( GRAPH *) malloc ( sizeof ( GRAPH ) ) ; G->n = n; G - > AdjList = NULL ; G - > AdjMatrix = NULL ; G->c = ( int *) calloc (n , sizeof ( int ) ) ; G->p = ( int *) calloc (n , sizeof ( int ) ) ; G->s = ( int *) calloc (n , sizeof ( int ) ) ; G->t = ( int *) calloc (n , sizeof ( int ) ) ; G->d = ( int *) calloc (n , sizeof ( int ) ) ; return G ; } Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Lista di adiacenza Matrice di adiacenza Nota: lettura di un grafo da file GRAPH * G ra p hR ea d By A d j L i s t ( char * file ) { GRAPH * G ; VERTEX ** AdjList ; int n ; if (( AdjList = AdjListRead ( file ,& n ) ) == NULL ) return NULL ; G = GraphAlloc ( n ) ; G - > AdjList = AdjList ; return G ; } GRAPH * G r a p h R e a d B y A d j M a t r i x ( char * file ) { GRAPH * G ; int ** AdjMatrix ; int n ; if (( AdjMatrix = AdjMatrixRead ( file ,& n ) ) == NULL ) return NULL ; G = GraphAlloc ( n ) ; G - > AdjMatrix = AdjMatrix ; return G ; } Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search La ricerca in profondit` a (Depth First search) `e una procedura (ricorsiva) di vista di un grafo. Dato un vertice sorgente, produce un albero di copertura per la componente connessa a cui appartiene il vertice sorgente. Utilizzando dei marcatori di inizio e fine visita di un vertice, pu` o essere utilizzata per calcolare un ordinamento topologico nei grafi diretti e aciclici (DAG). Costo computazionale: O(|V | + |E |). Informazioni aggiuntive utilizzate dalla DFS: colore di un nodo (c[]): WHITE (non visitato), GREY (in visita), BLACK (gi` a visitato) puntatore al padre (p[]): contiene le informazione per ricostruire l’albero di copertura inizio visita (s[]): marcatore temporale intero fine visita (t[]): marcatore temporale intero Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: esempio p[b]=NIL s[b]=NIL t[b]=NIL time=0 b 0 p[d]=NIL s[d]=NIL t[d]=NIL 1 d 1 p[a]=NIL s[a]=NIL t[a]=NIL 5 a 2 1 3 c p[c]=NIL s[c]=NIL t[c]=NIL Pietro Di Lena 4 e p[e]=NIL s[e]=NIL t[e]=NIL Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: esempio p[b]=NIL s[b]=NIL t[b]=NIL time=1 b 0 p[d]=NIL s[d]=NIL t[d]=NIL 1 d 1 p[a]=NIL s[a]=1 t[a]=NIL 5 a 2 1 3 c p[c]=NIL s[c]=NIL t[c]=NIL Pietro Di Lena 4 e p[e]=NIL s[e]=NIL t[e]=NIL Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: esempio p[b]=a s[b]=2 t[b]=NIL time=2 b 0 p[d]=NIL s[d]=NIL t[d]=NIL 1 d 1 p[a]=NIL s[a]=1 t[a]=NIL 5 a 2 1 3 c p[c]=NIL s[c]=NIL t[c]=NIL Pietro Di Lena 4 e p[e]=NIL s[e]=NIL t[e]=NIL Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: esempio p[b]=a s[b]=2 t[b]=NIL time=3 b 0 p[d]=b s[d]=3 t[d]=NIL 1 d 1 p[a]=NIL s[a]=1 t[a]=NIL 5 a 2 1 3 c p[c]=NIL s[c]=NIL t[c]=NIL Pietro Di Lena 4 e p[e]=NIL s[e]=NIL t[e]=NIL Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: esempio p[b]=a s[b]=2 t[b]=NIL time=4 b 0 p[d]=b s[d]=3 t[d]=NIL 1 d 1 p[a]=NIL s[a]=1 t[a]=NIL 5 a 2 1 3 c p[c]=NIL s[c]=NIL t[c]=NIL Pietro Di Lena 4 e p[e]=d s[e]=4 t[e]=NIL Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: esempio p[b]=a s[b]=2 t[b]=NIL time=5 b 0 p[d]=b s[d]=3 t[d]=NIL 1 d 1 p[a]=NIL s[a]=1 t[a]=NIL 5 a 2 1 3 c p[c]=NIL s[c]=NIL t[c]=NIL Pietro Di Lena 4 e p[e]=d s[e]=4 t[e]=5 Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: esempio p[b]=a s[b]=2 t[b]=NIL time=6 b 0 p[d]=b s[d]=3 t[d]=6 1 d 1 p[a]=NIL s[a]=1 t[a]=NIL 5 a 2 1 3 c p[c]=NIL s[c]=NIL t[c]=NIL Pietro Di Lena 4 e p[e]=d s[e]=4 t[e]=5 Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: esempio p[b]=a s[b]=2 t[b]=7 time=7 b 0 p[d]=b s[d]=3 t[d]=6 1 d 1 p[a]=NIL s[a]=1 t[a]=NIL 5 a 2 1 3 c p[c]=NIL s[c]=NIL t[c]=NIL Pietro Di Lena 4 e p[e]=d s[e]=4 t[e]=5 Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: esempio p[b]=a s[b]=2 t[b]=7 time=8 b 0 p[d]=b s[d]=3 t[d]=6 1 d 1 p[a]=NIL s[a]=1 t[a]=NIL 5 a 2 1 3 c p[c]=a s[c]=8 t[c]=NIL Pietro Di Lena 4 e p[e]=d s[e]=4 t[e]=5 Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: esempio p[b]=a s[b]=2 t[b]=7 time=9 b 0 p[d]=b s[d]=3 t[d]=6 1 d 1 p[a]=NIL s[a]=1 t[a]=NIL 5 a 2 1 3 c p[c]=a s[c]=8 t[c]=9 Pietro Di Lena 4 e p[e]=d s[e]=4 t[e]=5 Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: esempio p[b]=a s[b]=2 t[b]=7 time=10 b 0 p[d]=b s[d]=3 t[d]=6 1 d 1 p[a]=NIL s[a]=1 t[a]=10 5 a 2 1 3 c p[c]=a s[c]=8 t[c]=9 Pietro Di Lena 4 e p[e]=d s[e]=4 t[e]=5 Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: esempio Albero di copertura prodotto dalla DFS a partire dal vertice sorgente a. a [2,7] b [3,6] d [4,5] e Pietro Di Lena [1,10] c [8,9] Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Depth First Search: pseudocodice 1: procedure DFS(G , u) 2: for each vertex v in G do 3: c[v ] ← WHITE 4: p[v ] ← s[v ] ← t[v ] ← NIL 5: end for 6: time ← 0 7: DFS-Visit(G , u) 8: end procedure 1: procedure DFS-Visit(G , u) 2: c[u] ← GREY 3: s[u] ← time ← time + 1 4: for each vertex v in G adj to u do 5: if c[v]=WHITE then 6: p[v ] ← u 7: DFS-Visit(G , v ) 8: end if 9: end for 10: c[u] ← BLACK 11: t[u] ← time ← time + 1 12: end procedure Quale implementazione ` e maggiormente efficiente: con liste o matrici di adiacenza? Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Strutture dati per grafi Visita di un grafo Depth First Search: esempio Depth First Search: pseudocodice Nota: come generare un grafo random Genera un grafo random di n vertici. L’argomento prob, controlla la probabilit` a che esista un arco tra due nodi. L’argomento maxdist controlla la distanza massima tra due nodi connessi. # include < stdio .h > # include < stdlib .h > # include < time .h > int main ( int argc , char * argv []) { int n , max ,i , j ; double prob ; if ( argc !=4) { fprintf ( stderr ," Usage : randgraph <n > < prob edge > < maxdist >\ n ") ; return 1; } n = atoi ( argv [1]) ; prob = atof ( argv [2]) ; max = atoi ( argv [3]) ; srand ( time ( NULL ) ) ; printf ("% d \ n " , n ) ; for ( i =0; i < n ; i ++) for ( j =0; j < n ; j ++) if (1.0* rand () / RAND_MAX < prob ) printf ("% d % d % d \ n " ,i ,j , rand () %( max +1) ) ; return 0; } Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati
© Copyright 2024 ExpyDoc