Ricerca di un elemento in un
vettore ordinato
Lezione n°10
Algoritmi Avanzati
Prof.ssa Rossella Petreschi
Idea
Variabili:
N: numero dei processori
y: elemento da cercare
X = (x1, x2, …, xn), tale che x1  x2 …  xn: vettore in cui cercare y
l ed r (inizializzati a 0 ed n rispettivamente): estremi del vettore su cui si lavora;
q0,…qN+1 (relative a ciascun processore + 2 aggiuntive): indice degli elementi da
analizzare;
c0,…cN+1 (inizializzate a 0, cN+1 inizializzata ad 1): identificatori del sottovettore su cui
iterare.
Input: X, y
Output: i t.c. xi  y  xi+1
Passo 1: dividi iterativamente il vettore in sottovettori più o meno bilanciati finché il
numero di elementi nel sottovettore identificato non è  N e controlla se X[qi]=y;
Passo 2: controlla se nel sottovettore di dimensione  N è presente l’elemento cercato.
Algoritmo
P1:
c0 = 0; cN+1 = 1; l=0; r=n+1;
while (r-l) > N do
Pj:
for j = 1 to N pardo
if j = 1 then q0 = l; qN+1 = r
qj = l +  j (r-l) / (N+1) 
if y = X[ qj ] then return qj
else if y > X[ qj ] then cj = 0 else cj = 1
if cj < cj+1 then l = qj; r = qj+1
if j = 1 and c0 < c1 then r = q1
Pj:
for j = 1 to N pardo
if y = X[ l+j ] then return l+j
else if y > X[ l+j ] then cj = 0 else cj = 1
if cj < cj+1 then return l+j
if j = 1 and c0 < c1 then return l
Passo 1
Passo 2
Esempio
l
0
r
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
n = 14
N=2
y = 37
x - -22 -3 4 10 12 15 27 32 35 42 55 56 61 70 
q0
q1
q2
0
c
l
4
1
6
7
8
9
10
11
x 10 12 15 27 32 35 42 55
q0 q1
0
c
q2
1
2
q3
3
0 0 1 1
r
5
2
q3
Passo 2
l
7
8
9
10
11
x 27 32 35 42 55
0
3
0 0 0 1
r
c
1
2
3
0 0 1 1
return 9
Complessità dell’algoritmo
•Ciascuna iterazione del Passo 1 richiede tempo O(1).
•Dimensione del sottovettore alla iterazione i-esima:
si+1 = si / (N+1) = s0 / (N+1)i = n+2 / (N+1)i
•Numero totale di iterazioni:
logN+1(n+2) = log2(n+2) / log2(N+1)
•Il Passo 2 richiede tempo costante.
Tempo complessivo richiesto dall’algoritmo: O(log2(n+2) / log2(N+1)).
Il modello di PRAM è CREW perché tutti gli N processori accedono
contemporaneamente alle variabili y, l, r e c.
Quando N = O(1), il costo complessivo dell’algoritmo è O(log n): pari all’ottimo nel
sequenziale.
Quando N = O(n) il tempo diventa costante.
Algoritmo pari/dispari
L’idea base è quella di far lavorare prima tutti i processori di indice pari e poi quelli di
indice dispari per evitare letture e scritture concorrenti nei confronti.
0
• for s = 1 to n/2 do
• for i = 0 to i < n-1 step 2 pardo
•Pi:
if x[i] > x[i+1] then swap(x[i], x[i+1])
• for i = 1 to i < n-1 step 2 pardo
•Pi:
if x[i] > x[i+1] then swap(x[i], x[i+1])
1
2
3
4
5
6
s=1 pari
8 5 9 2 4 3 6
s=1 dispari
5 8 2 9 3 4 6
s=2 pari
5 2 8 3 9 4 6
s=2 dispari
2 5 3 8 4 9 6
s=3 pari
2 3 5 4 8 6 9
s=3 dispari
2 3 4 5 6 8 9
Fine
2 3 4 5 6 8 9
•Richiede tempo O(n) su una PRAM EREW con O(n) processori.
•Il costo complessivo è O(n2).
Algoritmo pari/dispari
con p < n processori
Ogni processore Pi gestisce un blocco Si composto di b = n/p elementi.
Pi: ordina Si in modo sequenziale
for s = 0 to p/2 do
for i = 0 to i < p-1 step 2 pardo
Pi:
Si' = Merge(Si, Si+1)
Si = Si' [0, b-1]
Si+1 = Si' [b, 2b-1]
for i = 1 to i < p-1 step 2 pardo
Pi:
Si' = Merge(Si, Si+1)
Si = Si' [0, b-1]
Si+1 = Si' [b, 2b-1]
Il tempo richiesto è Tp = O(n/p log (n/p)) + p/2 O(n/p).
Se p = O(log n), il tempo Tp diventa O(n), ovvero costo totale O(n log n).
Ordinamento su PRAM CRCW
Sfruttiamo la scrittura concorrente per ottenere un semplice algoritmo di ordinamento.
Assumiamo una PRAM CRCW con scrittura concorrente della somma dei valori scritti.
xiniz
for i = 0 to n-1 pardo
for j = 0 to n-1 pardo
Pi,j:
if (x[ i ] > x[ j ]) or
(x[ i ] = x[ j ] and i > j) then c[ i ] = 1
for i = 0 to n-1 pardo
Pi,1: x[ c[ i ] ] = x[ i ]
7
5
3
8
5
0
1
2
3
4
1
2
3
4
0
1
2
3
4
xfin
3
5
5
7
8
Risultati dei confronti
effettuati
i
Con n2 processori il tempo richiesto è O(1).
Il costo totale è quindi O(n2).
0
C
3
1
0
4
2
0
1
2
3
4
j
0
1
2
3
4
F
F
F
V
F
V
F
F
V
V
V
V
F
V
V
F
F
F
F
F
V
F
F
V
F