Progetti - Dipartimento di Informatica e Sistemistica

annuncio pubblicitario
Algoritmi e Strutture Dati (A.A. 2007-2008)
Progetti Software
Giuseppe F. Italiano, Luigi Laura
Istruzioni generali
I progetti proposti di seguito possono essere svolti dagli studenti del corso di Algoritmi e
Strutture Dati dell’Anno Accademico 2007-2008, secondo le modalità descritte nella
pagina Web del corso seguito (Prof. Italiano oppure Prof. Laura):
http://gauguin.info.uniroma2.it/~italiano/Teaching/Algoritmi/
oppure
http://www.dis.uniroma1.it/~laura/index.php?id=78
Il progetto è obbligatorio e contribuisce al voto. Il progetto deve essere svolto in gruppi
di 2 o 3 studenti. In caso di particolari esigenze il progetto può anche essere svolto
singolarmente, ma questo non è consigliato dai docenti (per possibile carico di lavoro
eccessivo).
Quale progetto svolgere?
Per scegliere il progetto, calcola la seguente funzione:
associa a ciascuna delle lettere minuscole dell’alfabeto inglese un numero da 0 a 25, in
ordine crescente: quindi a ~> 0, b ~> 1, ... , z ~> 25;
calcola la somma s dei valori numerici corrispondenti alle lettere minuscole contenute nel
cognome e nel nome di tutti i componenti del gruppo;
svolgete il progetto 1 + s%7, dove % indica l’operatore modulo, ovvero il resto della
divisione per 7.
Ad esempio, progetto(giuseppe italiano luigi laura) = 1 + 264%7 = 6. Il corretto calcolo
della funzione è un prerequisito indispensabile per la valutazione del progetto: non
saranno presi in considerazione progetti non corrispondenti ai propri cognome e nome.
Quando e dove consegnare?
Il progetto deve essere consegnato almeno 5 giorni prima della data prevista per la
verbalizzazione dell’appello. E’ quindi possibile presentare il progetto entro e non oltre i
cinque giorni che precedono l’ultimo appello del settembre 2008, la cui data sarà resa
nota sulla pagina Web del corso. Il materiale va consegnato al docente di riferimento
(Prof. Italiano, Prof. Laura) oppure lasciato nella casella della posta del Prof. Giuseppe F.
Italiano, al piano terra del Dipartimento di Informatica, Sistemi e Produzione, edificio di
Ingegneria della Informazione. In ogni caso, sul progetto va indicato chiaramente il nome
del docente di riferimento (Prof. Italiano, Prof. Laura).
Non si accettano progetti consegnati per posta elettronica.
Cosa consegnare?
Va consegnato il seguente materiale, sul quale devono essere chiaramente indicati il
nome, cognome ed e-mail di tutti i componenti del gruppo:
1) Un CD-ROM contenente il codice di tutta la sperimentazione, che deve essere chiaro e
ben commentato. Per codice si intendono sia header file sia sorgenti delle
implementazioni, incluso un main di prova che permetta di testare facilmente il corretto
funzionamento dell’implementazione. Non includere invece nel codice alcuna libreria.
2) Una relazione che contenga tutti i risultati della sperimentazione sia in forma tabulare
che mediante grafici. Per ogni classe implementata deve essere data una precisa
descrizione dei metodi e dei dati membro pubblici e privati. Inoltre, per ogni metodo
implementato deve essere data una precisa descrizione dei parametri, del valore restituito
e dell’operato del metodo. Si richiede una versione cartacea della relazione e,
facoltativamente, anche una versione elettronica da includere nel CD-ROM.
3) Una stampa delle esecuzioni eseguite (test esaurienti!).
Il progetto non verrà corretto se il materiale consegnato non è completo.
Scopo del progetto
Il progetto richiede la sperimentazione di algoritmi e strutture dati descritti durante il
corso. Il progetto può essere implementato nel linguaggio C++ o nel linguaggio Java.
Linguaggio C++: Chi decide di implementare il progetto in C++ deve utilizzare la
Libreria ASD, di cui parleremo in seguito. Le implementazioni devono utilizzare
caratteristiche standard del C++, come descritto in [2]. Il codice deve essere chiaro, ben
indentato ed abbondantemente commentato. Non è possibile utilizzare librerie ausiliarie,
tranne poche classi basilari della Libreria Standard del C++, quale i contenitori standard
vector, list e map, descritti in [3].
Quale compilatore C++ usare?
Una corretta compilazione è un requisito indispensabile per la valutazione del progetto: il
progetto non verrà corretto in caso di problemi di compilazione. Ti consigliamo pertanto
di usare compilatori ed ambienti standard per il linguaggio C++, come ad esempio
Borland C++ o Dev C++ in ambiente Windows, e i compilatori della famiglia GNU (gcc
o g++) in ambiente Linux. Se non disponi di un tale compilatore puoi usarne un altro,
limitandoti però alle sole istruzioni e funzioni standard del C++. Ti sconsigliamo
fortemente di usare ambienti avanzati di programmazione C++, come ad esempio C++
Builder e Visual C++.
Linguaggio Java: chi decide di utilizzare il linguaggio Java deve usare la libreria
ASDlab, di cui parleremo in seguito. Le implementazioni devono utilizzare caratteristiche
standard di Java. Il codice deve essere chiaro, ben indentato ed abbondantemente
commentato. Non è possibile utilizzare librerie al di fuori di quelle distribuite nel JDK.
La sperimentazione deve consistere di uno o più programmi di test i cui risultati devono
essere riportati e ampiamente commentati nella relazione.
Libreria ASD e ASDlab
Per svolgere il progetto devi utilizzare la Libreria ASD (C++) o la Libreria ASDlab
(Java), entrambe scaricabili dalla pagina Web del corso. I componenti di queste librerie
sono le implementazioni degli pseudocodici del libro di testo, [1]. L'elenco dettagliato
degli algoritmi e delle strutture dati è fornito nella documentazione delle librerie. Inoltre,
per ciascuna componente che dovrete o vorrete utilizzare, potete leggere la relativa
documentazione che descrive dettagliatamente l’interfaccia pubblica e la modalità d’uso.
Se hai bisogno di una certa funzionalità, prima di realizzarla in maniera indipendente, ti
consigliamo di cercarla innanzitutto fra quelle offerte dalle librerie.
Ti consigliamo di studiare la documentazione prima di scrivere una sola linea di codice.
Come scaricare e compilare la libreria ASD
Scarica il file asd_2.0.zip seguendo il link Download. Una volta scompattato, troverai
nella directory include un insieme di header file divisi per categoria: albero,
algoritmi, codapriorita, dizionario, grafo, unionfind. Per usufruire delle
funzionalità della Libreria ASD, basta includere le componenti che si intende utilizzare.
Come già detto, nella directory doc trovi l’intera documentazione, presente anche sulla
pagina Web del corso. Nella directory main trovi un buon numero di programmi di prova
che potrebbero risultare molto utili al fine di comprendere come utilizzare una certa
componente. Nella directory make trovi un esempio di makefile per compilare i
programmi di prova in ambiente Linux.
Come scaricare e utilizzare la libreria ASDlab
Scarica il file asdlab-runtime.zip seguendo il link Download. Una volta scompattato,
troverai nella directory lib il file di runtime della libreria asdlab.jar. Per usufruire
delle funzionalità della Libreria ASD, basta includere nel classpath la cartella contenente
il suddetto file. Come già detto, nella directory javadoc trovate l’intera documentazione,
consultabile a partire dal file index.html.
I progetti
In questo paragrafo descriviamo 7 progetti software, tra cui dovrai sceglierne uno
secondo le modalità descritte nel Paragrafo 1.1. Le implementazioni devono essere
efficienti da un punto di vista asintotico e rispecchiare fedelmente gli algoritmi e le
strutture dati descritte nel libro di testo [1]. Le sperimentazioni devono essere complete
ed esaurienti, e i risultati vanno riportati e ampiamente commentati nella relazione.
Le potenzialità offerte dai linguaggi C++ e Java devono essere sfruttate al meglio: in
particolare, ti invitiamo ad usare il meccanismo dell’ereditarietà (ad esempio, gli alberi
AVL devono ereditare le proprietà degli alberi binari di ricerca) ed il meccanismo delle
classi template (gli elementi e le chiavi mantenute nelle strutture dati devono avere tipi
generici).
IMPORTANTE! – NOTE COMUNI A TUTTI I PROGETTI:
Per un’idea di come si effettua una buona sperimentazione di algoritmi si rimanda al
Paragrafo 1.3.3 – Metodologie di Analisi Sperimentale - di [4]. Dello stesso testo si
consiglia inoltre una lettura approfondita di tutto il Capitolo 1 e dei capitoli che
presentano algoritmi e strutture dati relativi al proprio progetto (in particolare i paragrafi
di Analisi Sperimentale presenti alla fine di ogni capitolo).
La descrizione dei progetti fornisce le specifiche minime per la realizzazione dei progetti
stessi, gli studenti sono liberi di ampliare la sperimentazione aggiungendo altri
esperimenti.
Misurazione del tempo negli esperimenti:
C++. Per misurare il tempo di esecuzione puoi usare la funzione clock() dichiarata nella
libreria standard time.h: ricorda che per ottenere il tempo in secondi occorre dividere il
risultato di clock() per CLOCKS_PER_SEC.
Java. Per misurare il tempo di esecuzione potete usare il metodo System.nanoTime(),
che fornisce un valore di tipo long che rappresenta il tempo trascorso a partire da un
istante di tempo prefissato, in nanosecondi.
Progetto 1: ordinamento di stringhe
Si richiede di condurre un’indagine sperimentale sul comportamento di differenti
algoritmi di ordinamento. In particolare si chiede di confrontare almeno tre diversi
algoritmi di ordinamento tra quelli visti nel Capitolo 4 del libro di testo [1], di cui almeno
uno scelto tra InsertionSort, SelectionSort e BubbleSort e almeno uno scelto tra
QuickSort, HeapSort e MergeSort. Si richiede di ordinare array di stringhe di dimensioni
crescenti (dimensioni degli array, non delle stringhe!). Si chiede di studiare le prestazioni
degli algoritmi al variare delle dimensioni dell’input. Inoltre, (facoltativo!) come si
comportano gli algoritmi se la memoria principale non è in grado di contenere tutto
l’array? I risultati della sperimentazione devono essere presentati sia in forma tabulare
che mediante grafici aventi sulle ascisse la dimensione degli array e sulle ordinate i tempi
di esecuzione.
Note:
! se alcuni algoritmi sono particolarmente “lenti” non è necessario provarli su
istanze di grandissime dimensioni;
! per trovare array di stringhe di grandi dimensioni da ordinare si possono scaricare
dei testi in formato .txt, come i grandi classici della letteratura presenti sul sito
www.liberliber.it
Progetto 2: ordinamento di interi
Si richiede di condurre un’indagine sperimentale sul comportamento di differenti
algoritmi di ordinamento. In particolare si chiede di confrontare il comportamento degli
algoritmi RadixSort, IntegerSort e almeno un terzo algoritmo a scelta tra tra QuickSort,
HeapSort e MergeSort. Si richiede di generare array casuali (ma uguali per tutti gli
algoritmi!) di dimensione crescente contenente n interi compresi tra 0 e k. Siamo
interessati al comportamento degli algoritmi al variare di n, numero degli elementi
dell’array, k, massimo valore presente nell’array e b, base del RadixSort (vedi Capitolo 4
di [1] e [4].
Progetto 3: calcolo deterministico e randomizzato del mediano
Si richiede di condurre un’indagine sperimentale sul comportamento di differenti
algoritmi per il calcolo del mediano. In particolare si chiede di confrontare il
comportamento degli algoritmi quickSelect ([1], Paragrafo 5.2) e select ([1],
Paragrafo 5.3). Si richiede di trovare il mediano di array di stringhe di dimensioni
crescenti (dimensioni degli array, non delle stringhe!). Si chiede di studiare le prestazioni
degli algoritmi al variare delle dimensioni dell’input. Inoltre, (facoltativo!) come si
comportano gli algoritmi se la memoria principale non è in grado di contenere tutto
l’array? I risultati della sperimentazione devono essere presentati sia in forma tabulare
che mediante grafici aventi sulle ascisse la dimensione degli array e sulle ordinate i tempi
di esecuzione.
Nota: per trovare array di stringhe di grandi dimensioni da ordinare si possono scaricare
dei testi in formato .txt, come i grandi classici della letteratura presenti sul sito
www.liberliber.it
Progetto 4: calcolo deterministico del mediano
Si richiede di condurre un’indagine sperimentale sul comportamento dell’algoritmo per il
calcolo del mediano. In particolare si chiede di confrontare il comportamento
dell’algoritmo select ([1], Paragrafo 5.3), che opera ricorsivamente su gruppi di 5
elementi, con varianti dello stesso algoritmo (da implementare!), che operino
rispettivamente su 3, 7 e 9 elementi. Si richiede di trovare il mediano di array di stringhe
di dimensioni crescenti (dimensioni degli array, non delle stringhe!). Si chiede di studiare
le prestazioni degli algoritmi al variare delle dimensioni dell’input. Inoltre, (facoltativo!)
come si comportano gli algoritmi se la memoria principale non è in grado di contenere
tutto l’array? I risultati della sperimentazione devono essere presentati sia in forma
tabulare che mediante grafici aventi sulle ascisse la dimensione degli array e sulle
ordinate i tempi di esecuzione.
Nota: per trovare array di stringhe di grandi dimensioni da ordinare si possono scaricare
dei testi in formato .txt, come i grandi classici della letteratura presenti sul sito
www.liberliber.it
Progetto 5: alberi binari di ricerca e alberi AVL
Si richiede di condurre un’indagine sperimentale sul comportamento di alberi binari di
ricerca e di alberi AVL. In particolare si chiede di confrontare il comportamento di queste
due strutture dati in seguito a una sequenza casuale di inserimenti/cancellazioni/ricerche
di stringhe. Si chiede di studiare le prestazioni degli algoritmi al variare delle dimensioni
dell’input (ovvero, numero di stringhe inserite). Inoltre, (facoltativo!) come si
comportano gli algoritmi se la memoria principale non è in grado di contenere
completamente le strutture dati? I risultati della sperimentazione devono essere presentati
sia in forma tabulare che mediante grafici aventi sulle ascisse il numero di stringhe (da un
minimo di 5.000 a un massimo di 50.000) e sulle ordinate i tempi di esecuzione.
Nota: per creare istanze di input si possono scaricare dei testi in formato .txt, come i
grandi classici della letteratura presenti sul sito www.liberliber.it. Per ogni stringa si
decide con probabilità p1 (0 <= p1 < 1) se inserirla, con probabilità p2 (0 <= p2 < 1) se
cercarla o con probabilità p3 (p3 = 1- p1- p2) se cancellarla.
Progetto 6: d-heap e heap binomiali
Si richiede di condurre un’indagine sperimentale sul comportamento di d-heap e heap
binomiali. In particolare si chiede di confrontare il comportamento di queste due strutture
dati in seguito a una sequenza casuale di inserimenti di numeri interi e di estrazioni del
minimo. Si chiede di studiare le prestazioni degli algoritmi al variare del numero di
operazioni (inserimenti e estrazioni del minimo) e, relativamente ai d-heap, anche al
variare del valore di d. I risultati della sperimentazione devono essere presentati sia in
forma tabulare che mediante grafici aventi sulle ascisse il numero di operazioni (da un
minimo di 5.000 a un massimo di 50.000) e sulle ordinate i tempi di esecuzione.
Nota: per creare istanze di input si possono generare degli interi casuali. Dopo aver
inserito un certo numero di interi nelle strutture dati (d-heap e heap binomiali), a ogni
passo si può decidere (con probabilità 0 <= p1 <1) di inserire un altro intero, oppure (con
probabilità 1- p1) di estrarre il minimo. Studiare il comportamento delle strutture dati
anche al variare del valore di p1.
Per delle linee guida sulla sperimentazione si consiglia di fare riferimento al paragrafo
8.3 del testo [4].
Progetto 7: UnionFind
Si richiede di condurre un’indagine sperimentale su strutture dati Union-find (capitolo 9
di [1]), confrontando tra di loro le diverse strutture dati disponibili nella libreria ASD (per
chi svolge il progetto in C++; chi svolge il progetto in Java può fare riferimento alla
libreria ASDlab). In particolare si chiede di studiare le prestazioni delle strutture dati a
fronte di una sequenza di operazioni di tipo Union e Find. I risultati della
sperimentazione devono essere presentati sia in forma tabulare che mediante grafici
aventi sulle ascisse il numero di operazioni (da un minimo di 500 a un massimo di 5.000)
e sulle ordinate i tempi di esecuzione. Per delle linee guida sulla sperimentazione si
consiglia di fare riferimento al paragrafo 9.4 del testo [4].
Riferimenti bibliografici
[1] C. Demetrescu, I. Finocchi e G. F. Italiano: Algoritmi e Strutture Dati. McGraw-Hill,
2004.
[2] B. Stroustroup: C++: linguaggio, libreria, principi di programmazione. Terza
edizione. Addison-Wesley, 2000.
[3] La documentazione di STL: http://www.sgi.com/tech/stl/index.html
[4] C. Demetrescu, U. Ferraro Petrillo, I. Finocchi e G. F. Italiano: Progetto di algoritmi e
strutture dati in Java. McGraw-Hill, 2007.
Scarica