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,…)