# Algoritmi e Complessita' Esame: seminario algoritmo/argomento teorico + esame orale (leggero, a meno che non si riesca a fare la presentazione). ## Introduzione Panoramica su tecniche algoritmiche. Studio di complessita' e limiti di applicabilita'. ### Procedimento automatico Risoluzione di problemi utilizzando dati in input e restituendo dati in output. Risorse limitate, ci si basa sulla macchina registri (asciando da parte lambda calculus). Programmazione imperativa. *(vedi slides per linguaggio di disegno, pseudolinguaggio utilizzato per descrivere algoritmi nel corso)* ### Complessita' Lo studio e' relativo principalmente alla complessita' nel tempo, soluzione classica: complessita' **asintotica** (notazione *O(f(n))*, *o(f(n))*, *theta(f(n))* che significa sia *O* sia *o* di *f(n)*, moltiplicata per due costanti *c1* e *c2* ). Importante e' la differenza tra algoritmi polinomiali (n, n^2, nlog(n), ...) e algoritmi **esponenziali** (a^n), che si rivelano molto limitati rispetto ai polinomiali (a causa del tempo richiesto vs. crescita del dataset). ### Ottimizzazione I problemi di computazione in cui i dati sono **finitamente rappresentabili** richiedono spesso **ottimizzazione discreta** (per trovare il risultato *migliore/ottimale*). ### Problemi NP-difficult Molti problemi (commesso viaggiatore, ciclo hamiltoniano, etc) sono **NP-difficili**, per cui quindi il tempo di esecuzione e' ***almeno esponenziale***. Spesso, per ridurre il problema a polinomiale, si deve: * ridurre il tipo di dati in input (classi di input per cui funziona in polinomiale). oppure: * accettare che si possa richiedere un gran numero (infinito) di risorse per un determinato problema. * accettare **risultati approssimati** (il risultato migliore restituito potrebbe non essere il miglore in assoluto). Questo include anche **algoritmi probabilistici**, che restituiscono risultati esatti **con una certa probabilita'**. (es: Test di Primarieta'). Da questo deriva il problema P==NP. ### Tecniche algoritmiche principali * Greedy (sempre scelta localmente ottima) * Divide-et-Impera (scomposizione in sottoproblemi con approccio top-down) * Programmazione dinamica (come d-e-i, ma **bottom up** da sottoproblemi potenzialmente ripetuti) * Backtracking (spesso esponenziale) * Ricerca locale (migliorare soluzioni esistenti non ottime) #### Soluzioni a problemi complessi (NP) * Approssimazione (risultati approssimati) * Randomizzazione (algoritmi probabilistici o randomizzati) * Algoritmi Genetici / Simulated annealing / Ricerca Tabu' (per problemi di ottimizzazione combinatoria, *meta-algoritmi*)