IL PROBLEMA DELLO SHORTEST SPANNING TREE



Похожие документы
Metodi e Modelli per l Ottimizzazione Combinatoria Il problema del flusso di costo minimo

COORDINAMENTO E GESTIONE DI PROGETTI COMPLESSI

Algoritmi e strutture dati. Codici di Huffman

f(x) = 1 x. Il dominio di questa funzione è il sottoinsieme proprio di R dato da

risulta (x) = 1 se x < 0.

Dimensione di uno Spazio vettoriale

MATEMATICA DEL DISCRETO elementi di teoria dei grafi. anno acc. 2009/2010

Il principio di induzione e i numeri naturali.

Ricerca Operativa Esercizi sul metodo del simplesso. Luigi De Giovanni, Laura Brentegani

Sono casi particolari di MCF : SPT (cammini minimi) non vi sono vincoli di capacità superiore (solo x ij > 0) (i, j) A : c ij, costo di percorrenza

1. PRIME PROPRIETÀ 2

LEZIONE 23. Esempio Si consideri la matrice (si veda l Esempio ) A =

Siamo così arrivati all aritmetica modulare, ma anche a individuare alcuni aspetti di come funziona l aritmetica del calcolatore come vedremo.

Sistemi Operativi mod. B. Sistemi Operativi mod. B A B C A B C P P P P P P < P 1, >

4 3 4 = 4 x x x 10 0 aaa

b i 1,1,1 1,1,1 0,1,2 0,3,4

Logica Numerica Approfondimento 1. Minimo Comune Multiplo e Massimo Comun Divisore. Il concetto di multiplo e di divisore. Il Minimo Comune Multiplo

1 Serie di Taylor di una funzione

Esercizi su lineare indipendenza e generatori

Sequenziamento a minimo costo di commutazione in macchine o celle con costo lineare e posizione home (In generale il metodo di ottimizzazione

APPUNTI DI MATEMATICA LE FRAZIONI ALGEBRICHE ALESSANDRO BOCCONI

Lezione 9: Cambio di base

APPUNTI SU PROBLEMI CON CALCOLO PERCENTUALE

PROBLEMA DELLA RICERCA DI UN ELEMENTO IN UN ARRAY E ALGORITMI RISOLUTIVI

Iniziamo con un esercizio sul massimo comun divisore: Esercizio 1. Sia d = G.C.D.(a, b), allora:

Esercizi Capitolo 6 - Alberi binari di ricerca

Sommario. Definizione di informatica. Definizione di un calcolatore come esecutore. Gli algoritmi.

Soluzione dell esercizio del 2 Febbraio 2004

Lezioni di Matematica 1 - I modulo

Appunti sulla Macchina di Turing. Macchina di Turing

A intervalli regolari ogni router manda la sua tabella a tutti i vicini, e riceve quelle dei vicini.

Fasi di creazione di un programma

2.1 Definizione di applicazione lineare. Siano V e W due spazi vettoriali su R. Un applicazione

LA TRASMISSIONE DELLE INFORMAZIONI QUARTA PARTE 1

CRITERI DI CONVERGENZA PER LE SERIE. lim a n = 0. (1) s n+1 = s n + a n+1. (2) CRITERI PER LE SERIE A TERMINI NON NEGATIVI

Politecnico di Milano. Facoltà di Ingegneria Industriale. Corso di Analisi e Geometria 2. Sezione D-G. (Docente: Federico Lastaria).

1 Applicazioni Lineari tra Spazi Vettoriali

Matematica in laboratorio

Analisi di una Rete Sociale

Esercitazione #5 di Statistica. Test ed Intervalli di Confidenza (per una popolazione)

Equilibrio bayesiano perfetto. Giochi di segnalazione

Corso di Matematica per la Chimica

1 Giochi a due, con informazione perfetta e somma zero

Algoritmi e Strutture Dati

Capitolo 2. Operazione di limite

UNA LEZIONE SUI NUMERI PRIMI: NASCE LA RITABELLA

Ottimizzazione Multi Obiettivo

Parte 2. Determinante e matrice inversa

Proof. Dimostrazione per assurdo. Consideriamo l insieme complementare di P nell insieme

Matematica generale CTF


Politecnico di Milano Facoltà di Ingegneria dell Informazione AGENTI AUTONOMI E SISTEMI MULTIAGENTE Appello COGNOME E NOME

Cenni su algoritmi, diagrammi di flusso, strutture di controllo

PROBABILITÀ - SCHEDA N. 2 LE VARIABILI ALEATORIE

ESEMPIO 1: eseguire il complemento a 10 di 765

LE SUCCESSIONI 1. COS E UNA SUCCESSIONE

e-dva - eni-depth Velocity Analysis

Statistica e biometria. D. Bertacchi. Variabili aleatorie. V.a. discrete e continue. La densità di una v.a. discreta. Esempi.

Ottimizazione vincolata

Grandezze scalari e vettoriali

Osservazioni sulla continuità per le funzioni reali di variabile reale

Università di Trieste Facoltà d Ingegneria. Esercitazioni per la preparazione della prova scritta di Matematica 3 Dott.

Minimo Albero Ricoprente

Il sapere tende oggi a caratterizzarsi non più come un insieme di contenuti ma come un insieme di metodi e di strategie per risolvere problemi.

Indice. 1 Introduzione alle Equazioni Differenziali Esempio introduttivo Nomenclatura e Teoremi di Esistenza ed Unicità...

[MANUALE VISUAL BASIC SCUOLA24ORE PROF.SSA PATRIZIA TARANTINO] 14 dicembre 2008

Per lo svolgimento del corso risulta particolarmente utile considerare l insieme

Grandezze scalari e vettoriali

IGiochidiArchimede-SoluzioniBiennio 22 novembre 2006

La Programmazione Lineare

B9. Equazioni di grado superiore al secondo

Funzioni. Parte prima. Daniele Serra

x u v(p(x, fx) q(u, v)), e poi

Problema del trasporto

Sulle funzioni di W 1,p (Ω) a traccia nulla

a) Determinare i numeri indice a base fissa del fatturato con base 2007=100 e commentare i risultati ottenuti per gli anni 2008 e 2012

13. Campi vettoriali

Attività 9. La città fangosa Minimal Spanning Trees

Le query di raggruppamento

Capitolo 6. Soluzione degli esercizi a cura di Rosa Falotico

Algoritmo. I dati su cui opera un'istruzione sono forniti all'algoritmo dall'esterno oppure sono il risultato di istruzioni eseguite precedentemente.

Gestione Risorse Umane Web

1 Estensione in strategia mista di un gioco

x 2 + y2 4 = 1 x = cos(t), y = 2 sin(t), t [0, 2π] Al crescere di t l ellisse viene percorsa in senso antiorario.

Gestione della memoria centrale

CPM - PERT CPM - PERT. Rappresentazione di un progetto. Gestione di un progetto. Critical Path Method Project Evaluation and Review Technique

Programmazione dinamica

Barriere assorbenti nelle catene di Markov e una loro applicazione al web

Fondamenti di Informatica 2. Le operazioni binarie

A i è un aperto in E. i=1

Capitolo 13: L offerta dell impresa e il surplus del produttore

Prodotto libero di gruppi

b. Che cosa succede alla frazione di reddito nazionale che viene risparmiata?

Un po di statistica. Christian Ferrari. Laboratorio di Matematica

Транскрипт:

IL PROBLEMA DELLO SHORTEST SPANNING TREE n. 1 - Formulazione del problema Consideriamo il seguente problema: Abbiamo un certo numero di città a cui deve essere fornito un servizio, quale può essere l energia elettrica, il gas, l acqua, la fognatura, ecc... ; potenzialmente queste città possono essere collegate tra di loro mediante un elettrodotto, o un gasdotto, acquedotto, ecc.; alcuni di questi collegamenti diretti sono resi impossibili da ostacoli fisici insormontabili o difficilmente sormontabili, quali colline, laghi, ecc.; i collegamenti possibili consentono comunque di collegare tra loro a due a due le diverse cittá, passando per le altre. Si deve decidere quali collegamenti realizzare effettivamente, in maniera da servire tutte le cittá con il minimo costo. Possiamo formalizzare il problema pensando le cittá come nodi di un grafo, e i collegamenti potenziali tra due cittá come archi del grafo. Il grafo é pesato, poiché ad ogni arco puó essere associato il costo di costruzione del collegamento, qualora il collegamento venisse realmente realizzato; inoltre il grafo é non orientato, poiché il costo di costruzione di un qualunque arco (a, b) coincide con il costo dell arco (b, a). Dal momento che i collegamenti devono essere realizzati al minimo costo, non ha senso prevedere di costruire archi che collegano una cittá con se stessa e quindi possiamo supporre che il grafo sia senza lacci. Inoltre il grafo é connesso, poiché si é detto che due cittá sono sempre collegabili mediante un cammino che passa per le altre. I collegamenti che si vanno realmente a realizzare possono essere interpretati come gli archi di un sottografo G = (N, A ) di G; tale sottografo deve essere tale che: (1) due cittá sono sempre raggiungibili una dall altra, e quindi G deve essere connesso, (2) il grafo non deve contenere cicli, altrimenti ci sarebbero degli archi superflui, che comporterebbero un costo aggiuntivo evitabile, (3) tutte le cittá devono essere servite, e quindi deve essere N = N. Pertanto G deve essere un albero tale che N = N; un tale sottografo dicesi spanning tree, cioé albero invadente o ricoprente il grafo G. Naturalmente tra tutti gli alberi invadenti occorre scegliere quello di costo minimo. Pertanto il problema puó essere cosí formalizzato: Dato un grafo non orientato connesso e senza lacci G = (N, A), costruire un sottografo G = (N, A ) che sia un albero invadente e che abbia lunghezza minima tra tutti gli alberi invadenti. n. 2 - Algoritmo di PRIM Il problema testé formulato puó essere risolto in maniera iterativa: ad ogni iterazione si dispone di un sottografo G = (N, A ) che sia un albero, e, (finché N N), si aggiunge un arco ad A, (e i relativi nodi ad N ), in modo che il nuovo sottografo sia ancora un albero; ovviamente la scelta dell arco da aggiungere deve essere funzionale all obiettivo di costruire un albero di lunghezza minima. Ebbene, per individuare l arco (a, b) da aggiungere ad A, osserviamo che: (1) se ad A aggiungiamo un arco (a, b), tale che entrambi gli estremi a e b appartengono ad N, allora il nuovo sottografo contiene dei cicli; (infatti, il cammino unione dell arco (a, b) con il cammino congiungente b con a in G é un ciclo); (2) se ad A aggiungiamo un arco (a, b), tale che entrambi gli estremi a e b non appartengono ad N, allora il nuovo sottografo non é connesso, poiché a e b non sono congiungibili con i nodi di N. 1

2 Pertanto, se vogliamo che il nuovo sottografo sia ancora un albero, dobbiamo aggiungere ad A un arco che congiunge un nodo a N con un nodo b N N. In effetti, si vede facilmente che, se a N e b / N, allora il sottografo G = (N, A ), con N = N {b}, A = A {(a, b)}, é ancora connesso e senza cicli, e quindi é ancora un albero. Infatti, G é connesso poiché: - due nodi distinti di N sono tra loro congiungibili in G e quindi in G, - il nodo b é congiungibile con a mediante l arco (a, b), ed é congiungibile con qualunque a N, a a mediante il cammino unione del cammino congiungente a ad a con l arco (a, b). Inoltre, G non ha cicli; infatti se esistesse un ciclo in G, tale ciclo dovrebbe passare per il nodo b, (altrimenti sarebbe un ciclo in G, contro l ipotesi che G non ha cicli). Ne seguirebbe che il ciclo dovrebbe contenere l arco (a, b) ed un ulteriore arco (b, a ) A, con a a: ma allora ne seguirebbe che b N, mentre b era stato scelto in N N. D altra parte, dovendo cercare l albero invadente di lunghezza minima, sembra ragionevole scegliere, (tra gli archi candidati ad essere aggiunti ad A ), quello di lunghezza minima. Siamo dunque in grado di formulare il seguente Algoritmo di PRIM (0) - (Inizializzazione) - Si sceglie arbitrariamente un nodo a N e si pone N = {a}, A =. (1) - (Fase iterativa) - Finché N N, si cercano ā N, b N N tali che (ā, b) A e l(ā, b) = min {l(a, b) : a N, b N N, (a, b) A}. Si aggiunge b ad N ed (ā, b) ad A. Dopo n 1 iterazioni l algoritmo si interrompe e fornisce un sottografo G che é un albero invadente di lunghezza minima. Infatti é evidente che il sottografo iniziale G = (N, A ), con A =, é un albero; conseguentemente, il sottografo trovato dopo la prima iterazione é un albero. Ma allora anche quello trovato dopo la seconda iterazione é un albero, e in generale il sottografo trovato dopo ogni iterazione é un albero. Pertanto, il sottografo G = (N, A ) trovato dopo n 1 iterazioni é un albero; d altra parte tale albero é invadente, perché, dopo n 1 iterazioni, l insieme N avrá n elementi e quindi coincide con N. E inoltre intuitivo che, avendo ogni volta selezionato l arco piú breve tra quelli candidati, tale albero invadente sia quello di lunghezza minima. I dettagli della dimostrazione della ottimalitá dell albero prodotto dall algoritmo di Prim sono contenuti nella Appendice. Osservazione 2.1 - L algoritmo di Prim puó essere formalizzato in maniera piú dettagliata, utilizzando un contatore k dei nodi giá serviti, una variabile reale MIN che serve per calcolare la minima lunghezza degli archi congiungenti un nodo a N con un nodo b / N, una variab ile NEXT che serve per individuare il prossimo nodo da servire, e due vettori n-dimensionali, LABEL e P RED, per memorizzare i nodi e gli archi giá selezionati, nel senso che per ogni j = 1, 2,..., n risulta: { 1 se aj N, LABEL(j) = 0 altrimenti, j se a j é il nodo iniziale P RED(j) = i > 0 se a j N ed (a i, a j ) A,. 0 se a j / N L algoritmo di PRIM assume allora la forma:

3 Algoritmo di PRIM (0) - (Inizializzazione) - Si sceglie arbitrariamente un nodo, ad esempio a 1 N, e si pone k = 1, LABEL(1) = P RED(1) = 1, LABEL(j) = P RED(j) = 0 per ogni j = 2, 3,..., n. (1) - (Fase iterativa) - Si pone M IN = M, (dove M é un numero molto grande rispetto alle lunghezze degli archi del grafo), e si esegue il ciclo: Per i = 1, 2,..., n e per j = 1, 2,..., n esegui: se LABEL(i) = 1 e LABEL(j) = 0 ed l(a i, a j ) < M, allora poni: MIN = l(a i, a j ), NEXT = j, PRED (NEXT)=i. Alla fine del ciclo si pone k = k + 1, LABEL(NEXT)=1. (2) -(Test di arresto) - Se k = n STOP, altrimenti si torna al Passo 1. Osservazione 2.2 - Alla fine della esecuzione dell algoritmo di Prim, dal vettore P RED si ricostruisce l albero invadente di lunghezza minima: esso é formato dagli n 1 archi (P RED(2), 2), (P RED(3), 3),..., (P RED(n), n). La lunghezza di tale albero é data ovviamente dalla somma delle lunghezze di tali archi. n. 3 - L algoritmo di PRIM-DIJKSTRA L algoritmo di Prim descritto sopra effettua ad ogni iterazione n 2 confronti, prima di individuare il prossimo nodo da servire e il relativo arco da aggiungere. L algoritmo giunge quindi alla soluzione ottima con (n 1) n 2 operazioni, e non é molto efficiente perché non cerca di tenere conto delle informazioni via via acquisite. Un approccio piú efficiente si otterrebbe se ad ogni iterazione noi ricercassimo per ogni nodo a j non ancora scelto l arco piú breve che congiunge a j con i nodi giá scelti, e memorizzassimo, per un successivo utilizzo, la lunghezza LMIN(j) di tale arco e l arco stesso (P RED(j), j). E chiaro, infatti, che la scelta del prossimo arco da aggiungere si restringe a tali archi, e per trovare il prossimo nodo da servire sará sufficiente cercare il nodo non servito per cui si ha il min {LMIN(j) : a j N }. D altra parte, se abbiamo trovato che il nodo da aggiungere é a h ed LMIN(j) rappresenta la lunghezza dell arco piú breve che congiunge a j con i nodi serviti prima dell aggiunta di a h, per trovare l arco piú breve che congiunge a j ai nodi scelti dopo l aggiunta di a h basterá confrontare LMIN(j) con la lunghezza l(h, j) dell arco (a h, a j ). E chiaro, infatti, che se LMIN(j) l(h, h), allora l arco piú breve trovato prima é rimasto competitivo anche dopo l aggiunta di a h ; se peró risulta l(h, j) < LMIN(j), allora l arco piú breve dopo l aggiunta di a h é diventato l arco (a h, a j ), ed occorre quindi sostituire LMIN(j) e P RED(j) trovati prima, rispettivamente, con l(h, j) e h. Siamo cosí in grado di formulare la seguente variante dell algoritmo di Prim che va sotto il nome di Algoritmo di Prim - Dijkstra. Consideriamo dunque i vettori LABEL e P RED per memorizzare i nodi e gli archi serviti, il vettore LMIN, la cui generica componente j-esima rappresenta, per ogni nodo a j non servito, la lunghezza dell arco piú breve che congiunge a j ai nodi giá serviti. Consideriamo inoltre il contatore k dei nodi serviti, le variabili NEXT e LAST che rappresentano il prossimo nodo da servire e l ultimo nodo servito, e la variabile M IN necessaria per calcolare la lunghezza dell arco da aggiungere ad ogni iterazione. Si ha allora il seguente

4 Algoritmo di PRIM - DIJKSTRA (0) - (Inizializzazione) - Si sceglie arbitrariamente un nodo, ad esempio a 1 N, e si inizializzano i vettori LABEL, P RED, e LM IN, ponendo LABEL(1) = 1, P RED(1) = 1, LMIN(1) = 0, LABEL(j) = 0, P RED(j) = 1, LMIN(j) = l(1, j) per ogni j = 2, 3,..., n. Si inizializza il contatore k ponendo k = 1 e si pone LAST = 1. (1) - (Fase iterativa) - Si pone M IN = M, (dove M é un numero molto grande rispetto alle lunghezze degli archi del grafo), e si esegue il ciclo: Per j = 1, 2,..., n esegui: se LABEL(j) = 0 ed LMIN(j) < M, allora si pone MIN = LMIN(j), NEXT = j. Alla fine del ciclo si pone LABEL(NEXT ) = 1, k = k + 1. (2) - (Test di arresto) - Se k = n STOP, altrimenti si va al Passo 3. (3) - (Aggiornamento) - Si pone LAST = NEXT e si esegue il ciclo: per ogni j = 2, 3,..., n esegui: se LABEL(j) = 0 e risulta LMIN(j) > l(last, j), allora poni: LMIN(j) = l(last, j) e P RED(j) = LAST. Con i vettori LMIN e P RED cosí modificati si torna al Passo 1. Osservazione 3.1 - L algoritmo di Prim-Dijkstra effettua, in ciascuna delle n 1 iterazioni, al massimo n confronti per calcolare MIN e quindi NEXT, ed al massimo n confronti per aggiornare i vettori LM IN e P RED, e dunque complessivamente al massimo 2n(n 1) operazioni, e quindi ha una complessitá computazionale di ordine n 2, mentre l algoritmo di Prim aveva una complessitá computazionale di ordine n 3. Alla fine dell esecuzione dell algoritmo si ricostruisce l albero invadente dal vettore P RED, mentre dal vettore LM IN si ottiene direttamente la lunghezza dello shortest spanning tree. Infatti, se in una generica iterazione si seleziona il nodo a j, allora LMIN(j) rappresenterá la lunghezza dell arco scelto in quella iterazione; di conseguenza la lunghezza dell intero albero invadente sará dato da j LMIN(j). n. 4 - Algoritmo di Kruskal L algoritmo di Prim costruisce l albero invadente di lunghezza minima in maniera iterativa, aggiungendo ad ogni iterazione al sottografo G = (N, A ) l arco piú breve che aggiunto ai precedenti conserva al sottografo G la caratteristica di essere un albero, cioé un sottografo connesso e senza cicli. E possibile seguire peró un altro approccio: ad ogni iterazione si possiede un sottografo G che puó essere sconnesso, ma deve essere senza cicli, e si aggiunge l arco piú breve che non forma cicli con quelli giá scelti. Di conseguenza gli estremi dell arco (a, b) da aggiungere devono appartenere a due diverse componenti connesse del grafo G ; aggiungendo l arco (a, b) ad A, le due componenti connesse di G a cui appartenevano a e b verranno a formare un unica componente connessa. Pertanto ad ogni iterazione si costruisce un sottografo in cui il numero delle componenti connesse diminuisce di una unitá. Ebbene, si parte con il sottografo (N, ), in cui non c é nessun arco, e quindi nessun nodo puó essere raggiungibile da un altro nodo, ed in cui quindi ci sono n componenti connesse, quanti sono i nodi, e ad ogni iterazione si aggiunge un arco che produce una riduzione di una unitá del numero delle componenti connesse. Dopo n 1 iterazioni avremo costruito un sottografo G = (N, A ) senza cicli, in cui sono rimaste n (n 1) componenti connesse, cioé in cui é rimasta un unica componente connessa. Pertanto il sottografo trovato dopo n 1 iterazioni é connesso, senza cicli e serve tutti i nodi, cioé é un albero invadente.

Infine avendo avuto cura di aggiungere sempre l arco piú breve tra quelli disponibili, il sottografo finale é un albero invadente di lunghezza minima. Il procedimento descritto é la sostanza del procedimento di ricerca dello shortest spanning tree, noto come algoritmo di KRUSKAL Per illustrarne i dettagli supponiamo che il grafo sia stato memorizzato mediante i vettori F ROM, T O e LEN GT H, ordinati in ordine crescente di lunghezza. Consideriamo a) un vettore m-dimensionale LABEL per memorizzare gli archi accettati: LABEL(j) = 1 se l arco j-esimo é stato giá scelto, altrimenti LABEL(j) = 0, b) un vettore n dimensionale COMP, caratterizzato dal fatto che COMP (j) = i se a j appartiene alla stessa componente connessa del nodo a i, c) il contatore k degli archi giá accettati, d) una variabile intera ARCO che rappresenta l indice dell arco sotto esame, da accettare o da scartare. Si ha allora il seguente: 5 ALGORITMO DI KRUSKAL (0) - (inizializzazione) Si pone k = 0, ARCO = 1 e si inizializzano i vettori LABEL e COMP ponendo LABEL(j) = 0 per ogni j = 1, 2,..., m e COMP (i) = i per ogni i = 1, 2,... n. (1) - (Fase iterativa) - Si esegue il ciclo: finché COMP(FROM(ARCO)) = COMP(TO(ARCO)), si pone ARCO = ARCO + 1. Alla fine del ciclo si pone LABEL(ARCO) = 1, k = k + 1. (2) - (Test di arresto) Se k = n 1 STOP, altrimenti si va al Passo 3 (3) - (Aggiornamento) Si esegue il ciclo: per i = 1, 2,..., n esegui: se COMP (i) = COMP (T O(ARCO)), allora poni COMP (i) = COMP (F ROM(ARCO)). Con il vettore COMP cosí modificato si torna al Passo 1. n. 5 - Appendice Dimostrazione della ottimalitá dell albero generato dall algoritmo di Prim Per dimostrare che l albero generato dall algoritmo di Prim é quello di lunghezza minima, é opportuno premettere la seguente Definizione. Si dice sottoalbero ottimo di G un sottografo G = (N, A ) di G per cui esiste un albero invadente di lunghezza minima G = (N, A ) tale che A A. Sussiste allora il seguente Teorema di Prim. Sia G = (N, A ) un sottoalbero ottimo di G tale che N N e siano ā N, b N N tali che (ā, b) A e (*) l(ā, b) = min {l(a, b) : a N, b N N, (a, b) A}. Allora il sottografo G = (N { b}, A {(ā, b)} é ancora un sottoalbero ottimo. Dim. Sia G = (N, A ) un albero invadente di lunghezza minima tale che A A e dimostriamo che esiste un albero invadente di lunghezza minima G = (N, A ) tale che A A (ā, b).

6 Ebbene, se (ā, b) A, l albero G soddisfa la tesi. In caso contrario, esiste un cammino in G che congiunge ā con b; tale cammino conterrá un arco (a, b) tale che a N e b / N. Consideriamo allora il sottografo G di G ottenuto sostituendo in A l arco (a, b) con l arco (ā, b), (cioé G = (N, A ), con A = A {(ā, b)} {(a, b)}), e dimostriamo che : (1) G é connesso, (2) G non ha cicli, (3) la lunghezza di G é minore o uguale della lunghezza di G ; ne seguirá che G é (al pari di G ), un albero invadente di lunghezza minima, e quindi soddisfa la tesi, dal momento che risulta chiaramente G A {(ā, b)}. Dim. di (1). Siano a, b N, a b e dimostriamo che esiste un cammino in G un acmmino congiungente a con b. A tal fine, sia Γ il cammino in G congiungente a con b ; se Γ non contiene l arco (a, b), allora Γ soddisfa la tesi. In caso contrario, il cammino cercato si ottiene sostituendo Gamma con il cammino Γ unione dei seguenti cammini: il cammino congiungente a con a, il cammino congiungente a con ā, l arco (ā, b), il cammino congiungente b con b, il cammino congiungente b con b. Dim. di (2). Supponiamo per assurdo che G contiene un ciclo Γ e dimostriamo che allora esiste un ciclo in G, il che é impossibile, poiché G é un albero. Infatti, se Γ non contiene l arco (ā, b), allora Γ stesso é un ciclo in G. Se Γ contiene l arco (ā, b), allora un ciclo in G si ottiene sostituendo, in Γ, l arco (ā, b) con il cammino Γ unione dei seguenti cammini: il cammino congiungente ā con a, l arco (a, b), il cammino congiungente b con b. Dim di (3). I sottografi G e G differiscono solo per gli archi (ā, b) e (a, b) e risulta l(ā, b) l(a, b), in virtú di (*); ne segue che la lunghezza di G é minore o uguale della lunghezza di G. Dal teorema di Prim si deduce che il sottografo trovato alla fine dell esecuzione dell algoritmo di Prim é un albero invadente di lunghezza minima. Infatti é evidente che il sottografo iniziale G = (N, A ), con A =, é un sottoalbero ottimo; conseguentemente, il sottografo trovato dopo la prima iterazione é un sottoalbero ottimo. Ma allora anche quello trovato dopo la seconda iterazione é un sottoalbero ottimo, e in generale il sottografo trovato dopo ogni iterazione é un sottoalbero ottimo. Pertanto, il sottoalbero G = (N, A ) trovato dopo n 1 iterazioni é un sottoalbero ottimo, e quindi esiste un albero invadente di lunghezza minima G = (N, A ), tale che A A. Ebbene si vede facilmente che N = N, A = A, e quindi che il sottoalbero G trovato dall algoritmo di Prim é proprio l albero invadente di lunghezza minima G = (N, A ). Infatti, dopo n 1 iterazioni, l insieme N avrá n elementi e quindi coincide con N; d altra parte, deve essere A = A, perché se ci fosse un arco (a, b) A A, il cammino unione dell arco (a, b) con il cammino in G congiungente b con a sarebbe un ciclo in G, e questo é impossibile, poiché G é un albero.