Algoritmi e Strutture Dati (Mod. B) Algoritmi su grafi Ricerca in profondità (Depth-First Search) Parte IV
Algoritmo per il calcolo delle CFC 1 DFS(G) 2 Calcola il grafo trasposto GT 3 DFS(GT) ma esaminando i vertici in ordine decrescente di tempo f[v] di fine visita 4 fornisci i vertici di ogni albero della foresta DF prodotta al passo 3 come una diversa CFC
Correttezza di CFC(G) Teorema: CFC(G) calcola correttamente le compo-nenti fortemente connesse del grafo orientato G. Dimostrazione: Per induzione sul numero di alberi DF trovati durante la DFS di GT, dimostriamo che i vertici di ogni albero DF formano una CFC. Ipotesi induttiva: Ogni albero DF prodotto è una CFC. Passo Base: inizialmente non ci sono alberi precedenti. L’ipotesi induttiva vale banalmente. Infatti: La radice r dell’ultimo albero DF è il vertice termi-nato per ultimo in tutto il grafo G. r raggiunge in G tutti i vertici del suo albero DF i vertici che r raggiunge in GT sono quelli che lo raggiungono in G, quindi otteniamo una CFC di G.
Correttezza di CFC(G) Teorema: CFC(G) calcola correttamente le compo-nenti fortemente connesse del grafo orientato G. Dimostrazione: Passo Induttivo: Consideriamo l’albero DF T con radice r pro-dotto da DFS su GT e sia C(r)={vV: (v)=r}. Dimostriamo che u è aggiunto a T se e solo se uC(r). se: Per il Teorema 2 (sotto), ogni vertice in C(r) viene messo nello stesso albero DF. Poiché r C(r), e r è la radice del nuovo albero DF, ogni elemento di C(r) verrà messo in T dalla DFS su GT Teorema 2: In ogni DFS, tutti i vertici nella stessa CFC compaiono nello stesso albero DF.
Correttezza di CFC(G) Teorema: CFC(G) calcola correttamente le compo-nenti fortemente connesse del grafo orientato G. Dimostrazione: Dimostriamo che u è aggiunto a T se e solo se uC(r). solo se: Dimostriamo che ogni vertice w tale che f[(w)] < f[r] o f[(w)] < f[r] non è posto in T. Per induzione sul numero di alberi costruiti, ogni w tale che f[(w)] > f[r] non è posto in T, poiché quando r è selezionato dal ciclo in DFS, w è già stato messo nell’albero con radice (w). Ogni w tale che f[(w)] < f[r] non può essere posto in T, se così fosse, allora w r e dalla formula (1) e da r = (r) segue che f[(w)] f[(r)]= f[r], che contraddice f[(w)] < f[r]. u v implica che f[(v)] f[(u)] (1)
Correttezza di CFC(G) Teorema: CFC(G) calcola correttamente le compo-nenti fortemente connesse del grafo orientato G. Dimostrazione: Dimostriamo che u è aggiunto a T se e solo se uC(r). solo se: Ogni w tale che f[(w)] < f[r] non può essere posto in T, se così fosse, allora w r e dalla formula (1) e da r = (r) segue che f[(w)] f[(r)]= f[r], che contraddice f[(w)] < f[r]. Quindi, T contiene solo quei vertici u per i quali f[(u)]= r. Cioè, T è proprio uguale alla componenete fortemente connessa C(r), e ciò completa la dimostrazoine
Esercizi su CFC Dal libro di testo: Esercizio 23.5-4 Esercizio 23.5-5
Altre proprietà dei grafi Caratterizzazione di alcune importanti proprietà dei grafi: Percorso di Eulero Circuito di Eulero Cicli di Hamilton e alcune loro applicazioni!
Circuito di Eulero e Percorso di Eulero Un circuito di Eulero di un grafo G è un circuito in G che visita ogni arco di G esattamente una volta. Una percorso di Eulero di un grafo G è un percorso aperto in G che visita ogni arco di G esattamente una volta.
Circuito di Eulero Un vertice v si dice dispari se grad(v) è dispari. Un vertice v si dice pari se grad(v) è pari. Teorema: Sia G un grafo connesso. Allora G ha un circuito di Eulero se e solo se ogni vertice di G è pari.
Dimostrazione Se G ha un circuito di Eulero, allora (il grado di) ogni vertice di G è pari. In un circuito di Eulero, un vertice è incontrato e poi abbandonato da un arco differente, quindi per ogni visita di un vertice, sono necessari due archi. Vale anche per il vertice di partenza e arrivo. La somma degli archi per ogni vertice deve quindi essere pari.
Dimostrazione Se (il grado di) ogni vertice di G è pari, allora G ha un circuito di Eulero. Lo dimostriamo fornendo una procedura generale per costruire un circuito di Eulero, assumendo la condizione sopra.
Dimostrazione Se (il grado di) ogni vertice di G è pari, allora G ha un circuito di Eulero. Lo dimostriamo fornendo una procedura generica per costruire un circuito di Eulero che assume la condizione sopra. Usiamo DFS per trovare i circuiti, eliminando via via ogni arco attreversato. Appena ritorniamo al vertice di partenza, se esistono altri archi, scegliamo uno dei vertici del ciclo trovato per cui esiste ancora un arco. Altrimenti termina. Torniamo al passo
Fusione di Circuiti
Fusione di Circuiti: esempio
Algoritmo per il circuito di Eulero Usiamo DFS per trovare i circuiti, eliminando via via ogni arco attreversato. Appena ritorniamo al vertice di partenza, se esistono altri archi, scegliamo uno dei vertici del ciclo trovato per cui esiste ancora un arco. Altrimenti va la passo Torniamo al passo Fondiamo, nei vertici comuni, i circuiti trovati in un unico circuito come visto prima.
Percorso di Eulero Teorema: Sia G un grafo connesso. G ha un per-corso di Eulero se e solo se G ha esattamente 2 vertici dispari. Inoltre, il percorso parte da uno di questi vertici dispari e termina all’altro vertice dispari.
G ha 2 vertici dispari Ogni vertice di H è pari G ha un percorso di Eulero H ha un circuito di Eulero
Cicli Hamiltoniani An ciclo Hamiltoniano di un grafo G è un ciclo in G che visita ogni vertice di G esattamente una volta. Applicazione: Il commesso viaggiatore. Trovare un ciclo Hamiltoniano in un grafo è un “problema molto complesso”.