Progettazione di Algoritmi - Dipartimento di Informatica
Transcript
Progettazione di Algoritmi - Dipartimento di Informatica
Progettazione di Algoritmi a.a. 2015/16 Classe 3: matricole congrue 2 modulo 3 Presentazioni • Marcella Anselmo • Info: http://www.di.unisa.it/professori/anselmo/ • Orario ricevimento: • Martedì 16:00-17:00 • Venerdì 14:00-16:00 • Il mio studio è il n° 57 al 4° piano (ultimo piano) della Stecca 7 (fra l'aula F8 e Farmacia). Pagina del corso • Pagina del corso: http://www.di.unisa.it/professori/anselmo/pjalgo1516.htm Troverete: orario lezioni, ricevimento, programma, syllabus, avvisi, calendario aggiornato via via, slides, date di esame Svolgimento del corso 6 CFU di lezione frontale ed esercitazioni = 48 ore • Il corso prevede 48 ore di lezione frontale che saranno svolte secondo l’orario previsto, oppure in eventuali ore di recupero, di cui si darà notizia in classe e sulla pagina web. • Ultima lezione prevista: martedì 15 dicembre 2015, a meno di… • Eventuali ore di recupero: venerdì dalle 15 alle 17 in aula F1 o in laboratorio P13. • Per esempio: se vogliamo fare il ponte dell’Immacolata, la lezione del lunedì 7/12 dovrebbe essere recuperata (venerdì 4/12?) Prerequisiti Non vi sono propedeuticità formali, ma….. Il corso è la naturale prosecuzione del corso di Introduzione agli Algoritmi e Strutture Dati (concetto di algoritmo, analisi delle risorse, strutture dati, algoritmi iterativi e ricorsivi, tecnica Divide et Impera…) Lo studente dovrebbe avere acquisito la capacità di sviluppare ragionamenti di tipo logico (teorema, ipotesi, tesi, dimostrazioni per assurdo, induzione..) Dovrebbe altresì aver appreso e padroneggiato i concetti di base di programmazione (cicli, iterazione, ricorsione,…) Nonché padroneggiare nozioni di matematica acquisite nei precedenti anni scolastici (logaritmi, diseguaglianze, polinomi, sommatorie,… ) Modalità di frequenza Lo svolgimento delle esercitazioni e la frequenza del corso sono fortemente consigliate. Gli studenti devono essere preparati a trascorrere una congrua quantità di tempo nello studio al di fuori delle lezioni. 1CFU=25 ore di lavoro=8 ore frontali+17 ore studio individuale Come studiare? • Lezioni (domande «stupide» non esistono e sono quelle che fanno crescere) • Slides, appunti, ma… libri! • Esercizi (da soli, a gruppi,…) • Ricevimento • Organizzare gli esami dei vari corsi • Non dimenticare obiettivi e motivazioni Libri di testo I libri di testo di riferimento sono: [KT] Kleinberg, Tardos. Algorithm Design. Pearson Addison Wesley. [DPV] S. Dasgupta, C. H. Papadimitriou, and U. V. Vazirani. Algorithms. McGraw-Hill (cap. 9) Altri libri di consultazione sono: [CLR1] T. H. Cormen, C. E. Leiserson, R. L. Rivest, Introduzione agli Algoritmi, prima edizione, McGraw Hill. [CLRS2] T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein, Introduzione agli Algoritmi, seconda edizione, McGraw Hill. [DFI] C. Demetrescu, I. Finocchi, G.F. Italiano, Algoritmi e Strutture Dati , McGraw Hill, 2004. Esami (!) • L’esame consiste di una prova scritta e di una orale (cui si accede solo dopo il superamento di quella scritta). La prova scritta consiste di una parte con domande a risposta multipla e alcuni quesiti aperti. • Non sono previste prove intercorso, ma brevi test di valutazione dell’apprendimento (per me, per voi). • Gli studenti interessati alle prove di esame devono prenotarsi su Esse3 entro il termine utile. Ricordo inoltre che è possibile e doveroso cancellare la propria prenotazione qualora si decida di non partecipare, per evitare un inutile spreco di risorse. • Durante lo svolgimento del compito scritto NON è consentito consultare libri, appunti o altro materiale/fonte di nessun tipo. Date esami Tantissime… Pre-appello nel periodo 7 - 15 Gennaio 2016: 15 gennaio 2016, ore 9, aule P3 e P4. 2. Primo appello nel periodo 18 Gennaio 2016 - 5 Febbraio 2016: 4 febbraio 2016, ore 9, aule P3 e P4. 3. Secondo appello nel periodo 8 - 26 Febbraio 2016: 22 febbraio 2016, ore 9, aule P3 e P4. 4. Appello straordinario nel periodo 4 – 15 Aprile 2016. 5. Primo appello nel periodo 20 Giugno 2016 – 8 Luglio 2016. 6. Secondo appello nel periodo 11 – 29 Luglio 2016. 7. Appello nel periodo 1 - 19 Settembre 2016. 8. Appello straordinario in Novembre 2016. Contenuto del corso (dal syllabus) Ore di Lezioni frontali: 48 1. Introduzione alla analisi asintotica degli algoritmi. (2 ore frontali) 2. La tecnica di progetto di algoritmi Divide et Impera e relativi esempi di applicazione: Mergesort, Quicksort. Ricorrenze. (4 ore frontali) 3. La tecnica di progetto di algoritmi Programmazione Dinamica e relativi esempi di applicazione: Calcolo di numeri di Fibonacci, Combinazioni; Problemi diottimizzazione: Scheduling di risorse, Zaino intero, Problemi su stringhe, Cammini minimi su grafi. (12 ore frontali). 4. La tecnica di progetto di algoritmi Greedy e relativi esempi di applicazione: Scheduling di intervalli; Scheduling con deadline; Compressione Dati e Codici di Huffman. (10 ore frontali). 5. Algoritmi su grafi. Connettività e visita di grafi; DAG e ordinamento topologico. Calcolo di Cammini Minimi (algoritmo di Dijkstra). Calcolo di alberi ricoprenti minimi (algoritmi di Prim e Kruskal). (8 ore frontali). 6. Calcolo di flusso su grafi e loro applicazioni. (6 ore frontali). 7. Algoritmi intelligenti di ricerca esaustiva: backtracking e branch-and-bound. (6 ore frontali). [DPV, cap. 9] Algoritmi e Progettazione di Algoritmi Primo anno di attivazione Differenze principali: • presupposti: conoscenza di IASD, MMI, (oltre gli altri corsi classici) • contenuti: – breve ripasso di analisi asintotica, ricorrenze, tecnica divide et impera (chi non conosce gli argomenti dovrà approfondire autonomamente da subito) – più enfasi sull’implementazione, adesso che sono note (?) le principali SD – Parte in più su algoritmi esaustivi: tecniche backtracking e branch-and-bound Prologo sugli algoritmi da [DPV] Algoritmi e rivoluzioni L’esistenza di algoritmi efficienti per manipolare dati può essere cruciale nella storia. La numerazione romana fu abbandonata perché non è semplice lavorarci: MCDXLVIII + DCCCXII =? Il sistema decimale inventato in India intorno al 600 d.C. fu una rivoluzione quando nel 9° sec. uno studioso di Baghdad scrisse un manuale con metodi elementari per addizionare, moltiplicare, etc. numeri in decimale. Queste procedure erano precise, senza ambiguità, meccaniche, efficienti, corrette…… in breve erano degli ALGORITMI! Lo studioso era Al Khwarizmi ed è in suo onore che adesso li chiamiamo così. Cos’è un algoritmo? detto fra noi: questo lo capiremo solo alla fine del corso…. Primi algoritmi “Before there were computers, there were algorithms. But now that there are computers, there are even more algorithms, and algorithms lie at the heart of computing.” T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein, Introduction to Algorithms. La frittata con le uova…. Un algoritmo è un procedimento per risolvere un problema mediante una sequenza finita di operazioni elementari. Il procedimento deve essere descritto in maniera precisa e univoca allo scopo di essere eseguito automaticamente dall’esecutore. Input: 4 uova Output: una frittata Ricetta: 1. Rompere le uova 2. Sbattere le uova 3. Cuocere Posso eseguire questa ricetta senza pensarci? Questo è un algoritmo? Non proprio! Non è un metodo generale, una ricetta per ogni frittata. Algoritmo per moltiplicare due numeri (non 4+5) Accendere fornello, prendere padella, … Separare gusci, aggiungere sale etc, cuocere come? L’esecutore sa rompere le uova? Obiettivi Abbiamo bisogno di algoritmi ogni qual volta vogliamo scrivere un programma. Obiettivo finale: programmare in maniera consapevole Dal problema al programma che lo risolve: 1. Formalizzazione del problema 2. Scelta della tecnica per progettare algoritmo 3. Correttezza 4. Analisi risorse usate / efficienza Cosa imparerete in questo corso? • A progettare nuovi algoritmi per risolvere i problemi di oggi e di domani • Studiando come hanno fatto gli altri finora, quali tecniche sono state sviluppate e vengono tutt’ora utilizzate con successo (se siete fortunati, nuovi problemi possono essere formalizzati con problemi noti la cui soluzione è ben conosciuta e testata) • Come dimostrarne la correttezza e valutarne la efficienza Ho un problema…. Un problema reale…. 1. gestire richieste di affitto campo di calcio* 2. elaborare una dieta 3. calcolare/prevedere numeri di amici di Facebook che avrò fra tot anni Voglio risolverlo in maniera «automatica» *Vedi quesiti di appelli alla fine della presentazione Approccio 1: lo «smanettone» Ho un computer + conosco un linguaggio di programmazione Scrivo del codice, compilo, correggo, ……. FATTO! Funziona: l’ho provato con vari dati e ci ha messo pochi secondi. Sei sicuro che funzioni? Ci mette molto tempo? Si poteva fare meglio? Approccio 2: l’informatico laureato! Ho un computer + conosco un linguaggio di programmazione, ma ….. Prendo carta e penna: • Formalizzo il problema: quali i dati che ho? quali voglio? • Cerco tutte le soluzioni che riesco a trovare applicando le tecniche studiate • Valuto la complessità di tempo/spazio di ognuna relativamente ad una organizzazione dei dati. Scelgo! • Vado al computer ad implementarla (ma di questo ne parlerete in altri corsi) Alla fine…. Ti posso dimostrare che funziona e che fra quelle considerate è la più efficiente. Sei sicuro che funzioni? Ci mette molto tempo? Si poteva fare meglio? Riprendiamo il «programma» in breve 1. Analisi asintotica degli algoritmi e tecnica Divide et Impera (in breve) 2. Tecniche di progetto di algoritmi: Programmazione Dinamica, Greedy, Ricerca esaustiva intelligente (BT e B&B) 3. Algoritmi su grafi (molti problemi possono essere espressi tramite grafi) 4. Calcolo di flusso su grafi e applicazioni. Problemi… Un algoritmo risolve un problema, ma… … cos’è un problema? Un esempio Problema reale / concreto: Organizzazione/Scheduling di attività: In una scuola c’è 1 sala computer e più classi che vogliono accedervi ognuna in certi orari. Come accontentare il maggior numero di classi? Formalizzazione del problema Problema computazionale: è definito da input e output Esempio (continua) • Input / Dati: S = { 1, 2, … , n } insieme delle classi Per ogni classe i : • si tempo di inizio • fi tempo di fine • Output / Soluzione: S’ sottoinsieme di S di attività compatibili (= orari non si accavallano) tale che Card(S’) massima S’ = soluzione ottimale Card(S’) = valore ottimo Esempio S = {1, 2, 3, 4, 5, 6} s1 = 9, f1 = 12 s2 = 10, f2 = 14 s3 = 13, f3 = 15 …. 1 2 Soluzioni ammissibili : S1 = {1, 3, 6} S2 = {1, 6} S3 = {2, 4, 6} S4 = {5} 3 4 5 6 9 10 11 12 13 14 15 16 17 18 19 Soluzioni ottimali: S1 = {1, 3, 6} S3 = {2, 4, 6} Valore ottimo = 3 Varianti • Nell’input : Scheduling di attività pesato Ad ogni classe è associato un valore Cerco S’ il cui valore totale sia massimo (non necessariamente la cardinalità) • Nell’output – Cerco soltanto valore ottimo – Cerco tutti S’ Scelta della tecnica per Scheduling di attività 1) Ricerca esaustiva/ Forza bruta / naïf • Considero tutti i sottoinsiemi di S • Per ognuno verifico compatibilità • Fra i sottoinsiemi di attività compatibili restituisco quello di cardinalità massima Q: Quanti sono tutti i sottoinsiemi di {1, 2, …. , n}? Cardinalità insieme delle parti di {1, 2, …. , n} Quanti sono tutti i sottoinsiemi di {1, 2, …. , 6}? Quante sono le stringhe binarie di lunghezza 6? {1, 3, 6} 101001 Sono 2n Analisi: il tempo di esecuzione di tale algoritmo è esponenziale! Esponenziale = non accettabile Altra soluzione? Tecniche di programmazione 2) Programmazione dinamica lo risolve in O(nlogn) 3) Tecnica greedy lo risolve in O(nlog n) Tempo O(nlog n) è accettabile Confronto efficienza n logn vs 2n accettabile non accettabile Altra soluzione Grafo della compatibilità: ogni nodo è un intervallo; due nodi collegati se si accavallano 1 1 3 2 4 2 3 5 4 5 6 6 9 10 11 12 13 14 15 16 17 18 19 Soluzione S1 = {1, 3, 6} Insieme di nodi indipendenti = tale che ogni coppia di nodi NON è collegata Problema più generale Problema dell’insieme indipendente Input: grafo Output: insieme indipendente di cardinalità massima Una soluzione del problema dell’insieme indipendente fornisce una soluzione del problema dello scheduling di attività. Purtroppo però il problema dell’insieme indipendente è un problema «difficile» Concludendo • Dal problema reale al problema computazionale • Bisogna conoscere più tecniche di progettazione di algoritmi • Necessario saper analizzare l’efficienza (tempo/spazio) • Dimostrare correttezza • Molti problemi si possono esprimere con i grafi Appello 15 gennaio 2015 Quesito 2 (24 punti) Dopo le festività natalizie avete messo su qualche chilo, e decidete di cominciare una dieta. Ne avete trovato una che fa al caso vostro. La Dieta consiste nel comporre ogni pasto scegliendo fra alcuni cibi che avete a disposizione, ognuno con un assegnato numero di calorie, senza superare una data quantità di calorie a pasto. Potete però scegliere secondo il vostro gusto. Ad ogni porzione di cibo a disposizione, assegnate quindi un vostro personale "grado di appetibilità" (un intero da 1 a 10). Il problema è allora di calcolare il pasto che non superi il massimo di calorie ammesse in quel pasto, ma che sia il più appetitoso possibile. Ricordate che ogni porzione di cibo va scelta per intera al più una volta. Formalizzate il problema reale in un problema computazionale e risolvetelo con la tecnica che ritenete più opportuna affinché la soluzione sia il più efficiente possibile. Giustificate le risposte. Appello 29 gennaio 2015 Quesito 2 (24 punti) Dopo la Laurea in Informatica avete aperto un campo di calcetto che ha tantissime richieste e siete diventati ricchissimi. Ciò nonostante volete guadagnare sempre di più, per cui avete organizzato una sorta di asta: chiunque volesse affittare il vostro campo (purtroppo è uno solo), oltre ad indicare da che ora a che ora lo vorrebbe utilizzare, deve dire anche quanto sia disposto a pagare. Il vostro problema è quindi scegliere le richieste compatibili per orario, che vi diano il guadagno totale maggiore. Avete trovato una soluzione, ma è molto lenta. Vi ricordate allora che al corso di Algoritmi vi avevano tempestato con le varie tecniche di progettazione di algoritmi: potranno esservi utili (almeno una volta nella vita)? Formalizzate il problema reale in un problema computazionale e risolvetelo in maniera che sia il più efficiente possibile. Giustificate le risposte. Appello 19 febbraio 2015 Quesito 2 (24 punti) Dopo la Laurea in Informatica avete aperto un campo di tennis, ma gli affari non vanno benissimo. Decidete di proporre un’offerta: chi vuole affittare il campo, indipendentemente dalla durata del noleggio, paga sempre lo stesso prezzo fisso di x euro. Sarete però voi a decidere quali richieste accontentare, dopo aver raccolto tutte le richieste, con i rispettivi orari di inizio e di fine, per una stessa giornata. Il vostro problema è di scegliere le richieste compatibili per orario, che vi diano il massimo guadagno totale. Formalizzate il problema reale in un problema computazionale e risolvetelo in maniera che sia il più efficiente possibile, per quanto riguarda sia il tempo di esecuzione che lo spazio di memoria necessario. Giustificate la correttezza della vostra soluzione. Appello 17 aprile 2015 Quesito 2 (24 punti) E’ domenica pomeriggio, piove e non avete voglia di studiare (né di vedere le partite!). Coi vostri amici decidete di fare una “maratona” di film. Potete scegliere fra un certo numero di film, di cui conoscete la durata esatta, e volete vedere il maggior numero di film possibili nelle ore che avete a disposizione. Il vostro problema è ora di selezionare i film. Ognuno di voi ha un’idea differente, dalla più semplice alla più complicata, ma nessuno riesce a convincere gli altri che la propria soluzione è la migliore. E il tempo passa. Vi ricordate allora che al corso di Algoritmi vi avevano tempestato con le varie tecniche di progettazione di algoritmi, sui modi per dimostrarne la correttezza e valutarne la bontà: potranno esservi utili (almeno una volta nella vita)? Formalizzate il problema reale in un problema computazionale e risolvetelo nella maniera più efficiente possibile e in modo che, soprattutto, riusciate a convincere gli altri che la vostra soluzione funziona perfettamente. Giustificate le risposte. Appello 9 luglio 2015 Quesito 2 (24 punti) Da quando ti sei registrato su Facebook ad oggi, i tuoi amici sono aumentati in maniera vertiginosa. Il primo anno avevi solo 10 amici; il secondo 35; il terzo 100 e nessuno ti elimina mai dagli amici. Hai poi notato che ogni tuo amico, 3 anni dopo averti dato la sua amicizia, ti porta un nuovo amico (spesso è un collega di università/lavoro, fidanzato/a, fratello/a, cugino/a). E tutti i tuoi nuovi amici si aggiungono sempre e solo in questo modo. Sapresti calcolare quanti diventeranno i tuoi amici nei prossimi anni? a) Descrivere un algoritmo efficiente per il calcolo del numero dei tuoi amici dopo n anni dalla tua registrazione su Facebook, supponendo che aumentino sempre rispettando la regola sopra descritta. E’ necessario analizzare la complessità di tempo e di spazio dell’algoritmo proposto. b) Valutare la crescita del numero di amici rispetto ad n (in notazione asintotica). Appello 15 gennaio 2016 Suggerimenti?