Due concetti da non confondere Problema computazionale ✦ Relazione formale che intercorre fra l'input e l'output desiderato. Spesso specificata in modo dichiarativo, non in modo procedurale ✦ Informatica II Algoritmo ✦ Capitolo 1 Introduzione agli algoritmi e strutture dati Descrizione di una sequenza di azioni che un esecutore deve compiere per giungere alla soluzione di un problema (cioè, dato un input, ottenere il corrispondente output) ✦ Gli algoritmi rappresentano e organizzano input, output e tutti i dati intermedi necessari ✦ Esempio ✦ Adattamento delle slide originali di A.Montresor. Disponibili secondo Creative Commons Attribution-NonCommercial-ShareAlike License. Problema computazionale: due esempi Minimo ✦ Input: ingredienti Output: piatto cucinato ✦ Algoritmo: ricetta Esecutore: cuoco Algoritmo: esempi ✦ ✦ Il minimo di un insieme A è l’elemento di A che è minore o uguale ad ogni elemento di A ✦ Minimo Per trovare il minimo di un insieme, confronta ogni elemento con tutti gli altri; l’elemento che è minore di tutti è il minimo Ricerca ✦ Sia A=a1,...,an una sequenza di dati ordinati e distinti, a1 < a2 < ··· < an. Eseguire una ricerca della posizione di un dato v in A consiste nel determinare l’indice corrispondente, se v è presente in A, oppure restituire 0, se v non è presente ✦ ✦ Ricerca Per trovare un valore v nella sequenza A, confronta v con tutti gli elementi di A, in ordine, e restituisci la posizione corrispondente; restituisci 0 se nessuno degli elementi corrisponde Problemi Le due descrizioni precedenti presentano diversi problemi: Come descrivere un algoritmo E' necessario utilizzare una descrizione il più possibile formale ✦ ✦ ✦ Descrizione ✦Descrivono algoritmi in linguaggio naturale (imprecisione, ambiguità, …) ✦Abbiamo bisogno di un linguaggio più formale Valutazione ✦Esistono algoritmi “migliori” di quelli proposti? ✦Dobbiamo definire il concetto di migliore Indipendente dal linguaggio: si userà uno “Pseudo-codice” ✦ Particolare attenzione va dedicata al livello di dettaglio utilizzato nella descrizione ✦ Se una ricetta della Sachertorte recita: “... amalgamate il tutto e fate riposare un quarto d'ora...” ✦ Cosa significa “amalgamare”? Cosa significa “far riposare”? ✦ ✦ Progettazione ✦Questi problemi sono semplici ✦Problemi più complessi devono essere affrontati applicando tecniche più raffinate Esempio: ricerca del minimo in un vettore Ecco una possibile soluzione al problema del minimo: E perché non c'è scritto più semplicemente “prepara la Sachertorte”? ✦ Ricerca in un array ordinato Problema ✦ Dato un vettore A contenente n elementi, verificare se un certo elemento v è presente ✦ ✦ Esempi: elenco del telefono, dizionario Una soluzione “banale” ✦ Scorro gli elementi in ordine, finché non trovo un oggetto “maggiore o uguale” a v ✦ 1 Esercizio: Scrivere un programma C/C++ che implementi questo algoritmo 5 12 15 20 23 32 21 Alcune domande Alcune domande • Quanti “passi” compie “in media” questo algoritmo? E nel caso peggiore? • Quanti “passi” compie “in media” questo algoritmo? E nel caso peggiore? • Vi viene in mente un algoritmo diverso? • Vi viene in mente un algoritmo diverso? • È migliore? • È migliore? • Ma cosa vuol dire “migliore”? • Ma cosa vuol dire “migliore”? Algoritmo alternativo: confronta v con l’elemento situato a metà del vettore. Se sono uguali ok, trovato! Altrimenti: se v è maggiore cerca nel suffisso; se v è minore cerca nel prefisso. Ricerca in un array ordinato: ricerca binaria Ricorsione e ricorsione di coda Osservando l’algoritmo di binarySearch() si nota che la chiamata ricorsiva è sempre l’ultima istruzione della funzione In questo caso si parla di ricorsione di coda (tail-recursion) La ricorsione di coda può essere facilmente sostituita con una iterazione: Esercizio: Scrivere un programma C/C++ che implementi questo algoritmo Componenti del nostro pseudo-codice per gli algoritmi: Componenti del nostro pseudo-codice per gli algoritmi: Tipi di dato composto ✦ Vettori, matrici ✦ Record ✦ Puntatori ✦ Torniamo ai problemi: Valutazione algoritmi Per valutare un algoritmo dobbiamo stabilire se: ✦ Descrizione L’algoritmo risolve correttamente il problema? ✦ Descritti in linguaggio naturale, imprecisi ✦ Abbiamo bisogno di un linguaggio più formale ✦ ✦ Valutazione Esistono algoritmi “migliori” di quelli proposti? ✦ ✦ Nota: Alcuni problemi non possono essere risolti ✦ Nota: Alcuni problemi vengono risolti in modo approssimato Risolve il problema in modo efficiente? Dobbiamo definire il concetto di migliore Progettazione Questi problemi sono semplici ✦Problemi più complessi devono essere affrontati applicando tecniche più raffinate Serve una dimostrazione formale!! (l’intuizione non basta) ✦ ✦ ✦ ✦ ✦ ✦ Prima dobbiamo definire cosa è “efficienza” ✦ Alcuni problemi non possono essere risolti in modo efficiente ✦ Esistono soluzioni “ottime”: non è possibile essere più efficienti Quali altre proprietà entrano in gioco? ✦ ✦ Semplicità, modularità, manutenibilità, espandibilità, … Valutazione algoritmi - correttezza Valutazione algoritmi - correttezza ✦ Invariante di min() Concetto di invariante ✦ All'inizio di ogni iterazione del ciclo for, la variabile min contiene il minimo parziale degli elementi nel prefisso A[1 .. i − 1] È una condizione (una proprietà espressa in modo formale) che deve essere sempre vera in un certo punto del programma ✦ Un esempio importante è l’invariante di ciclo: ✦ una condizione che è sempre vera all'inizio della iterazione di un ciclo ✦ ed vera alla fine della iterazione (e quindi sarà vera all’inizio della successiva iterazione, e all’uscita dal ciclo) ✦ Esercizio: Scrivere in modo formale l’invariante per min() Valutazione algoritmi - correttezza Il concetto di invariante di ciclo ci aiuta a dimostrare la correttezza di un algoritmo: ✦Inizializzazione (caso base): ✦la condizione è vera all'inizio ✦Conservazione (passo induttivo): Induzione ✦se la condizione è vera prima di un'iterazione del ciclo, allora rimane vera al termine (quindi sarà vera prima della successiva iterazione) ✦Conclusione: ✦Quando il ciclo termina, l'invariante deve rappresentare la “correttezza” dell'algoritmo ✦ ✦ Esercizio ✦Dimostrare che l'invariante di min() è rispettato Valutazione algoritmi - correttezza Esercizio: dimostrare la correttezza di binarySearch() ✦ Suggerimento: non si può usare un invariante di ciclo, si deve procedere per induzione sulla dimensione dell’input ✦ Valutazione algoritmi - efficienza Complessità di un algoritmo ✦ Valutazione algoritmi - efficienza Contiamo il numero di confronti per il problema del minimo ✦ Analisi delle risorse impiegate da un algoritmo per risolvere un problema, in funzione della dimensione e dal tipo dell'input ✦ ✦ Algoritmo “banale” (quello descritto all’inizio): n(n-1)/2 ✦ Algoritmo più efficiente: n-1 Perché contare i confronti? ✦ Ma cosa sono le risorse ? ✦ ✦ Tempo: tempo impiegato per completare l'algoritmo ✦ Spazio: quantità di memoria utilizzata Altre risorse: banda usata, energia consumata, numero di esecutori usati, … Valutazione algoritmi - efficienza Contiamo il numero di confronti per il problema della ricerca ✦Algoritmo “banale” (quello descritto all’inizio): n-1 ✦Algoritmo più efficiente: log n ✦ Torniamo ai problemi: ✦ ✦ ✦ Descrizione ✦ Descritti in linguaggio naturale, imprecisi ✦ Abbiamo bisogno di un linguaggio più formale Valutazione ✦ Esistono algoritmi “migliori” di quelli proposti? ✦ Dobbiamo definire il concetto di migliore Progettazione ✦ Questi problemi (min e search in un vettore) sono semplici Problemi più difficili devono essere affrontati applicando tecniche più raffinate (divide-et-impera, greedy,…) ✦ ✦ Servono anche strutture dati più complesse (code, alberi, grafi,…)