Algoritimi
Moreno Marzolla
Dipartimento di Informatica—Scienza e Ingegneria (DISI)
Università di Bologna
http://www.moreno.marzolla.name/
Algoritmi
2
Algoritmi
3
Algoritmi
●
●
Un algoritmo è un procedimento per
risolvere un problema mediante una
sequenza finita di passi elementari
– Descritto in modo preciso allo scopo di
automatizzarne l'esecuzione
Il termine deriva dal nome del matematico
persiano Muhḥammad ibn Mūsā alKhwārizmī (‫)محمد بن موسى الخوارزمی‬
– Autore di un primo fondamentale
trattato di algebra (‫الكتاب المختصر في‬
‫ حساب الجبر والمقابلة‬al-Kitāb almukhtasḥar fī hḥisāb al-jabr walmuqābala)
– Un cratere lunare porta il suo nome
Algoritmi
Muhḥammad ibn Mūsā al-Khwārizmī
(c. 780 – c. 850) (francobollo sovietico
commemorativo; Fonte: Wikipedia)
4
Proprietà di un algoritmo
●
Atomicità
–
●
Non ambiguità
–
●
L'algoritmo deve essere composto da un numero finito di passi e
richiedere una quantità finita di risorse (di qualunque tipo) per la sua
esecuzione;
Terminazione
–
●
I passi devono essere interpretabili in modo diretto e univoco
dall'esecutore, sia esso umano o artificiale;
Finitezza
–
●
I passi costituenti devono essere elementari, cioè non ulteriormente
scomponibili;
L'esecuzione deve avere termine dopo un tempo finito;
Effettività
–
L'esecuzione deve portare ad un risultato univoco.
Algoritmi
5
E' un algoritmo?
●
●
●
●
●
Atomicità
Non ambiguità
Finitezza
Terminazione
Effettività
"Tutte le qualità di funghi possono fare al caso;
ma io ritengo che i porcini sieno da preferirsi,
esclusi però i grossissimi. Nettateli bene dalla
terra e lavateli, poi tritateli minuti alla
grossezza di un cece o anche meno. Metteteli
al fuoco con burro, sale e pepe e quando
avranno soffritto alquanto, tirateli a cottura con
sugo di carne. Ritirati dal fuoco, legateli con
balsamella, uova e parmigiano e assodate il
composto a bagno-maria. Grammi 600 di
funghi in natura con cinque uova faranno uno
sformato bastante per dieci persone. Servitelo
caldo e per tramesso."
[Pellegrino Artusi (1910), La scienza in cucina
e l'arte di mangiar bene, 452 Sformato di
Funghi]
Algoritmi
6
Cosa si intende per "istruzione elementare"?
●
●
Dipende dall' "esecutore" che consideriamo
Nell'esempio "culinario", le istruzioni devono essere
tali da poter essere eseguite in modo non ambiguo da
chiunque voglia cimentarsi con la cucina
–
–
–
–
–
"Separare il tuorlo dell'uovo dall'albume"
"Versare due cucchiaini di zucchero nel composto"
"Portare l'acqua ad ebollizione"
"Frullare il composto per 5 min"
...
Algoritmi
7
Cosa si intende per "istruzione elementare"?
●
Noi considereremo come "istruzioni elementari" cose
del tipo:
–
Assegnare un valore ad una variabile
●
–
Calcolare il valore di una espressione aritmetica
●
–
–
Es: b ← (3+a)*5 - 1
Confrontare il valore di due espressioni
●
–
Es: a ← 5
Es: a < (b+3)
Chiedere all'utente l'inserimento di un valore, oppure
visualizzare un valore
...
Algoritmi
8
Come si descrive algoritmo?
●
●
●
Linguaggio naturale
Pseudocodice
Notazioni grafiche (diagrammi di flusso o flowchart)
Algoritmi
9
Esempio: Massimo Comun Divisore
Descrizione in linguaggio naturale
1.Siano n e m due valori interi positivi
2.Se n = m, termina indicando n come risultato
3.Se n > m:
–
–
assegna a n il valore (n - m);
torna al punto 2
4.Se n < m:
–
–
assegna a m il valore (m - n);
torna al punto 2
Algoritmi
10
Vantaggi e svantaggi del linguaggio
naturale
●
Vantaggi
–
●
Notazione comprensibile
anche ai non esperti
Svantaggi
–
–
Algoritmi
Il linguaggio naturale può
risultare verboso, e quindi
produrre una descrizione
prolissa
Persone diverse hanno
stili di scrittura diversi, e
questo può in certi casi
generare ambiguità
11
Esempio: Massimo Comun Divisore
Descrizione mediante pseudocodice
Precondizione: quali
proprietà devono valere
perché l'algoritmo
fornisca il risultato
desiderato
Postcondizione: quali
proprietà valgono al
termine dell'esecuzione,
nell'ipotesi in cui le
precondizioni siano
soddisfatte
Pre: n, m interi > 0
Post: Stampa il MCD(n,m)
while (n ≠ m) do
if (n > m) then
n ← n – m;
else
m ← m – n;
end if
end while
Stampa n;
Algoritmi
12
Vantaggi e svantaggi dello
pseudocodice
●
Vantaggi
–
–
–
●
Consente descrizioni più
precise e meno verbose
rispetto al linguaggio
naturale
Può essere compreso
anche da utenti non esperti
purché abbiano una minima
confidenza con la notazione
Facilita la traduzione
dell'algoritmo in un "vero"
linguaggio di
programmazione
Algoritmi
Svantaggi
–
Notazione non univoca:
non esiste un unico “tipo”
di pseudocodice
13
Esempio: Massimo Comun Divisore
Descrizione mediante flowchart
L'esecuzione inizia
da questo nodo
Nodo condizionale: deve
contenere una
espressione che da come
risultato vero/falso
Inizio
F
n≠m
V
F
V
n>m
m←m-n
n←n-m
Stampa n
L'esecuzione termina
in questo nodo
Algoritmi
Fine
Nodo di input/output:
indica che si chiede
l'immissione o la stampa
di valori
14
Vantaggi e svantaggi dei diagrammi
di flusso
●
Vantaggi
–
–
–
●
Notazione di facile
comprensione anche per
non esperti
Consente di individuare “a
colpo d'occhio” strutture
particolari come cicli e
condizioni
Esistono software per
“disegnare” flowchart, e
convertirli in codice
eseguibile
Algoritmi
Svantaggi
–
Possono risultare confusi
per algoritmi di dimensioni
medio-grandi
●
–
I flowchart richiedono uno
spazio maggiore rispetto
alle descrizioni testuali
Se abusati, possono
produrre descrizioni
incomprensibili
●
Vedi seguito
15
Flowchart
●
In linea di principio, un diagramma di flusso può avere
una struttura arbitraria...
–
●
cioè è possibile connettere i blocchi in qualsiasi modo
...però questa libertà può portare ad algoritmi difficili
(impossibili?) da comprendere
Algoritmi
16
Programmazione strutturata
●
Paradigma di programmazione in cui qualsiasi
algoritmo viene espresso combinando tra loro alcune
strutture di controllo fondamentali
–
–
–
●
Sequenza
Condizione
Iterazione
La programmazione strutturata consente di descrivere
algoritmi in modo più comprensibile e meno soggetto a
errori
–
Può a volte risultare utile deviare dalle rigide regole della
programmazione strutturata
Algoritmi
17
Costrutti fondamentali
Sequenza
S1
S2
S1
S2
Condizione: if-then
C
if C then
S
end if
F
V
S
Condizione: if-then-else
if C then
Strue
else
Sfalse
end if
Algoritmi
F
Sfalse
C
V
Strue
18
Costrutti fondamentali
Iterazione: for
Iterazione: while-do
C
while C do
S
end while
F
for v ← a to b do
S
end for
V
S
v←a
v≤b
V
Iterazione: do-while
S
S
do
S
while C
F
V
C
v←v+1
F
Algoritmi
19
Composizione
●
E' possibile rimpiazzare i blocchi tratteggiati con altri
costrutti (proprietà di composizione)
Inizio
n≠m
F
F
m←m-n
V
n>m
V
n←n-m
Fine
Stampa n
Algoritmi
20
Esempio: Elevamento a potenza
●
Scrivere un algoritmo che, dati in input un numero
reale x ≠ 0 e un intero n ≥ 0, calcola il valore xn
n
x =⏟
x×x …×x
n volte
–
Per definizione si ha che x0 = 1
Algoritmi
21
Elevamento a potenza
Inizio
Leggi x, n
Pre: x ≠ 0, n intero ≥ 0
Post: Stampa p = xn
p←1
p ← 1
while (n > 0) do
p ← p * x
n ← n – 1
end while
Stampa p
n>0
F
V
p←p*x
n←n-1
Stampa p
Algoritmi
Fine
22
Esempio: Massimo e Minimo
●
Dato un array (vettore) di valori reali v0, v1, … vn-1, scrivere un
algoritmo per determinare il valore massimo e minimo
presente nell'array
–
–
●
Se tutti i valori sono uguali, massimo e minimo coincidono
Se l'array ha un solo elemento (n = 1), massimo e minimo
coincidono con l'unico valore presente
Un array di n elementi può essere intuitivamente immaginato
come un insieme di n "scatole" (celle), ciascuna etichettata
con un intero da 0 a n – 1 e contenente un valore
Celle dell'array
21
6
7
-2
15
0
1
2
3
4
Algoritmi
41
33
41
5
6
7
23
Indici delle celle
Inizio
Possibile soluzione
Min ← v0 Max ← v0
i←1
Pre: v0, v1, … vn-1 array non vuoto
di valori reali (n ≥ 1)
Post: Min, Max sono i valori minimo
e massimo presenti nell'array
Min ← v0
Max ← v0
for i ← 1 to n-1 do
if (vi < Min) then
Min ← vi
else if (vi > Max) then
Max ← vi
end if
end for
Stampa Min, Max;
i<n
F
V
F
F
vi > Max
vi < Min
V
V
Min ← vi
Max ← vi
i←i+1
Stampa Min, Max
Algoritmi
Fine
24
Esempio: Ricerca Binaria
●
●
●
Dati:
–
Un array di valori reali distinti v0, v1, … vn-1 ordinati in senso
crescente (v0 < v1 < … < vn-1 )
–
Un valore reale k (arbitrario)
Determinare la posizione di k nell'array (se presente)
–
Cioè determinare l'indice i, se esiste, tale che vi = k
–
Se k non compare nell'array, restituire -1
Es:
v0
v1
v2
v3
v4
v5
v6
v7
-3
-1
2
5
6
13
15
21
Algoritmi
k = 13
Il risultato deve essere 5
25
Esempio
●
Ricerca di k = 7
2
3
7
12
Algoritmi
18
21
27
26
Esempio
●
Ricerca di k = 7
2
3
7
12
Algoritmi
18
21
27
27
Esempio
●
Ricerca di k = 7
2
3
7
12
Algoritmi
18
21
27
28
Esempio
●
Ricerca di k = 7
2
3
7
12
Algoritmi
18
21
27
29
Esempio
●
Ricerca di k = 7
2
3
7
12
Algoritmi
18
21
27
30
Esempio
●
Ricerca di k = 7
2
3
7
12
18
21
27
Trovato!
Algoritmi
31
Esempio
●
Ricerca di k = 20
2
3
7
12
Algoritmi
18
21
27
32
Esempio
●
Ricerca di k = 20
2
3
7
12
Algoritmi
18
21
27
33
Esempio
●
Ricerca di k = 20
2
3
7
12
Algoritmi
18
21
27
34
Esempio
●
Ricerca di k = 20
2
3
7
12
Algoritmi
18
21
27
35
Esempio
●
Ricerca di k = 20
2
3
7
12
Algoritmi
18
21
27
36
Esempio
●
Ricerca di k = 20
2
3
7
12
Algoritmi
18
21
27
37
Esempio
●
Ricerca di k = 20
2
3
7
12
18
21
27
Non trovato!
Algoritmi
38
Domande
●
Dato un array ordinato di n elementi:
–
–
Quanti elementi bisogna esaminare nel caso migliore?
Quanti elementi bisogna esaminare nel caso peggiore?
Algoritmi
39
Funzionamento dell'algoritmo
●
●
Usiamo due valori interi i (inizio) e f (fine) per
rappresentare la posizione (indice) del primo e
dell'ultimo elemento della porzione di array in cui
potrebbe trovarsi il valore cercato
Indichiamo con m (mezzo) l'indice dell'elemento che
occupa la posizione centrale nel sottovettore v i … vf
i=0
m=3
f=6
v0
v1
v2
v3
v4
v5
v6
2
3
7
12
18
21
27
Cerchiamo k = 3
Algoritmi
40
Funzionamento dell'algoritmo
●
●
Usiamo due valori interi i (inizio) e f (fine) per
rappresentare la posizione (indice) del primo e
dell'ultimo elemento della porzione di array in cui
potrebbe trovarsi il valore cercato
Indichiamo con m (mezzo) l'indice dell'elemento che
occupa la posizione centrale nel sottovettore v i … vf
i=0
m=3
f=6
v0
v1
v2
v3
v4
v5
v6
2
3
7
12
18
21
27
Cerchiamo k = 3
Algoritmi
41
Funzionamento dell'algoritmo
●
●
Usiamo due valori interi i (inizio) e f (fine) per
rappresentare la posizione (indice) del primo e
dell'ultimo elemento della porzione di array in cui
potrebbe trovarsi il valore cercato
Indichiamo con m (mezzo) l'indice dell'elemento che
occupa la posizione centrale nel sottovettore v i … vf
i=0
m=1
f=2
v0
v1
v2
v3
v4
v5
v6
2
3
7
12
18
21
27
Trovato in posizione m = 1
Algoritmi
42
Pseudocodice
primo tentativo
Pre: v0, v1, … vn-1 array non vuoto ordinato, valore k
Post: stampa la posizione del valore k nell'array, se presente,
altrimenti stampa "non trovato"
i ← 0
f ← n - 1
while "sottovettore non vuoto" do
m ← "posizione centrale nel sottovettore vi … vf"
if (vm = k) then
stampa "Trovato in posizione:" m;
stop
else
"aggiorna estremi i ed f"
endif
endwhile
stampa "Non trovato"
Algoritmi
43
Primo raffinamento
●
Come facciamo a "calcolare la posizione centrale nel
sottovettore vi … vf" ?
(f – i + 1) elementi
i
m
f
...
...
Circa (f – i)/2 elementi
Circa (f – i)/2 elementi
m = i + (f – i) / 2 = (i + f) / 2
Algoritmi
44
Attenzione...
●
Controlliamo se funziona anche in casi particolari
i=1
f=2
m = (1 + 2) / 2 = 1
i=4
f=4
m = (4 + 4) / 2 = 4
Algoritmi
45
Pseudocodice
raffinamento
Pre: v0, v1, … vn-1 array non vuoto ordinato; valore k
Post: stampa la posizione del valore k nell'array, se presente,
altrimenti stampa "non trovato"
i ← 0
f ← n - 1
while "sottovettore non vuota" do
m ← (i + f) / 2;
if (vm = k) then
stampa "Trovato in posizione:" m;
stop
else
"aggiorna estremi i ed f"
endif
endwhile
stampa "Non trovato"
Algoritmi
46
Secondo raffinamento
●
Se il valore centrale non è quello cercato, come
aggiornare il valore di i ed f ?
–
Caso 1: il valore centrale è troppo grande (es., cerchiamo 3,
valore centrale è 12)
i
2
m
3
i
2
7
f
12
18
21
27
12
18
21
27
f
3
7
Algoritmi
47
Secondo raffinamento
●
Se il valore centrale non è quello cercato, come
aggiornare il valore di i ed f ?
–
Caso 2: il valore centrale è troppo piccolo (es., cerchiamo
21, valore centrale è 12)
i
2
m
3
7
12
f
18
21
i
2
3
7
12
Algoritmi
18
27
f
21
27
48
Pseudocodice
ulteriore raffinamento
Pre: v0, v1, … vn-1 array non vuoto ordinato, valore k
Post: stampa la posizione del valore k nell'array, se presente,
altrimenti stampa "non trovato"
i ← 0
f ← n - 1
while "sottovettore non vuoto" do
m ← (i + f) / 2;
if (vm = k) then
stampa "Trovato in posizione:" m;
stop
else
if (vm > k) then
f ← m – 1;
else
i ← m + 1;
endif
endif
endwhile
Algoritmi
stampa "Non trovato"
49
Raffinamento finale
●
●
L'algoritmo termina quando non ci sono più elementi
da esaminare
Es: cerchiamo k = 13
i=0
m=1
f=2
i ← 0
f ← n - 1
while "sottovettore non vuoto" do
m ← (i + f) / 2;
if (vm = k) then
stampa "Trovato in posizione:" m;
stop
else
if (vm > k) then
f ← m – 1;
else
i ← m + 1;
endif
endif
endwhile
stampa "Non trovato"
Algoritmi
2
2
2
12
15
i=2
m=2
12
15
f=1
i=2
12
15
f=2
50
Pseudocodice
versione finale
Pre: v0, v1, … vn-1 array non vuoto ordinato, valore k
Post: stampa la posizione del valore k nell'array, se presente,
altrimenti stampa "non trovato"
i ← 0
f ← n - 1
while (f ≥ i) do
m ← (i + f) / 2;
if (vm = k) then
stampa "Trovato in posizione:" m;
stop
else
if (vm > k) then
f ← m – 1;
else
i ← m + 1;
endif
endif
endwhile
Algoritmi
stampa "Non trovato"
51
Esercizio per casa
Ricerca sequenziale
●
Dati:
–
–
●
Un array di valori reali v0, v1, … vn-1 non necessariamente
distintie non ordinati
Un valore reale k (arbitrario)
Determinare la posizione di k nell'array (se presente)
–
Cioè determinare un indice i, se esiste, tale che vi = k
–
Se esistono più elementi dell'array con valore k è possibile
restituire l'indice di una qualunque occorrenza
Se k non compare nell'array, restituire -1
–
Algoritmi
52
Esercizio per casa
Primo e secondo minimo
●
●
Dato un array di valori reali distinti v0, v1, … vn-1 con
almeno due elementi (n ≥ 2), scrivere un algoritmo per
determinare i due valori minimi
Es:
–
–
1, 9, -3, 7, 5, 12, 4 → ritorna -3, 1
1, 2, 3, 4, 5 → ritorna 1, 2
Algoritmi
53
Primo e secondo minimo
●
Idea: esaminiamo uno per uno gli elementi dell'array
Supponiamo di aver determinato i valori Min1, Min2 del primo e
secondo minimo del sottovettore v1, v2, … vi – 1
●
Esaminiamo il valore vi
●
Tre casi possibili
●
vi
Min1
–
vi < Min1
–
Min1 < vi < Min2
Min1
–
vi > Min2
Min1
Min2
vi
Min2
Min2
vi
(Per ipotesi tutti i valori sono distinti, quindi non si potrà mai verificare
che vi = Min1 oppure vi = Min2)
Algoritmi
54
Primo e secondo minimo
In ciascuno dei tre casi, come dobbiamo modificare i
valori Min1 e Min2 affinché essi siano ancora il primo e
il secondo minimo del sottovettore v0, v1, … vi?
●
vi
Min1
Min1
Min1
●
Min2
vi
Min1
Min2
Min2
Min2
Min1 Min2
Min1
vi
Min2
Come definiamo Min1 e Min2 all'inizio?
Algoritmi
55
Esercizio per casa
Deposito
●
Il primo gennaio dell'anno zero, Augusto deposita l'equivalente di 1
Euro in banca, negoziando un tasso composito del 5% annuo
–
Il primo gennaio dell'anno 1 si trova nel conto 1(1+0.05) = 1.05 Euro
–
Il primo gennaio dell'anno 2 si trova nel conto 1.05(1+0.05) = 1.1025 Euro
–
Il primo gennaio dell'anno 3 si trova nel conto 1.1025(1+0.05) = 1,157625
Euro
… e così via
–
●
●
●
Il primo gennaio dell'anno zero, Claudia deposita l'equivalente di 100
Euro in banca, negoziando un tasso composito del 4% annuo
Entrambi i depositi vengono tramandati di generazione in
generazione, alle stesse condizioni
In quale anno l'importo presente nel conto (degli eredi) di Augusto
diventa strettamente maggiore di quello presente nel conto (degli
eredi) di Claudia?
Algoritmi
57