ELEMENTI PER IMPLEMENTARE SEMPLICI OPERAZIONI SUI GRAFI per le classi quarte vers0.0 Contenuti Alcune definizioni................................................................................................................................2 Albero...................................................................................................................................................5 Esempi applicativi................................................................................................................................6 Struttura dati.........................................................................................................................................8 Matrice delle Adiacenze...................................................................................................................8 Lista di Adiacenza............................................................................................................................9 Matrice di Adiacenza vs. Lista di Adiacenza...................................................................................9 Operazioni sui grafi............................................................................................................................11 Operazioni di base..........................................................................................................................11 Altre operazioni..............................................................................................................................11 Problema del cammino minimo (Shortest Path Problem, SPP) .....................................................11 Algoritmo di Dijkstra .................................................................................................................11 Esempio per individuare l’algoritmo .........................................................................................11 Algoritmo ...................................................................................................................................16 Struttura dati di supporto............................................................................................................17 Visita in profondità (depth-first search DFS) ................................................................................18 Struttura dati di supporto............................................................................................................18 Esempio per individuare l'algoritmo..........................................................................................18 Elenco esercitazioni ...........................................................................................................................21 Elementi per implementare semplici operazioni sui grafi Alcune definizioni DEFINIZIONE Un grafo G è costituito da una coppia ordinata di insieme (N,A) dove N è l'insieme finito, i cui elementi sono chiamati nodi, e A è un insieme di coppie ordinate di nodi ovvero è un sottoinsieme del prodotto cartesiano di N i cui elementi sono chiamati archi G=(N,A) Un grafo G = (N, Ø ) privo di archi è detto "grafo nullo". Un caso estremo di grafo nullo è quello del grafo G = (Ø ,Ø), per il quale anche l'insieme dei nodi è vuoto ESEMPIO Siano N = {1, 2, 3, 4} e A={(1,3), (1,2), (2,2), (2,4), (3,4), (4,1)} con A NxN. Per disegnare un grafo si usano generalmente dei punti o dei cerchi per rappresentare i nodi e delle linee che collegano i nodi per rappresentare gli archi. ESEMPIO Grafo con 6 nodi e 5 archi Si distinguono due tipi di grafi, i grafi orientati ed i grafi non orientati. Un grafo orientato G è costituito da una coppia ordinata di insiemi (N, A), dove N è l'insieme dei nodi di G e A è l'insieme degli archi orientati di G. Un arco orientato (ni, nj) stabilisce un collegamento dal nodo ni al nodo nj, ma non viceversa, ed è caratterizzato da una direzione; per rappresentarlo si utilizzano le frecce anziché la linea. 1 2 3 4 2/2 Elementi per implementare semplici operazioni sui grafi Un grafo non orientato G è costituito da una coppia ordinata di insiemi (N, A), dove N è l'insieme dei nodi di G, ed A è l'insieme degli archi non orientati di G. Un arco (ni, nj) è una coppia non ordinata di nodi: le coppie (ni, nj) e (nj, ni ) indicano lo stesso arco; per rappresentarlo si utilizza una linea che collega i due nodi. I nodi che formano un arco (ni, nj) sono detti nodi adiacenti. ESEMPIO Grafo non orientato in cui G=(N, A) con N={ 1, 2, 3, 4 } ed A={(1,2), (1,3), (3,2), (2,4)} DEFINIZIONE Dato un grafo non orientato G=(N,A), si definisce cammino una sequenza di nodi (n0, n1,.., nk) tali che (ni, ni+1)∈A e i=0, ..., k-1. Il valore k rappresenta la lunghezza della cammino, inoltre: o se nessun nodo è ripetuto, il cammino è detto semplice o se n0 = nk, il cammino è detto chiuso o un cammino semplice e chiuso è detto ciclo. ESEMPIO Sia G=(N, A) con N={ 1, 2, 3, 4} ed A={(1,2), (1,3), (1,4), (2,4), (3,4)} abbiamo che: Cammino 1,3,4 1,2,2,4,1,2 1,2,2,4,1 1,2,4,1 1,3,4,1 Lunghezza 2 5 4 3 3 Semplice Si No No Si Si Chiuso No No Si Si Si Ciclo No No No Si Si La definizione di cammino può essere estesa anche al caso di grafi orientati, tenendo presente che l’esistenza di un cammino da un nodo ni ad un nodo nj non assicura, in questo caso, l’esistenza di un cammino da nj ad ni. Avremo per i grafi orientati due tipi di connessione. DEFINIZIONE Sia G un grafo orientato: si definisce cammino non diretto la sequenza di nodi (n0, n1,.., nk) tali che (ni, ni+1)∈A oppure (ni+1, ni) ∈A, per ogni i= 0, …, k-1. Un arco che ha i due nodi coincidenti si dice "cappio", mentre più archi che connettono gli stessi due nodi danno origine ad un "multiarco". Un grafo sprovvisto di cappi e di multiarchi si dice grafo semplice. In caso contrario si parla di multigrafo. Lo scheletro sk(G) di G è il grafo che si ottiene da G eliminandone tutti i cappi e sostituendone ogni multiarco con un solo arco avente gli stessi vertici. In un grafo semplice per ogni arco orientato o non orientato diremo che: o due nodi si dicono adiacenti se sono connessi da un arco) 3/3 Elementi per implementare semplici operazioni sui grafi o due archi sono adiacenti se hanno un nodo in comune DEFINIZIONI Dato un grafo orientato G=(N, A) si definisce grado interno di un nodo n∈N come il numero di archi entranti nel nodo. Dato un grafo orientato G=(N, A) si definisce grado esterno di un nodo n∈N come il numero di archi uscenti dal nodo. Dato un grafo orientato G=(N, A) si definisce grado di un nodo n∈N come la somma tra il grado interno entrante e quello esterno Dato un grafo orientato G=(N, A) si definisce grado massimo di un grafo come il grado interno massimo dei suoi nodi Dato un grafo orientato G=(N, A) si definisce grado minimo di un grafo come il grado interno minimo dei suoi nodi Quando il grado massimo ed il grado minimo coincidono con un numero k, si è in presenza di un grafo regolare. DEFINIZIONE: Un grafo si dice completo se ogni suo nodo è collegato con almeno un altro nodo. Un grafo si dice connesso se esiste un cammino che collega ogni coppia di nodi. Un "nodo isolato" è un nodo che non è connesso a nessun altro nodo. Un nodo isolato ha grado 0 Un nodo snodo è un nodo che se soppresso sconnette il grafo. Un arco ponte è un arco che se soppresso sconnette il grafo. Un Grafo orientato si dice fortemente connesso se data una coppia qualunque di nodi è possibile determinare un cammino che li unisce nei due versi. Un grafo si dice, invece, debolmente connesso se il grafo (non orientato) ottenuto ignorando l’orientamento degli archi è un grafo connesso. Un grafo orientato si dice connesso se per ogni coppia di nodi v e w, esiste almeno un cammino non diretto che collega v e w. DEFINIZIONE Un grafo si dice traversabile se può essere disegnato senza mai alzare la penna dal foglio e senza mai passare due volte per lo stesso arco. Un ciclo di Eulero per un grafo G orientato e connesso è un ciclo che attraversa ogni arco di G una ed una sola volta, anche se si può ripassare più volte per lo stesso nodo. 4/4 Elementi per implementare semplici operazioni sui grafi Un cammino si dice Hamiltoniano se tocca una e una sola volta ogni nodo. Un Grafo Hamiltoniano è un grafo in cui esiste un cammino Hamiltoniano. Albero Una importante classe di grafi è quella degli alberi 1 3 2 4 5 Si definisce albero un grafo non orientato, connesso e privo di cicli 5/5 Elementi per implementare semplici operazioni sui grafi Esempi applicativi I grafi sono strutture matematiche discrete che rivestono interesse sia per la matematica che per un'ampia gamma di campi applicativi. I grafi si incontrano in vari capitoli dell'informatica (ad esempio per schematizzare programmi, circuiti, reti di computer, mappe di siti). Essi inoltre sono alla base di modelli di sistemi e processi studiati nell'ingegneria, nella chimica, nella biologia molecolare, nella ricerca operativa, nella organizzazione aziendale, nella geografia (sistemi fluviali, reti stradali, trasporti), nella linguistica strutturale, nella storia (alberi genealogici, filologia dei testi). ESEMPIO Un grafo i cui nodi potrebbero rappresentare i vari uffici di una società e gli archi potrebbero essere quelle coppie di uffici fra i quali c'è uno scambio diretto di informazioni per il completamento di pratiche. ESEMPIO Un grafo in cui i nodi rappresentano i centri abitati di una regione e gli archi rappresentano i tronchi stradali che collegano i centri; potremo valutare la distanza in Km. fra due nodi -adiacenti e non-, il tempo medio di percorrenza tra due centri abitati, il numero di persone/ora transitate nella strada ESEMPIO Grafo in cui i nodi rappresentano le tappe che rappresentano lo stato di avanzamento di un progetto e gli archi rappresentano l'attività da compiere per avanzare nella realizzazione del progetto. Gli archi identificano le seguenti grandezze: 1) stima del tempo di esecuzione dell'attività 2) quantità delle risorse impiegate nell'attività 3) costo delle risorse impiegate nell'attività ESEMPIO DEL PROBLEMA DEL COMMESSO VIAGGIATORE Nel 1859 sir William Rowan Hamilton (matematico irlandese) propose un rompicapo consistente nella ricerca di un cammino continuo lungo gli archi di un grafo in modo da toccare ciascun nodo una ed una sola volta. Si tratta della ricerca in un grafo di un circuito che sia il migliore per tempo di percorrenza e/o lunghezza del cammino. E' il problema che nel mondo dell'economia viene denominato PROBLEMA DEL COMMESSO VIAGGIATORE. I nodi del grafo si possono pensare come città (punti vendita) che il commesso viaggiatore partendo da casa (dove alla fine deve tornare) dovrà toccare (ciascuna una sola volta) per visitare i propri clienti. ESEMPIO DI RILEVANZA STORICA L’introduzione del concetto di grafo come strumento utile per la formalizzazione di un problema viene fatta risalire ad Eulero (1736). Egli viveva nella città di Könisberg che, posta alla confluenza di due fiumi, aveva sette ponti che collegavano le diverse parti della città. Eulero si chiese se fosse possibile compiere una passeggiata per la città attraversando ciascun ponte una ed una sola volta. La risposta negativa fu data da Eulero (a 31 anni). 6/6 Elementi per implementare semplici operazioni sui grafi Egli schematizzò il problema identificando i quartieri con nodi di un grafo e i ponti con gli archi Fig. 1 Fig. 2 In questo modo il suo problema era stato ricondotto al problema di trovare nel grafo costruito un cammino che passasse una ed una sola volta per ogni spigolo. Eulero dimostrò che per il grafo in questione non era possibile trovare un cammino simile, inoltre fornì un caratterizzazione completa dei grafi che permettono cammini di tal genere. 7/7 Elementi per implementare semplici operazioni sui grafi Struttura dati L’organizzazione delle informazioni per rappresentare un grafo può seguire due modalità diverse: matrice delle adiacenze lista delle adiacenze Matrice delle Adiacenze Sia G=(N, A) un grafo, una matrice di adiacenza è una matrice quadrata, A, di ordine n dove n è il numero dei nodi presenti nel grafo tale che: Ai,j = 0 se ( ni , nj ) ∉ A Ai,j = 1 se ( ni , nj ) ∈A. PROPRIETA' La somma degli elementi della generica riga r ci dice con quanti nodi è connesso il nodo della riga. La matrice d’adiacenza è una matrice simmetrica se i grafi non sono orientati. ESEMPIO Sia G=(N, A) grafo orientato con N={1, 2, 3, 4} e A={ (1,2), (1,3), (2,4), (3,2), (3,4)} la matrice di adiacenza di G è: 0 0 A 0 0 0 1 0 1 0 0 0 1 0 1 1 0 ESEMPIO Sia G=(N, A), N={1, 2, 3, 4} e A={ (1,2), (1,3), (2,3), (3,4)} il grafo non orientato in figura la matrice di adiacenza di G è: 0 1 A 1 0 0 1 0 1 1 0 1 1 0 1 0 1 ESEMPIO La rispettiva matrice d’adiacenza ci dice che il nodo 1 è collegato a 2 nodi, il nodo 5 ad uno solo e il nodo 4 è quello che ha più connessioni. Lo stesso ragionamento vale per gli altri due nodi. 8/8 Elementi per implementare semplici operazioni sui grafi 1 2 3 4 5 1 0 1 0 1 0 2 1 0 1 0 0 3 0 1 0 1 0 4 1 0 1 0 1 5 0 0 0 1 0 2 2 2 3 1 ESEMPIO Ora, nel caso di grafi orientati, la matrice d’adiacenza non sarà più simmetrica in quanto l’1 verrà messo solo dove l’arco è percorribile. 1 0 0 0 1 0 2 1 0 1 0 0 3 0 0 0 1 0 4 0 0 0 0 1 5 0 0 0 0 0 Lista di Adiacenza Sia G=(N,A) un grafo, l’insieme delle liste di adiacenza è un insieme L di liste il cui numero è uguale al numero dei nodi : L=( L1, ... Ln ) ∀ i = 1, ..., n : Li = { vj | (vi, vj ) ∈ A } In una lista di adiacenze, una lista mantiene un elenco di nodi, e ad ogni nodo è collegata una lista di puntatori ai nodi collegati da un arco. Questa matrice è invece n×m dove sulle righe abbiamo i nodi e sulle colonne gli archi del grafo. La matrice viene riempita in questo modo: sulla riga di ogni nodo si mette un 1 in corrispondenza dell’arco con il quale viene connesso ad altri nodi ESEMPIO Sia G=(N, A), N={1, 2, 3, 4} e A={ (1;2), (1;3), (2;4), (3;2), (3;4)} la lista di adiacenza è l’insieme L=( L1, L2, L3, L4 ) dove: L1 = { 2, 3 }, L2 = { 4 }, L3 = { 2, 4 }, L4 = {}. L’insieme delle liste di adiacenza possono essere rappresentate mediante un vettore ed un insieme di liste concatenate dove ogni elemento del vettore V è la testa di una lista concatenata che rappresenta la lista di adiacenza del nodo vi. Matrice di Adiacenza vs. Lista di Adiacenza 9/9 Elementi per implementare semplici operazioni sui grafi I concetti di struttura dati ed implementazione di un operatore sono strettamente connessi tra loro. L’utilizzo di una struttura dati ha influenza sull’implementazione di un operatore. Matrice di adiacenza La rappresentazione tramite matrice di adiacenza è particolarmente semplice da implementare, consentendo l' accesso diretto alle informazioni. Gli operatori di base sono implementabili in modo tale che essi richiedano un tempo di esecuzione costante: il numero di passi da eseguire è indipendente dal numero di nodi ed archi che costituiscono il grafo. Difetto principale di tale rappresentazione è dato dall’eccessivo utilizzo di memoria. La rappresentazione di un grafo con n nodi richiede la definizione di una matrice di dimensione n*n. Una matrice di adiacenze è invece indicata per descrivere grafi con molti archi, Lista di adiacenza La lista di adiacenza non consente un accesso diretto alle informazioni rappresentate. In tal caso gli operatori elencati nella definizione dell’ADT richiederanno un tempo proporzionale al numero di nodi. A favore, la rappresentazione mediante liste di adiacenza richiede un’occupazione di memoria minore rappresentata dalla somma tra il numero di nodi del grafo ed il numero di archi del grafo. Una lista di adiacenze risulta più adatta a rappresentare grafi sparsi o con pochi archi, perché consente di trovare tutti i nodi adiacenti ad un nodo dato e verificare l'esistenza di connessioni tra nodi. 10/10 Elementi per implementare semplici operazioni sui grafi Operazioni sui grafi Operazioni di base Dato un grafo G=(N,A) con N insieme dei nodi ed A insieme degli archi, le operazione di base per gestire un grafo sono ad esempio: o inserire un nuovo nodo al grafo o rimuovere un nodo dal grafo o aggiungere un arco al grafo o rimuovere un arco dal grafo o verificare l'esistenza di un arco o cancellare il grafo Altre operazioni Dato un grafo G=(N,A), operazioni molto importanti sono: o visita in profondità (DFS) o visita in ampiezza (BFS) o ricerca del cammino che congiunga due nodi o ricerca del cammino minimo che congiunga due nodi( Shortest Path Problem, SPP) o ricerca dell’albero ricoprente di un grafo (Spanning Tree, ST ) o ricerca dell’albero ricoprente più corto di un grafo (Shortest ST, SST) Lavoreremo solo su due operazioni sui grafi: visita in profondità/ricerca del cammino che congiunga due nodi e la ricerca del cammino minimo che congiunga due nodi. Problema del cammino minimo (Shortest Path Problem, SPP) Algoritmo di Dijkstra Dato il grafo orientato G=(N,A) con pesi sugli archi non negativi, l'algoritmo risolve il problema dei cammini minimi da un nodo iniziale ad un nodo finale. Fu proposto nel 1956 dall'informatico olandese Edsger Dijkstra. L' algoritmo trova applicazione in molteplici contesti : o ottimizzazione nella realizzazioni di reti (idriche, telecomunicazioni, stradali, circuitali, ecc.) o organizzazione e la valutazione di percorsi runtime nel campo della robotica. Esempio per individuare l’algoritmo Calcolare il percorso minimo tra casa e il posto di lavoro. Schematizziamo tutti i possibili percorsi ed il relativo tempo di percorrenza (supponendo di voler calcolare il percorso più breve in fatto di tempo di percorrenza). 11/11 Elementi per implementare semplici operazioni sui grafi I nodi A, B, C, D, E indicano le cittadine per cui è possibile passare. Ecco una schematizzazione della rete: Vediamo in pratica come si risolve questo esercizio. Questa è la rete in cui sono indicati anche i potenziali: Seguendo le regole appena fissate consideriamo il nodo con potenziale minore (“casa”) e lo rendiamo definitivo (colorandolo di rosso) ed aggiorniamo tutti i nodi adiacenti sommando l'attuale valore del potenziale (ovvero zero) al costo del percorso. Aggiorniamo i potenziali perché avevamo, nel caso di A, potenziale infinito mentre ora abbiamo potenziale 2. Ricordando che il potenziale minore è sempre preferibile. Vediamo come si è aggiornata la rete: 12/12 Elementi per implementare semplici operazioni sui grafi Bisogna ora considerare il nodo non definitivo (ovvero quelli scritti in nero) con potenziale minore (il nodo A). Lo si rende definitivo e si aggiornano i potenziali dei nodi adiacenti B e C. Indichiamo con una freccia da dove proviene il potenziale dei nodi resi definitivi. Il nodo con potenziale minore ora è C. lo si rende definitivo e si aggiornano quelli adiacenti. 13/13 Elementi per implementare semplici operazioni sui grafi Va notato come il nodo D abbia ora potenziale 6 in quanto 6 è minore di 8 e quindi lo si aggiorna. Se avessimo avuto un valore maggiore di quello che già c’era lo avremmo lasciato invariato. Rendiamo definitivo il nodo D e aggiorniamo il grafico: Il nodo con potenziale minore restante è B e lo si rende definitivo aggiornando di conseguenza il grafico: 14/14 Elementi per implementare semplici operazioni sui grafi Resta da considerare il nodo E ed aggiornare “ufficio”. Seguendo all'indietro le frecce si ottiene il percorso minimo da casa ad ufficio che misura (come indicato dal potenziale) “10”. 15/15 Elementi per implementare semplici operazioni sui grafi Bisogna notare come questo algoritmo ci dia non solo la distanza minima tra il punto di partenza e quello di arrivo ma la distanza minima di tutti i nodi da quello di partenza. Algoritmo Il metodo ottiene non solo il percorso minimo tra un nodo iniziale ed un nodo di arrivo ma il percorso minimo tra un nodo di partenza e tutti gli altri punti della rete. La schematizzazione del problema di percorso minimo deve includere tutti i nodi e gli archi; gli archi sono descritti mediante un valore numerico (ad esempio distanza o tempo); deve essere fissato un nodo di partenza ed un nodo di arrivo. I nodi del grafo vengono suddivisi in due sottoinsiemi chiamati nodi visitati (V) e nodi visitabili (T). Ad ogni nodo viene assegnato un valore numerico f, che indica il valore numerico complessivo accumulato nel percorso dal nodo iniziale al nodo corrente, inoltre ogni nodo deve indicare il nodo precedente nel percorso J. L’algoritmo procede secondo le seguenti regole; 1. CARICA IL GRAFO 2. INDICA IL NODO DI PARTENZA ED IL NODO DI ARRIVO 3. INIZIALIZZA LA RICERCA 4. WHILE ESISTONO NODI VISITABILI 4.1 SELEZIONA IL NODO, TRA I NODI VISITABILI, QUELLO A DISTANZA MINORE 4.2 AGGIORNA I NODI ADIACENTI AL NODO SELEZIONATO 4.3 INSERISCI NELL’INSIEME DEI NODI VISITATI IL NODO SELEZIONATO END 8. VISUALIZZA, SE ESISTE, IL PERCORSO MININO In dettaglio. 3. INIZIALIZZA LA RICERCA 16/16 Elementi per implementare semplici operazioni sui grafi o Porre ad infinito il valore f di ciascun nodo e inserire il nodo nel sottoinsieme dei nodi visitabili o Porre al 0 il valore f del nodo di partenza 4. ESISTONO NODI VISITABILI o se esiste almeno un nodo tra quelli visitabili con valore f finito 5. SELEZIONA IL NODO, TRA I NODI VISITABILI, QUELLO A DISTANZA MINORE o tra tutti i nodi visitabili selezionare quello a distanza minore 6. AGGIORNA I NODI VISITABILI ADIACENTI AL NODO SELEZIONATO o Ricalcola la funzione f come somma del nodo precedente ed il valore numerico dell’arco corrente se questo è minore del valore precedente altrimenti si lascia il valore precedente o Aggiorna la funzione nodo precedente con il nodo selezionato 7. INSERISCI NELL’INSIEME DEI NODI VISITATI IL NODO SELEZIONATO o Cambia lo stato del nodo da visitabile a visitato 8.VISUALIZZA, SE ESISTE, IL PERCORSO MININO o Dal nodo di arrivo per mezzo della funzione precedente ricostruire il percorso minimo Struttura dati di supporto La struttura dati per descrivere il grafo G=(N,A) è la seguente: Insieme dei nodi - individuati da un numero intero - stato del nodo: - distanza dal nodo iniziale - identificatore nodo precedente Insieme degli archi - matrice delle adiacenze i cui elementi diversi da zero e positivi indicano la distanza tra i due nodi L'algoritmo ha poi bisogno per procedere del nodo iniziale e del nodo finale. 17/17 Elementi per implementare semplici operazioni sui grafi Visita in profondità (depth-first search DFS) Dato un grafo G=(N,A), la strategia adottata da questo schema di visita consiste nel visitare il grafo sempre più in profondità (fin quando è possibile). Struttura dati di supporto Insieme dei nodi - individuazione attraverso un numero intero - stato del nodo: - identificazione del nodo precedente/predecessore Insieme degli archi - matrice delle adiacenze i cui elementi diversi da zero e positivi indicano la distanza tra i due nodi L'algoritmo ha poi bisogno per procedere di un nodo iniziale. Esempio per individuare l'algoritmo Dato un grafo G=(N,A) la visita in profondità è una della modalità di visita di un grafo. Inizializziamo lo stato di tutti i nodi come VISITABILI Inizializziamo il predecessore di tutti i nodi al valore NULLO Indichiamo il nodo iniziale. Il nodo corrente vene posto al nodo iniziale nodo=1 Lo stato del nodo corrente viene posto a VISITATO -Dal nodo corrente cerchiamo un arco uscente non ancora visitato verso un nodo con stato VISITABILE: nodo=2 Il nodo corrente vene posto al valore 2 Il predecessore del nodo corrente viene posto al valore 1 Lo stato del nodo corrente viene posto a VISITATO -Dal nodo corrente cerchiamo un arco uscente non ancora visitato verso un nodo con stato VISITABILE nodo=3 Il nodo corrente vene posto al valore 3 18/18 Elementi per implementare semplici operazioni sui grafi Il predecessore del nodo corrente viene posto al valore 2 Lo stato del nodo corrente viene posto a VISITATO -Dal nodo corrente cerchiamo un arco uscente non ancora visitato verso un nodo con stato VISITABILE: nodo=6 Il nodo corrente vene posto al valore 6 Il predecessore del nodo corrente viene posto al valore 3 Lo stato del nodo corrente viene posto a VISITATO -Dal nodo corrente cerchiamo un arco uscente non ancora visitato verso un nodo con stato VISITABILE: nessun nodo Il nodo corrente vene posto al valore del predecessore =3 -Dal nodo corrente cerchiamo un arco uscente non ancora visitato verso un nodo con stato VISITABILE: nodo=5 Il nodo corrente vene posto al valore 5 Il predecessore del nodo corrente viene posto nodo=3 Lo stato del nodo corrente viene posto a VISITATO -Dal nodo corrente cerchiamo il successivo arco uscente verso un nodo con stato VISITABILE: nessun nodo Il nodo corrente vene posto al valore del predecessore : 3 -Dal nodo corrente cerchiamo un arco uscente non ancora visitato verso un nodo con stato VISITABILE: nessun nodo Il nodo corrente vene posto al al valore del predecessore :2 -Dal nodo corrente cerchiamo un arco uscente non ancora visitato verso un nodo con stato VISITABILE: nodo=4 Il nodo corrente vene posto al valore 4 Il predecessore del nodo corrente viene posto nodo=2 Lo stato del nodo corrente viene posto a VISITATO -Dal nodo corrente cerchiamo un arco uscente non ancora visitato verso un nodo con stato VISITABILE: nessun nodo Il nodo corrente vene posto al valore del predecessore 2 -Dal nodo corrente cerchiamo un arco uscente non ancora visitato verso un nodo con stato VISITABILE: nessun nodo Il nodo corrente vene posto al nodo precedente: nodo=1 -Dal nodo corrente cerchiamo un arco uscente non ancora visitato verso un nodo con stato VISITABILE: nessun nodo Il nodo corrente vene posto al al valore del predecessore : NULLO La sequenza dei cammini stampati ad ogni passo del programma è la seguente 1 1,2 1,2,3 19/19 Elementi per implementare semplici operazioni sui grafi 1,2,3,6 1,2,3 1,2,3,5 1,2,3 1,2 1,2,4 1,2 1 0 20/20 Elementi per implementare semplici operazioni sui grafi Elenco esercitazioni Nota: non tutte le esercitazioni sono state proposte alla 4D. Esercitazione 01: Algoritmo per la ricerca del percorso minimo Dato un grafo mediante l'algoritmo presentato a lezione (Dijkstra) ricercare il percorso minimo tra due nodi. Esercitazione 02: Algoritmo per la ricerca di tutti i percorsi Dato un grafo trovare tutti i percorsi presenti tra due nodi Esercitazione 03: Utilizzo delle funzione in linguaggio C++ Utilizzando un programma delle due esercitazioni precedenti ristrutturarlo mediante l'uso delle funzioni Esercitazione 04: Utilizzo dei prototipi in linguaggio C++ Utilizzando il programma dell'esercitazione precedente ristrutturare il programma mediante l'utilizzo dei prototipi delle funzioni Esercitazione 05: Costruzione di una libreria in C++ e modalità di utilizzo Utilizzando il programma dell'esercitazione precedente ristrutturare il programma mediante l'utilizzo di librerie Esercitazione 06: Semplici esercizi per leggere e scrivere file di testo Integrazione di un semplice programma di scrittura per sviluppare un semplice report di attività sul programma di ricerca dei percorsi utilizzando anche le funzioni data ed ora Esercitazione 07: Scrittura di un documento tecnico Ripercorrendo le attività sviluppate durante le esercitazione di laboratorio e le lezioni frontali e fornendo l'indice dei contenuti scrivere il documento tecnico del software sviluppato La scrittura del documento in word prevede anche la strutturazione del documento con gli stili, le intestazioni ed il piè di pagina e il sommario generato automaticamente Esercitazione 08: Riutilizzo del software sviluppato per sviluppare un caso reale: la mappa di Venezia Utilizzando uno dei programmi precedenti ed utilizzando una bitmap (leggendola madiante paint) di una porzione della cartina di Venezia costruire un grafo utilizzando come strumento raccolta dati un foglio excel e mediante l'utilizzo di alcune funzione di excel generare automaticamente una parte della funzione di inizializzazione del grafo del programma di ricerca dei percorsi. Esercitazione 09: Integrazione di tutti i dati relativi alle cartine Utilizzando i dati sviluppati da tutti i gruppi trovare una modalità di integrazione dei vari fogli excel sviluppati nella esercitazione precedente, sviluppando una unica semplice base dati per costruire la funzione di inizializzazione del grafo del programma di ricerca dei percorsi. Esercitazione 10: Esercizi di base sull'utilizzo degli oggetti Sviluppare semplici oggetti in c++ per realizzare le operazione base di un grafo 21/21