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 componenti 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 terminato 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 componenti fortemente connesse del grafo orientato G.
Dimostrazione:
Passo Induttivo: Consideriamo l’albero DF T con radice r prodotto 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 componenti 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 componenti 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 percorso 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
G ha un percorso di Eulero
Ogni vertice di H è pari
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”.