Algoritmi e Strutture Dati
Capitolo 17 - Algoritmi probabilistici
Alberto Montresor
Università di Trento
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License. To view a
copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.5/ or send a letter to Creative
Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.
© Alberto Montresor
1
Introduzione
✦
“Audentes furtuna iuvat” - Virgilio
✦
✦
Abbiamo già incontrato il concetto di casualità
✦
✦
✦
Se non sapete quale strada prendere, fate una scelta casuale
Analisi del caso medio - si calcola una media su tutti i possibili dati di ingresso,
dopo aver individuato una distribuzione di probabilità per essi
Esempio: caso medio Quicksort, si assume che tutte le permutazioni siano
equiprobabili
Negli algoritmi probabilistici
✦
Il calcolo delle probabilità è applicato non ai dati di input, ma ai dati di output
✦
Due possibilità
✦
Algoritmi corretti, il cui tempo di funzionamento è probabilistico
✦
Algoritmo la cui correttezza è probabilistica
© Alberto Montresor
2
Esempio - espressione polinomiale nulla
✦
✦
✦
Definizione: data un’espressione algebrica polinomiale p(x1 , ... , xn) in n variabili,
determinare se p è identicamente nulla oppure no
Discussione
✦
Assumiamo che non sia in forma di monomi - altrimenti è banale
✦
Gli algoritmi basati su semplificazioni sono molto complessi
Algoritmo
✦
Si genera una n-pla di valori v1, ..., vn
✦
Si calcola x= p(v1 , ... , vn)
✦
✦
✦
Se x ≠ 0, p non è identicamente nullo
✦
Se x = 0, p potrebbe essere identicamente nullo
Se vi = random(1, 2d), dove d è il grado massimo del polinomio, allora la
probabilità di errore non supera 1/2.
Si ripete k volte, riducendo la probabilità di errore a (1/2)k
© Alberto Montresor
3
Statistica
✦
✦
Algoritmi statistici su vettori: Estraggono da un vettore numerico alcune
caratteristiche statisticamente rilevanti
Esempi
✦
✦
Media: µ = (A[1] + A[2] + ... + A[n])/n
n
2
1X
=
(A[i]
n i=1
µ)2
✦
Varianza (sample variance):
✦
Moda: il valore più frequente (o i valori)
✦
Mediano: il valore che occuperebbe la posizione ⎡n/2⎤ se l'array fosse ordinato
Selezione:
✦
Dato un array A[1..n] di valori distinti e un valore 1 ≤ k ≤ n, trovare l'elemento
che è maggiore di esattamente k-1 elementi
© Alberto Montresor
4
Selezione: casi particolari
✦
Ricerca del minimo, massimo
✦
T(n) = n-1 = θ(n) confronti
✦
Possiamo dimostrare che questo
algoritmo è ottimale?
✦
✦
✦
Idea: scelta del minimo come un
“torneo”
Tutti gli elementi (tranne il
vincitore) deve perdere almeno un
“partita”
Quindi il problema è Ω(n)
© Alberto Montresor
min. Si confronta min con gli elementi co
incontra un elemento minore, si aggiorna
minimo dell’insieme, che viene restituito al
I TEM min(I TEM[ ] A, integer n)
I TEM min
A[1]
for integer i
2 to n do
if A[i] < min then
min
A[i]
return min
Ricerca della posizione Come sopra, sup
vettore. L’algoritmo proposto per risolvere q
5
for integer i ⇤ 1 to 8 do
nx casi
⇤ xparticolari
+ mx [i]
Selezione:
ny ⇤ y + my [i]
if 1 ⇥ nx ⇥ 8 and
1 ⇥ ny ⇥ 8 and S[nx , ny ] = 0 then
✦ Ricerca del secondo
minimo
C.insert(i)
✦ Trovare il secondo elemento più piccolo dell'array
return C
✦ Domanda: Analisi del caso peggiore e medio
I TEM min2(I TEM[ ] A, integer n)
I TEM min1 ⇤ A[1]
I TEM min2 ⇤ A[2]
if min2 < min1 then min1 ⌅ min2
for integer i ⇤ 3 to n do
if A[i] < min2 then
min2 ⇤ A[i]
if min2 < min1 then min1 ⌅ min2
return min2
© Alberto Montresor
6
Selezione: casi particolari
✦
Ricerca del secondo minimo
✦
✦
L'albero del torneo permette di trovare il secondo minimo in O(n + log n) confronti nel caso pessimo
5
3
Dimostrazione
6
7
✦
n passi necessari per la ricerca del minimo
✦
Siano M e S il minimo e il secondo minimo
✦
Sicuramente c'è stato un “incontro” fra M e S, dove M ha “vinto”
✦
✦
2
4
8
Se così non fosse, esisterebbe un valore X<S che ha “battuto” S → assurdo dalla definizione di S
Quindi, basta cercare nei log n valori “battuti” direttamente da M per trovare il
secondo minimo. Totale: O(n + log n)
© Alberto Montresor
7
Selezione per piccoli valori di k
✦
Intuizione
✦
L'albero del torneo può essere “simulato” da uno heap
✦
L'algoritmo può essere generalizzato a valori generici di k > 2
✦
Complessità computazionale: O(n + k log n)
✦
✦
Se k = O(n/log n), il costo è O(n)
✦
Non va ancora bene per k = n/2
Codice
heapselect(ITEM[] A, integer n, integer k)
buildHeap(A)
for i := 1 to k-1 do deleteMin(A, n)
return min(A)
© Alberto Montresor
8
Per trovare il k-esimo elemento più piccolo senza ordinare il vettore, si può utilizzare la
procedura perno() [cfr. § 12]. Ricordiamo che la procedura perno(A, primo, ultimo) scambia
Selezione
tra loro elementi di A[primo . . . ultimo] e restituisce l’indice j del “perno” tale che A[i]  A[j],
per primo  i  j, e A[i]
A[j], per j  i  ultimo. La seguente procedura selezione(),
u
Ideada Hoare (1961), richiama la perno() ed individua cosı̀ il q-esimo elemento più picproposta
colo di uA[primo
. . . ultimo],
dove q = j primo
+ 1alè Quicksort
il numero di elementi di A[primo . . . j].
Approccio
divide-et-impera
simile
Se k  q, allora selezione() è riapplicata ad A[primo . . . j]; se invece k > q, allora selezione()
u
Ma
problema
diricercare
ricerca, ilnon
necessario
cercare
entrambe
è riapplicata
ad essendo
A[j + 1 . .un
. ultimo],
ma per
(k è q)-esimo
elemento
piùin
piccolo.
La le
chiamata iniziale
è selezione
1, n, k).
partizioni,
basta(A,
cercare
in una sola di esse
I TEM selezione(I TEM[ ] A, integer primo, integer ultimo, integer k)
if primo = ultimo then
primo
1
return A[primo]
else
integer j
perno(A, primo, ultimo)
integer q
j primo + 1
if k = q then
return A[j]
else if k < q then
return selezione(A, primo, j 1, k)
else
return selezione(A, j + 1, ultimo, k q)
© Alberto Montresor
j
ultimo n
q
9
return A[j]
else if k < q then
Complessità
return selezione(A, primo, j 1, k)
else
✦ Caso pessimo: O(n2)
return selezione(A, j + 1, ultimo, k q)
✦
Caso ottimo: O(n)
Caso medio
Assumendo
che perno() restituisca con la stessa probabilità una qualsiasi posizione j d
✦ Assumiamo che perno() restituisca con la stessa probabilità una qualsiasi
ettore A,
il numero medio di confronti T (n) tra elementi di A effettuati da selezione() è da
posizione
j del vettore A
alla relazione
di ricorrenza
✦
per n = 0, 1
T (n) = 0,
n
T (n) = n
n
1X
1+
T (max{q
n q=1
2
1+
n
n
X1
T (q),
1, n
q})
per n
2
q=bn/2c
nfatti, nel caso n sia pari, è facile vedere che i valori bn/2c, bn/2c + 1, . . . , n 1 vengon
ttenuti due volte dall’espressione max{q 1, n q}, per q = 1 . . . n; se invece n è dispari
© Alberto Montresor
10
ineare nella lunghezza della porzione di A, il numero complessivo di confronti dovr
cereDimostrazione
come n + n/2 + n/4 + · · · + 1  2n. Pertanto, una soluzione promettente di T
la quale tentare sembra essere O(n).
✦ Per sostituzione
Tentiamo quindi con T (n)  cn per qualche costante c. La base dell’induzione è
mente verificata
perché 0 = T (0) = T (1)  c. Si assuma che valga l’ipotesi indu
T (n0 )  cn0 , 8n0 < n
)  cq per ogni q  n 1. Sostituendo, si ricava:
0
1
bn/2c 1
n
1
n
1
X
X
X
2c
2c @
T (n)  n 1 +
q n+
q
qA
n
n q=1
q=1
q=bn/2c
✓
◆
2c n (n 1) bn/2c (bn/2c 1)
=n+
n
2
2
c
n+
n (n 1) (n/2 + 1) (n/2)
n
= n + c (n 1) (c/2) (n/2 + 1) = n + cn c cn/4 c/2
✓
◆
1 3
3
= cn
+
c 4 2n
Poiché l’ultima quantità tra parentesi è minore di 1 per n sufficientemente grande e per
11
ortuna
scelta di c, la relazione T (n)  cn vale per ogni n
m per le stesse costa
© Alberto Montresor
Versione probabilistica
✦
✦
Siamo partiti dall’assunzione
✦
j assume equiprobabilisticamente tutti i valori compresi fra 1 e n
✦
E se non è vero?
Lo forziamo noi
✦
✦
A[random(primo, ultimo)] ↔ A[primo]
Questo accorgimento vale anche per QuickSort
© Alberto Montresor
12
Selezione in tempo pessimo lineare
✦
✦
Algoritmo deterministico
✦
Deterministico: non necessita di randomizzazione
✦
Algoritmo complesso, con fattori coinvolti molto alti
✦
Interessante dal punto di vista della tecnica
Sviluppiamo l'idea
✦
✦
Supponiamo di avere un algoritmo “black box” che mi ritorni il mediano di n
valori in tempo O(n)
Domanda
✦
Potrei utilizzarlo per ottimizzare il problema della selezione?
✦
Che complessità otterrei?
© Alberto Montresor
13
Selezione in tempo pessimo lineare
✦
✦
Se conoscessi tale algoritmo
✦
il problema della selezione sarebbe quindi risolto
✦
... ma dove lo trovo un simile algoritmo?
Rilassiamo le nostre pretese
✦
✦
✦
Supponiamo di avere un algoritmo “black box” che mi ritorni un valore che dista
al più n/4 dal mediano (nell'ordinamento)
Domanda
✦
Potrei utilizzarlo per ottimizzare il problema della selezione?
✦
Che complessità otterrei?
Un algoritmo del genere esiste!
© Alberto Montresor
14
Selezione deterministica - cenni
✦
L'idea dell'algoritmo
✦
✦
Trova il mediano mi di ogni gruppo Si
✦
Tramite una chiamata ricorsiva, trova il mediano M dei mediani mi
✦
✦
Suddividi i valori in gruppi di 5. Chiameremo l'i-esimo gruppo Si, con i ∈ [1, ⎡n/5⎤]
Usa M come pivot e richiama l'algoritmo ricorsivamente sull'array opportuno,
come nella selezione() randomizzata
Caso base
✦
Possiamo utilizzare un algoritmo d'ordinamento per trovare il mediano quando la
dimensione scende sotto una certa soglia
© Alberto Montresor
15
Selezione deterministica
I TEM select(I TEM[ ] A, integer primo, integer ultimo, integer k)
% Se la dimensione è inferiore ad una soglia (10), ordina il vettore e
% restituisci il k-esimo elemento di A[primo . . . ultimo]
if ultimo primo + 1  10 then
InsertionSort(A, primo, ultimo)
% Versione con indici inizio/fine
return A[primo + k 1]
% Divide A in dn/5e sottovettori di dim. 5 e calcola la mediana di ognuno di essi
M
new integer[1 . . . dn/5e]
for i
1 to dn/5e do
M [i]
median5(A, primo + (i 1) · 5, ultimo)
% Individua la mediana delle mediane e usala come perno
I TEM m
select(M, 1, dn/5e, ddn/5e/2e)
integer j
perno(A, primo, ultimo, m)
% Versione con m in input
% Calcola l’indice q di m in [primo . . . ultimo ] % Confronto q con l’indice cercato e
ritorna il valore conseguente integer q
j primo + 1
if q = k then
return m
© Alberto Montresor
else if q < k then
16
M
new integer[1 . . . dn/5e]
for i
1deterministica
to dn/5e do
Selezione
M [i]
median5(A, primo + (i
1) · 5, ultimo)
% Individua la mediana delle mediane e usala come perno
I TEM m
select(M, 1, dn/5e, ddn/5e/2e)
integer j
perno(A, primo, ultimo, m)
% Versione con m in input
% Calcola l’indice q di m in [primo . . . ultimo]
% Confronto q con l’indice cercato e ritorna il valore conseguente
integer q
j primo + 1
if q = k then
return m
else if q < k then
return select(A, primo, q 1, k)
else
return select(A, q + 1, ultimo, k q)
© Alberto Montresor
17
Seleziona deterministica - cenni
✦
Lemma 1
✦
✦
Lemma 2
✦
✦
La prima chiamata ricorsiva dell'algoritmo select() viene effettuata su circa n/5
(esattamente ⎡n/5⎤) elementi
Lemma 3
✦
✦
Il calcolo dei mediani M[] richiede al più 6⎡n/5⎤ confronti.
La seconda chiamata ricorsiva dell'algoritmo select() viene effettuata al massimo
su 7n/10 elementi (esattamente n - 3⎡⎡n/5⎤/2⎤)
Teorema
✦
L'algoritmo select() esegue nel caso pessimo O(n) confronti
✦
Equazione di ricorrenza: T(n) ≤ T(n/5) + T(7n/10) + 11/5n
✦
E' possibile dimostrare che T(n) = O(n)
© Alberto Montresor
18
Alcune note storiche
✦
Il problema della selezione nella storia...
✦
✦
✦
Nel 1883 Lewis Carroll (!) notò che il secondo premio nei tornei di tennis non
veniva assegnato in maniera equa.
Nel 1932, Schreier dimostrò che n + log n - 2 incontri sono sempre sufficienti per trovare il secondo posto
Nel 1973, a opera di Blum, Floyd, Pratt, Rivest e Tarjan, appare il primo
algoritmo deterministico
© Alberto Montresor
19
Bucket sort
✦
Ipotesi sull'input
✦
✦
✦
I valori da ordinare sono numeri reali uniformemente distribuiti nell'intervallo [0, 1)
Qualunque insieme di valori distribuiti uniformemente può essere normalizzato nell'intervallo [0, 1)
Idea
✦
✦
✦
Dividere l'intervallo in n sottointervalli di dimensione 1/n, detti bucket, e poi distribuire gli n numeri nei bucket
Per l'ipotesi di uniformità, il numero atteso di valori nei bucket è 1
I singoli bucket possono essere ordinati con
Insertion Sort
© Alberto Montresor
0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
20