Title: Dimostrazione per induzione: esempio
1Dimostrazione per induzione esempio
n-1
n
?
?
...ma
i n (n-1)(n)/2 n n(n1)/2
i
i1
i1
Luguaglianza tra questi due termini non è altro
che affermazione(n-1) e quindi la assumiamo vera
per ipotesi induttiva.
2Metodo di sostituzione
- Primo passo
- Ci buttiamo a indovinare una possibile
soluzione T(n) clog2(n) - Secondo passo
- la verifichiamo per induzione come segue
- Assumiamo che T(n) clog2(n) per n lt n
- e dimostriamo che T(n) clog2(n)
- c è una costante (indipendente da n) che
determineremo strada facendo
3T(n) T(n/2) 1 clog2(n/2)
1 clog2(n) - clog2(2)
1 clog2(n) - c 1 se c 1
allora clog2(n)
?
Ipotesi induttiva !!!
4Equazioni ricorsive un esempio più complicato
?(1) se n 1
T(n)
2T(n/2) ?(n) se n gt 1
Soluzione T(n) ?(n log(n))
5Albero di ricorsione
c n
Cn 2T(n/2)
c n
C(n/2) 2T(n/4)
C(n/2) 2T(n/4)
c n
C(n/4) 2T(n/8)
C(n/4) 2T(n/8)
C(n/4) 2T(n/8)
C(n/4) 2T(n/8)
c n
?(1)
?(1)
?(1)
?(1)
n(log(n))
Il fattore log(n) deriva dal fatto che lalbero
ha un altezza log(n)
6Master Method
- T(n) aT(n/b) f(n) a ? 1, b gt 1,
f(n) gt 0
Poniamo x logba
f(n) O(nx-?) con ?gt0 allora T(n)
?(nx)
f(n) ?(nx) allora T(n)
?(nx log(n))
f(n) ?(nx?) con ?gt0 af(n/b)
cf(n) con clt1 allora T(n) ?(f(n)) per
tutti gli ngtn0
7 Merge sort T(n) ?(n log(n))
Insertion sort
Merge sort
?(n2) ?(n log(n))
Worst case
?(n2) ?(n log(n))
Average case
?(n) ?(n log(n))
Best case
8Perchè ordinare è importante
- velocizza molto la ricerca !!!
Binary-search(A,x) i0 jlength(A)-1
while iltj do k?(ij)/2? if Akx
then return true if Akgtx then jk-1
if Akltx then ik1 if Aix then return
true else return false
9Analisi di Binary search
- Poniamo D(t)j-i. D(t) è lampiezza del vettore
sul quale ancora dobbiamo eseguire la ricerca
dopo t confronti. Abbiamo - D(0) n-1
-
-
- D(t1) D(t)/2
- Usciamo dal while quando D(t)lt2
- ovvero se t log2n.
- Quindi T(n) ?(log2n)
10Priority Queue (Code a Priorità)
- Dati un insieme di elementi, ognuno dei quali ha
una chiave (un intero per esempio). - Operazioni inserimento, trova il massimo,
estrazione del massimo (massima chiave). - Applicazioni delle PQ Job scheduling Event-driv
en simulations
11Implementazione (facile) usando vettori
- Prima soluzione vettore ordinato. Ricerca
massimo ?(1) operazioni estrazione
massimo ?(1) operazioni inserimento
?(n) operazioni - Seconda soluzione vettore non ordinato.
- Ricerca massimo ?(n)
operazioni estrazione massimo ?(n)
operazioni inserimento ?(1)
operazioni - Si può fare meglio ???
12Grafi e Alberi
- G(V,E) V1,2,3,4,5,6,7,8E(1,2),(1,3),(1,4),
(3,4),(6,7),(7,8)
1,3,4,1 è un ciclo. Un grafo senza cicli è
aciclico.
6
2
1
7
3
4
5
8
13Un albero è un grafo aciclico con un numero di
nodi uguale al numero di archi più uno (
VE1 )
6
2
1
Albero
7
3
4
5
8
6
2
1
Foresta
7
3
4
5
8
14Radice
r
h(a) altezza del nodo a h(x)1 h(y)h(q)2 h(w
)3
x
q
y
w
r è la radice x è il padre di y y è un figlio di
x x e q sono avi di w w e q sono discendenti di
x q è fratello di y
Foglie
15Heap
128
72
64
30
12
8
7
6
1
3
A 128, 64, 72, 8, 7, 12, 30, 1,
6, 3 1 2 3 4 5
6 7 8 9 10
A(6) 12
16Heap definizione formale
- Un Heap è un albero binario quasi completo. Quasi
significa che possono mancare alcune foglie
consecutive a partire dallultima foglia di
destra. - Per ogni nodo i Value(i) Value(Parent(i))
- Nota 1 il massimo si trova nella radice
- Nota 2 non cè nessuna relazione tra il valore
di un nodo e quello di un suo fratello
17Memorizzazione di un heap in un vettore
128
72
64
30
12
8
7
6
1
3
18Memorizzazione di un heap in un vettore
- Radice posizione 1
- Per ogni nodo in posizione ileft-child(i)
posizione 2iright-child(i) posizione
2i1parent(i) ?i/2?
19i
A
B
Heaps
Heap
i
2i
2i1
4i
4i 3
8i
8i 7
parte del vettore già heapizzato
elemento da aggiungere al sotto heap (verde)
20IDEA facciamo scendere il nodo i nellalbero
finoa trovare la sua posizione.
i
A
B
21Heapify(A,i)
- Heapify(A,i)
- lleft(i)
- rright(i)
- if lheap-size(A) and AlgtAi
- then largestl
- else largesti
- if rheap-size(A) and ArgtAlargest
- then largestr
- if largest?i
- then Exchange(Ai,Alargest)
- Heapify(A,largest)
22Heapify costo computazionale
Caso pessimo il nodo si sposta fino ad arrivare
alle foglie. Heapify impiega tempo costante ad
ogni livello per sistemare Ai, Aleft(i) e
Aright(i). Esegue aggiustamenti locali al
massimo height(i) volte dove height(i) O(log(n))
23Build-heap(A)
- Build-heap(A)
- heap-size(A)length(A)
- for i?length(A)/2? downto 1 do heapify(A,i)
Analisi approssimativa ogni chiamata a heapify
costa O(log(n)). Chiamiamo heapify O(n) volte,
quindi build-heap O(nlog(n)) Domanda
(esercizio) build-heap ?(nlog(n)) ?
24PQ implementate con Heap
- Extract-max(A)
- if heap-size(A)lt1 then error
- maxA1
- A1Aheapsize(A)
- heapsize(A)heapsize(A)-1
- Heapify(A,1)
- return max
O(log(n))
25PQ implementate con Heap
max ??
26PQ implementate con Heap
- Insert(A,x)
- heap-size(A)heap-size(A)1
- iheap-size(A)
- while igt1 and Aparent(i)ltx
- do AiAparent(i)
- iparent(i)
- Aix
O(log(n))
27Heap Sort lidea.
Heap
Heapify
Heap
Heapify
... avanti così...
28Heap Sort
- Heap-Sort(A)
- build-heap(A)
- for ilength(A) downto 2
- do exchange(A1,Ai)
- heap-size(A)heap-size(A)-1
- heapify(A,1)
O(nlog(n)) È un metodo in place
29Quicksort lidea
- Dividi Dividi il vettore in due parti non vuote.
- Conquista ordina le due parti ricorsivamente
- Combina fondi le due parti ottenendo un vettore
ordinato.
A10,5,41,3,6,9,12,26
A metà A110,5,41,3 A26,9,12,26
mergesort
Dividi
Intorno a un Pivot, es 12A110,5,3,6,9,12
A241,26
quicksort
30Quicksort
- Quicksort(A,p,r)
- if pltr then
- qpartition(A,p,r)
- Quicksort(A,p,q)
- Quicksort(A,q1,r)
Nota Mergesort lavora dopo la
ricorsione Quicksort lavora prima della
ricorsione Partition è cruciale !!!
31A(p,r)
i
j
5 3 2 6 4 1 3 7
Pivot
i
j
5 3 2 6 4 1 3 7
i
j
3 3 2 6 4 1 5 7
i
j
3 3 2 6 4 1 5 7
i
j
3 3 2 1 4 6 5 7
?(n) in place
i
j
3 3 2 1 4 6 5 7
lt 5
5
32Analisi di QS nel caso ottimo
- Caso ottimo partizioni bilanciate
- T(n) 2T(n/2) ?(n)
- quindi T(n) ?(nlog(n))
33Analisi di QS nel caso pessimo
- Caso pessimo partizioni sbilanciate
- T(n) T(n-1) ?(n)
- quindi T(n) ?(n2)
partition
ricorsione
34Analisi di QS nel caso...... non buono !
90
10
T(n) ???
35Albero di ricorsione
n
n
n
1/10 n
9/10 n
n
1/100 n
9/100 n
9/100 n
81/100 n
log10n
81/1000 n
729/1000 n
lt n
log10/9n
?(n log(n))
36Analisi del caso medio di QSuna intuizione.
- Caso medio a volte facciamo una buona partition
a volte no... - buona partition
- cattiva partition
37Caso medio
- le buone e le cattive partition si alternano...
cattiva
1
n-1
buona
1
(n-1)/2
(n-1)/2
dopo una cattiva e una buona partizione in
successione siamo più o meno nella situazione in
cui la cattiva partizione non è stata fatta !
38QS distribuzione degli input
- Abbiamo assunto implicitamente che tutte le
sequenze di numeri da ordinare fossero
equiprobabili. - Se ciò non fosse vero potremmo avere costi
computazionali più alti. - Possiamo rendere gli input equiprobabili ?
mischiamo la sequenzacasualmente prima di
ordinare
come procediamo
Scegliamo il pivot a caso.
39QS randomizzato
- QSR una una versione randomizzata della procedura
Partition.
Randomized-partition(A,p,r) irandom(p,r) exchan
ge(Ap,Ai) return partition(A,p,r)
Un algoritmo randomizzato non ha un input
pessimo, bensì ha una sequenza di scelte pessime
di pivot.
40Insertionsort Mergesort Heapsort Quicksort
Caso pessimo n2 n log(n) n log(n) n2
Caso medio n2 n log(n) n log(n) n log(n)
Casoottimo n n log(n) n log(n) n log(n)
41È possibile ordinare in meno di n log(n)
???ovvero in o(n log(n))
42Limite inferiore di complessità
Insertion-sortMerge-sortHeap-sortQuick-sort
Comparison-sortalgoritmi basati su confronti
Questi metodi calcolano una soluzione che
dipende esclusivamentedallesito di confronti
fra numeri
TEOREMA (Lower Bound per algoritmi
Comparison-sort) Qualsiasi algoritmo
comparison-sort deve effettuare nel caso
pessimo ?(n log(n)) confronti per ordinare una
sequenza di n numeri.
43lower bound per comparison sort
- IDEA con n numeri ho n! possibili ordinamenti.
Possiamo scegliere quello giusto tramite una
sequenza di confronti.
gt
gt
gt
Ogni nodo rappresenta un confronto.
44Esempio n3 a1,a2,a3
albero dei confronti
a1a2
gt
a2a3
a1a3
gt
gt
a1,a2,a3
a1a3
a2,a1,a3
a2a3
gt
gt
a1,a3,a2
a3,a1,a2
a2,a3,a1
a3,a2,a1
Ogni nodo bianco rappresenta un confronto. Ogni
nodo rosso rappresenta una possibile soluzione.
45- 3! 6 numero di foglie dellalbero dei
confronti. - ogni (cammino dalla radice ad una) foglia
rappresenta un ordinamento - ci sono n! ordinamenti.
- quanto deve essere alto un albero binario per
avere - n! foglie ???
- un albero binario alto h ha al massimo 2h foglie
- dobbiamo avere 2h n!
- Formula di Stirling n! gt (n/e)n e2.17...
- h log(n/e)n nlog(n) - nlog(e) ?(nlog(n))
46Il caso pessimo di un qualsiasi algoritmo
comparison-sort eseguito su una sequenza di n
numeri è dato dallaltezza dellalbero di
decisione associato a quellalgoritmo.
MA
Un albero binario con n! foglie (ordinamenti) ha
un altezza ?(nlog(n))
QUINDI
qualsiasi algoritmo comparison-sort, nel caso
pessimo, esegue ?(nlog(n)) confronti.
47Counting sort come ordinare in tempo lineare
(!?!?)
Ipotesi di lavoroI numeri da ordinare
appartengono allintervallo 1,k
Risultato counting sort ha un costo
computazionale O(n k)
Se kO(n) allora counting sort ha un costo
computazionale O(n) e quindi batte tutti i
comparison sort
48Counting sort un esempio
A 3,6,4,1,3,4,1,4
C32 perché il numero 3 è contenuto 2 volte in
A
C 2,0,2,3,0,1
C47 perché ci sono 7 numeri minori o uguali
a 4
C 2,2,4,7,7,8.
49Algoritmi di ordinamento stabili
4
A
B
7
C
2
D
3
E
2
F
7
50Algoritmi di ordinamento NON stabili
4
A
B
7
C
2
D
3
E
2
F
7
51Algoritmi di ordinamento stabili
Un algoritmo di ordinamento è stabile se Se
Ai Aj e i lt j allora Ai compare
nellordinamento prima di Aj
ESERCIZIO dimostrare che counting sort è stabile.
52Counting-sort(A,B,k) 1. for i1 to k do
Ci0 2. for j1 to length(A) do
CAjCAj1 3. for i2 to k do
CiCiCi-1 4. for jlength(A) downto 1
do 5. BCAjAj 6. CAjCAj-1
- costa ?(k)
- costa ?(n)
- costa ?(k)
- costa ?(n)
Quindi Counting sort ?(n k)
53Radix sort
310638237272182926
310272 182 926 237638
310926237638 272182
182237272310638926
vettore ordinato
54Radix sort
Radix-sort(A,d) for i1 to d do usa un stable
sort per ordinare A sulla cifra iesima
Ogni cifra è compresa tra 1 e k. Usiamo counting
sort (stabile). Costo computazionale d?(nk)
?(nddk). Counting sort non lavora in place !
55Bucket sort
- Ipotesi i numeri da ordinare sono uniformemente
distribuiti nellintervallo 0,1), ovvero - Ci si aspetta che nellintervallo x,x?)
- ci siano tanti numeri quanti in y,y?)
- per qualunque x,y,?
5678
--
0
12
17
--
17
1
39
21
23
26
--
2
26
39
--
3
62
--
4
68
--
5
62
68
--
21
6
12
78
--
7
23
--
8
57Bucket-sort(A) nlength(A) for i1 to n do
inserisci Ai nella lista B?nAi? for i0 to
n-1 do ordina la lista Bi usando
insertion-sort Concatena le liste
B0,...,Bn-1
NOTA ?nAi? restituisce il bucket dove
inserire Ai
58Variabile Aleatoria Discreta variabile che può
assumere un numero finito di valori con una certa
distribuzione di probabilità. Esempio 1 X
(Testa, Croce) Pr(XTesta) Pr(XCroce) 1/2
Esempio 2 Y (1,2,3,4) Pr(Y1) Pr(Y2)
1/3, Pr(Y3) Pr(Y3) 1/6.
59Media di una VAD
Probabilità
EY 11/3 21/3 31/6 41/6 13/6
Valori possibili di Y
60Vogliamo calcolare il costo computazionale medio
di Bucket Sort. Bucket Sort usa Insertion Sort
sulle singole liste. Assumendo che la lunghezza
media di ogni lista sia ni , il costo della
singola applicazione di Insertion Sort è (ni
)2 (nel caso pessimo !!!) Dobbiamo quindi
valutare E(ni )2. NOTA EX2 diversa da EX2
61ni variabile aleatoria numero di elementi
nel bucket i Pr(x ---gt Bi) 1/n Distribuzione
binomiale Pr(ni k) ( ) (1/n)k
(1-1/n)n-k Eni n 1/n 1 Eni2 Varni
E2ni 2 - 1/n ?(1) Eni2 costo
computazionale di insertion sort Costo
computazionale di bucket sort O(n)
n k
62Selezione esempio
12 3 8 1 7 6 100 91
Input
Inputordinato
1 3 6 7 8 12 91 100
massimo
minimo
quarto elementonellordinamento
63Selezione
Selezione Calcolare liesimo elemento
nellordinamento.
- Ordinamento ?(nlog(n))
- minimo/massimo ?(n)
- Selezione ????
64Selezione
- Input un insieme A di n numeri distinti e un
numero i tra 1 e n - Output lelemento x in A maggiore di esattamente
i-1 altri numeri in A
Soluzione banale ordino gli elementi di A e
prendo liesimo elemento nellordinamento. ?(nlog(
n)) (analisi del caso pessimo)
65A1,...,n
L
R
n
1
q
Supponiamo cheAi Aj per ogni 1 i q e
ogni q lt j n
Domanda il k-esimo elemento nellordinamento
sta in L o in R ?
Risposta Facile. Se k q ---gt L. Altrimenti R.
66Selezione in tempo medio lineare
- Rand-select(A,p,r,i)
- if pr then return Ap
- qrand-partition(A,p,r)
- kq-p1
- if ik
- then return Rand-select(A,p,q,i)
- else return Rand-select(A,q1,r,i-k)
caso pessimo ?(n2) caso medio ?(n) (senza
dimostrazione)
67Selezione in tempo linearenel caso pessimo
IDEA dobbiamo progettare un buon algoritmo di
partition ?n (1- ?)n
Nota basta che ? sia maggiore di zero e
indipendente da n !!!
68- Select(i)
- Dividi i numeri in input in gruppi da 5 elementi
ciascuno. - Ordina ogni gruppo (qualsiasi metodo va bene).
Trova il mediano in ciascun gruppo. - Usa Select ricorsivamente per trovare il mediano
dei mediani. Lo chiamiamo x. - Partiziona il vettore in ingresso usando x
ottenendo due vettori A e B di lunghezza k e
n-k. - Se ik allora Select(i) sul vettore A
altrimenti Select(i-k) sul vettore B.
69?n/5?
M
5
Mediano della terza colonna
Calcoliamo il mediano di M usando Select
ricorsivamente !!!
70Supponiamo di aver riordinato le colonne a
seconda del valore del loro mediano.
Minori o uguali di
Maggiori o ugualidi
mediano dei mediani.
71più o meno 3 n/10
più o meno 3 n/10
Se partizioniamo intorno a lasciamo almeno
(circa) 3n/10 elementi da una parte e almeno
(circa) 3n/10 elementi dallaltra !!! OK
72Select costo computazionale
Costo per ordinare le colonne
?(1) se n lt c
Costo per calcolare il mediano dei mediani
T(n)
?(n) T(n/5) T(7n/10 )
se n c
Costo per la chiamata ricorsiva di select
T(n) k n, k costante opportuna Dim Esercizio
73Strutture Dati Elementari Pile e Code
74Pile (Stacks)
- Dati un insieme S di elementi.
- Operazioni PUSH, POP
- PUSH inserisce un elemento in S
- POP restituisce lultimo elemento inserito e lo
rimuove da S - Politica Last-In-First-Out (LIFO)
75Pila
PUSH
76Pila
POP
77Code (Queues)
- Dati un insieme S di elementi.
- Operazioni ENQUEUE, DEQUEUE
- ENQUEUE inserisce un elemento in S
- DEQUEUE restituisce lelemento da più tempo
presente (il più vecchio) e lo rimuove da S - Politica First-In-First-Out (FIFO)
78Coda
ENQUEUE
79Coda
DEQUEUE
80Implementazione di Pile con Vettori
- STACK-EMPTY(S)
- If topS 0 then return TRUE else return
FALSE
PUSH(S,x) topS topS 1 StopS x
POP(S) if STACK-EMPTY(S) then error else
topS topS - 1 return StopS 1
81Implementazione di code con Vettori
ENQUEUE(Q,x) QtailQ x if tailQ
lengthQ then tailQ 1 else tailQ
tailQ 1
DEQUEUE(Q,x) x QheadQ if headQ
lengthQ then headQ 1 else headQ
headQ 1
82Problemi con i vettori
- Vettori
- Semplici,
- Veloci
- ma
- Bisogna specificare la lunghezza staticamente
- Legge di Murphy
- Se usi un vettore di lunghezza n doppio di ciò
che ti serve, domani avrai bisogno di un vettore
lungo n1 - Esiste una struttura dati più flessibile?
83Linked Lists
Dato 1
next
Dato 2
next
Dato 3
---
HeadL
Elemento della lista Dato puntatore all
elemento successivo nella lista
84Doubly Linked Lists
Dato 1
----
next
Elemento della lista Dato puntatore al
predecessore puntatore al successore
HeadL
Dato 2
prev
next
Dato 3
prev
----
85Ricerca e Inserimento
- LIST-SEARCH(L,k)
- x headLwhile x lt gt nil and keyx lt gt k do
x nextxreturn x
LIST-INSERT(L,x) nextx headLif headL lt
gt nil then prevheadL xheadL xprevx
nil
86Cancellazione
- LIST-DELETE(L,k)
- x LIST-SEARCHL,kif prevx lt gt nil then
nextprevx nextx else headL
nextxif nextx lt gt nil then prevnextx
prevx
87Costi Computazionali
Inserimento LIST-INSERT Q?1)
Cancellazione LIST-DELETE Q?1)
Ricerca LIST-SEARCH Q?n)
88Sentinelle
Lista vuota usando le sentinelle
---
prev
next
nilL
89Sentinelle
sentinella
x
last
first
nilL
Dato 1
prev
next
Dato 2
prev
next
Dato 3
prev
next
Dato 4
prev
next
90Cancellazione usando le sentinelle
- LIST-DELETE(L,k)
- x LIST-SEARCHL,kif prevx lt gt nil then
nextprevx nextx else headL
nextxif nextx lt gt nil then prevnextx
prevx
LIST-DELETE-SENTINEL(L,k) x LIST-SEARCHL,k n
extprevx nextx prevnextx prevx
91- Esercizio usare le sentinelle per SEARCH e
INSERT
92Alberi binari rappresentatiusando liste
Padre
Figlio sinistro
Filgio destro
93Alberi generali rappresentatiusando liste
Padre
Primo figlio
Primo fratello
---
Lista dei fratelli
94Costo computazionale delle operazioni sulle liste
Singly linkednon ordinata Singly linkedordinata Doubly linkednon ordinata Doubly linkedordinata
Ricerca
Inserimento
Cancellazione
Successore
Predecessore
Massimo
95Tabelle Hash
96Ogni elemento ha una chiave Ki tale che 0 lt Ki lt
n1
1
Insieme S
Elemento 1
Vettore V
Elemento 2
Elemento i
Elemento 12
Elemento 41
S
97Tabella con indirizzamento diretto
Posizione nel vettore valore della chiave
i
i
Elemento i-esimo
j
j
Elemento j-esimo
98Tabella con indirizzamento diretto
Search(V,k) return Vk
Costo computazionale ?(1)
Insert(V,x) Vkeyx x
Delete(V,x) Vkeyx nil
99Problemi
- Supponiamo che solo una parte S dello spazio S
delle chiavi sia utilizzata/attiva. - Cosa succede quando S ltlt S ?
- Si spreca spazio di memoria !!!
- Soluzioni?
100Problemi
S
S
Spazio sprecato
101Una soluzione
- Possiamo ridurre loccupazione di spazio da
?(S) a ?(S) - Usando LINKED LISTS !!!
- PROBLEMA (non finiscono mai) Inserimento,
Cancellazione e Ricercacostano ?(S) invece di
?(1).
102Vero Problema compromesso tra TEMPO e SPAZIO
- Usando Hash tables possiamo raggiungere
- Tempo di accesso ?(1)
- Spazio di memoria ?(S)
- Ma in media e non nel caso pessimo !
103IDEA
h funzione hash
i
h(i)
104Funzione hash
- h restituisce un numero intero da 1 a M.
- Usiamo una tabella con M posizioni
- x viene memorizzato in posizione h(keyx)
105Proprietà per una buona h
- Deterministica ma deve sembrare random in modo
da minimizzare le collisioni. - x e y generano una collisione se
- x ? y e h(x) h(y)
- h deve minimizzare il numero di collisioni
106Risoluzione di collisioni con chaining
h(ki)h(kj)
ki
ki
kj
--
kj
107Chained-hash-insert(T,x) Inserisci x in testa
alla lista Th(keyx)
Chained-hash-search(T,k) Ricerca lelemento con
chiave k nella lista Th(k)
Chained-hash-delete(T,x) cancella x dalla
lista Th(keyx)
108Chaining analisi
Load factor ?n/m, n numero di elementi
memorizzati in Tm dimensione di T
Caso pessimo tutte le n chiavi finiscono nella
stessa posizione. Ricerca ?(n)
Caso medio Simple uniform hashing Pr(h(k)i)
Pr(h(k)j)
109Simple uniform hashing un esempio
U
1 (1/2)
1
m2
2 (1/8)
h
2
3 (1/8)
4 (1/16)
NON UNIFORME !!! PERCHE ???
5 (1/16)
6 (1/8)
in rosso è indicata la probabilità che una certa
chiave debba essere inserita nella tabella
110Simple uniform hashing un esempio
U
1 (1/2)
1
m2
2 (1/8)
h
2
3 (1/8)
4 (1/16)
UNIFORME !!! PERCHE ???
5 (1/16)
6 (1/8)
in rosso è indicata la probabilità che una certa
chiave debba essere inserita nella tabella
111Simple uniform hashing
- Una funzione hash si dice uniforme quando rende
uniforme il riempimento della tabella. - Non quando la distribuzione delle chiavi è
uniforme !!!
112Teorema Ipotesi collisioni gestite con
chaining simple uniform hashing caso
medio Tesi una ricerca ha costo computazionale
?(1?)
113- Dimostrazione
- Caso di ricerca senza successo.
- Load factor ? è la lunghezza media di una catena.
- In una ricerca senza successo il numero di
elementi esaminati è uguale alla lunghezza media
delle catene. - Calcolare h() costa 1.
114- Dimostrazione
- Caso di ricerca con successo.
- Assumiamo di inserire elementi in testa alla
catena. - Simple uniform hashing numero medio di
elementi in una catena dopo i inserimenti i/m - lelemento j ci si aspetta che venga inserito
nella posizione 1 (j-1)/m allinterno di una
catena.
115- Un elemento generico finirà in media nella
posizione data dalla formula - 1/n ? (1 (i-1)/m) 1/n (n n(n1)/2m -
n/m) - 1 ?/2 - 1/(2m)
- ?(1?)
n
i1
116Supponiamo che nO(m). Ovvero che il numero di
elementi inseriti nella tabella sia
proporzionale alla dimensione della tabella.
Abbiamo
? n/m O(m)/m O(1)
In questo caso la ricerca impiega tempo costante
!!!
Cosa succede se gli elementi vengono inseriti
allinizio delle liste ?
117Riepiloghiamo...
- Se usiamo doubly linked lists per le catene e se
inseriamo i nuovi elementi in testa alle liste
abbiamo
Ricerca Cancellazione Inserimento
O(1) operazioni in media
118Funzioni hash progettazione
Pr(k) probabilità della chiave k
Sj k ? U tali che h(k)j
Vogliamo uniform hashing ovvero ? Pr(k) 1/m
(mdimensione della tabella)
k?Sj
119Esempio
- U x? R 0xlt1
- x preso a caso da U.
- Definiamo h(x)?xm?
- Dimostrare per esercizio che h() è una buona hash
function. - (suggerimento definire Sj esplicitamente)
120Se Pr() è sconosciuta
Usiamo euristiche
- IDEA
- h deve dipendere da tutti i bit di k
- deve essere indipendente da eventuali pattern
che possono essere presenti nelle chiavi
121Supponiamo per semplicità che le chiavi siano
numeri naturali.
Metodo della divisione
h(k) k mod m
Esempio m12, k100, h(100) 100 mod 12 4
Per controllare se uno ha scelto un buon m è
consigliabile usare un benchmark reale.
122Metodo della moltiplicazione
h(k) ?m(kA mod m)?
Esempio A (51/2-1)/2 0.618..., k
123456, m 10000 h(123456) conti conti conti
41
123Risoluzione collisioni open addressing
?
1
?
2
h(?,0) 1
h(?,0) 1
h(?,1) 2
h(?,0) 2
h(?,1) 4
h(?,0) 2
h(?,1) 4
h(?,2) 5
3
?
4
?
5
124Open addressing
- Nessun puntatore spazio risparmiato!
- 1 sempre. Nessuna lista per gestire le
collisioni - Hash function più complessa. lth(k,0), h(k,1),
... , h(k,m-1)gt deve essere una permutazione di
lt1, ... , mgt
125- h(k,i) posizione della tabella in cui inserire
la chiave k quando tutte le posizioni h(k,0), ...
, h(k,i-1) sono già occupate.
126Open addressing uniform hashing
- Se gestiamo le collisioni con il metodo open
addressing, la funzione hash restituisce una
permutazione degli indici lt1, ... ,mgt. - Invece di simple uniform hashing parliamo di
uniform hashing. - Uniform hashing tutte le permutazioni devono
apparire con la stessa probabilità
127Open addressing inserimento
- Hash-insert(T,k)
- i0
- repeat jh(k,i)
- if Tjnil
- then Tjk
- return j
- else ii1
- until im
- error hash table overflow
128Open addressing ricerca
- Hash-search(T,k)
- i0
- repeat jh(k,i)
- if Tjk
- then return j
- else ii1
- until (Tjnil) or (im)
- return nil
129Open addressing cancellazione
- Hash-delete(T,k)
- iHash-search(T,k)
- if i?nil then Tinil
-
NON FUNZIONA
130h(6,0)0 h(6,1)1 h(6,2)2 h(6,3)3
0
3
Inseriamo 6
1
7
2
8
3
0
3
Cancelliamo 8
1
7
2
8
3
6
0
3
Risposta 6 non cè
1
7
ricerchiamo 6
2
3
6
131Esercizio Modificare Hash-search e
Hash-delete per risolvere il problema illustrato
nel lucido precedente.
Suggerimento usare un carattere con il
quale contrassegnare gli elementi cancellati.
0
3
1
7
2
D
3
6
132Open addressing linear probing
- Sia h una funzione hash ordinaria.
- Definiamo h(k,i)(h(k) i) mod m
133Linear probing primary clustering
Tempo medio di accesso per una ricerca senza
successo 1.5 Perche?
Tempo medio di accesso per una ricerca senza
successo 2.5 Perche?
Clustering primario
134Usando linear probing il clustering primario si
forma con alta probabilità.
Pr (i1)/m
i1 slot pieni
i slot pieni
Pr 1/m
i slot vuoti
135Quadratic probing
- h(k,i) (h(k) c1i c2i2) mod m
- con c2?0
Cosa si può dire sul clustering primario ?
136Double hashing
- h(k,i) (h1(k) ih2(k)) mod m
Cosa succede se MCD(m,h2(k)) d gt 1 ???
Quante permutazioni distinte produce il double
hashing ???
137Open addressing ricerca
- Teorema
- Data una hash table con open addressing e load
factor - ? n/m lt 1
- la lunghezza media di una probe in una ricerca
senza successo è 1/(1- ?). - (Ipotesi uniform hashing)
1381/(1- ?) m
? (m-1)/m (valore massimo di ?)
1/(1- ?) m/(m-1)
? 1/m(valore minimo di ?)
1/(1- ?) 2
? 1/2
139Dimostrazione IDEA cosa succede quando
facciamo una ricerca senza successo ???
X lunghezza probe quante volte devo
calcolare h(k,i) prima di trovare uno slot vuoto
elemento non trovato
Dobbiamo valutare EX media di X
Empty
140Lemma
0 --gt p0
1 --gt p1
X variabile aleatoria discreta
X
..........
8
i --gt pi
EX
?
ipi
..........
i0
8
?
iPr(Xi)
ESERCIZIO !!!
i0
8
8
i(Pr(Xi) - Pr(Xi1))
?
?
Pr(X i)
i0
i1
1418
EX
?
Pr(Xi)
i1
8
?
(n/m)i
i1
8
?
?i
i1
142Open addressing inserimento
- Teorema
- Data una hash table con open addressing e load
factor ? n/m lt 1, la lunghezza media di una
probe è 1/(1- ?). - (Ipotesi uniform hashing)
143- Dimostrazione
- Nota ? deve essere lt 1.
- Per inserire un elemento abbiamo bisogno di
determinare la posizione nella tabella dove
inserirlo. - Ricerca costo 1/(1-?).
- Per inserire nella tabella nella posizione appena
determinata ?(1).
144Alberi Binari di Ricerca
145Alberi di ricerca binari
gt
8
18
5
6
15
17
9
16
146Alberi di ricerca binari
8
18
5
gt
6
15
17
9
16
147BST definizione formale
- Sia x un nodo dellalbero
- Se y è un nodo nel sottoalbero sinistro di x
allora keyykeyx - Se y è un nodo nel sottoalbero destro di x allora
keyygtkeyx - Nota che un BST può essere molto sbilanciato !!!
bilanciato
sbilanciato
148Inorder-tree-walk(x) if x ? nil then
Inorder-tree-walk(leftx) print keyx
Inorder-tree-walk(rightx)
8
8
18
5
5
18
7
15
7
15
ORDINAMENTO
17
9
6
6
9
17
16
16
149Ricerca
ricerchiamo il 16
8
18
5
7
15
17
9
6
16
?(h) confronti haltezza albero
150Ricerca
- Tree-search(x,k)
- if xnil or kkeyx
- then return x
- if kltkeyx
- then return Tree-search(leftx,k)
- else return Tree-search(rightx,k)
Esercizio dimostrare che il costo
computazionale di Tree-search è ?(h)
151Successore
15
18
6
7
3
20
17
4
2
13
x ha il figlio destro. successore(x)minimo nel
sottoalbero di destra Dimostrazione Esercizio.
9
152Successore
15
18
6
7
3
20
17
4
2
13
x non ha il figlio destro. successore(x) il più
basso avo di xil cui figlio sinistro è avo di
x Dimostrazione Esercizio.
9
153Operazioni su BST
- Ricerca
- Minimo
- Massimo
- Predecessore
- Successore
?(h) confronti
154Inserimento
5
99
15
18
6
7
3
20
17
99
4
2
13
9
5
155Cancellazione
- 3 casi
- x non ha figli elimina x
- x ha un figlio
- x ha 2 figli
- Lemma il successore di x sta nel sotto albero
destro e ha al massimo 1 figlio. - Dimostrazione esercizio.
156eliminiamo
15
18
6
7
3
20
17
4
2
13
9
successore di 15
15717
18
6
7
3
20
4
2
13
9
17 ha preso il posto di 15
158- Cancellazione di un nodo x con 2 figli
- 1. sia y successore di x.
- y ha un solo figlio (al massimo)
- 2. sostituisci x con y.
- 3. rimuovi y.
159Problema
- Tutte le operazioni su BST hanno un costo lineare
nellaltezza dellalbero. - Purtroppo, quando lalbero è sbilanciato,
- h n-1
- Le operazioni hanno un costo lineare invece che
logaritmico come speravamo !!! Soluzione ???
160Soluzione
- Introduciamo alcune proprietà addizionali sui BST
per mantenerli bilanciati. - Paghiamo in termini di una maggiore complessità
delle operazioni dinamiche sullalbero. - Tali operazioni devono infatti preservare le
proprietà introdotte per mantenere il
bilanciamento.
161Red-Black Trees
162Red Black Trees BST alcune proprietà
aggiuntive
26
17
41
14
21
30
47
28
38
23
19
16
10
35
39
20
12
15
7
3
163Proprietà Aogni nodo è rosso o nero
26
17
41
14
21
30
47
28
38
23
19
16
10
35
39
20
12
15
7
3
164Proprietà Bogni foglia è nera (ne aggiungiamo
un livello fittiziamente)
26
17
41
14
21
30
47
28
38
23
19
16
10
35
39
20
12
15
7
3
165Proprietà C un nodo rosso ha figli neri
26
17
41
14
21
30
47
28
38
23
19
16
10
35
39
20
12
15
7
3
166Proprietà Dtutti i cammini da un nodo x alle
foglie ha lo stesso numero di nodi neri
26
17
41
14
21
30
47
28
38
23
19
16
10
35
39
20
12
15
7
3
4 nodi neri
4 nodi neri
167Idea di base
- Proprietà D se un RB tree non ha nodi rossi è
completo. - Possiamo immaginarci un RB tree come un albero
nero completo a cui abbiamo aggiunto non troppi
nodi rossi (Proprietà C). - Ciò rende lalbero quasi bilanciato
168Black-height di un RB tree
- bh(x) numero di nodi neri (senza contare x) nel
cammino da x a una foglia) - bh(root) black-height dellalbero
169bh(x)
3
26
3
17
41
2
2
14
21
30
47
28
38
23
19
16
10
35
39
20
12
15
7
3
170Teorema Un RBT con n nodi interni è alto al
massimo 2log2(n1)
Lemma Il numero di nodi interni di un sotto
albero radicato in x è maggiore o uguale a
2bh(x)-1
171Dimostrazione del lemma. Per induzione
sullaltezza di x. CASO BASE h(x)0. Se h(x)0
allora bh(x)0 inoltre x è una foglia quindi
il numero di nodi interni è 0. INDUZIONE
h(x)gt0. x ha 2 figli L e R. Abbiamo 2 casi L
è rosso bh(L) bh(x) L è nero bh(L)
bh(x) - 1 R viene trattato in modo analogo
172Visto che h(L) lt h(x) e h(R) lt h(x) applichiamo
lipotesi induttiva. Numero di nodi interni
dellalbero radicato in Lmaggioreo o uguale a
2bh(L) - 1. Stesso discorso per R. Inoltre
2bh(L)-1 ? 2bh(x)-1 - 1 e 2bh(R) - 1 ? 2bh(x)-1
- 1 Quindi numero di nodi interni dellalbero
radicato in x maggiore o uguale a 2bh(x)-1 - 1
2bh(x)-1 - 1 1 che è uguale a 2bh(x) - 1.
173Dimostrazione del teorema. Sia h laltezza
dellalbero. Qualsiasi cammino dalla radice --gt
foglia contiene almeno metà nodi neri. Il cammino
radice --gt foglia che determina
laltezzadellalbero contiene almeno h/2 nodi
neri. bh(T) bh(root) ? h/2 Lemma --gt n ?
2bh(root) - 1 quindi n ? 2bh(root) - 1 ? 2h/2
- 1. concludiamo log2(n1) ? log2(2h/2 ) h/2.
174RotazioniOperazioni di ristrutturazione locale
dellalbero che mantengono soddisfatte le
proprietà A,B,C,D
esercizio scrivere il pseudo codice per le
rotazioni
Y
X
X
A
Y
B
destra
C
B
A
C
sinistra
175Inserimento
- Idea
- inseriamo x ---gt T
- colorxred
- qualche rotazione ricolorazione
41
30
47
28
38
35
39
nodo inserito ---gt
32
---gt !!!!!! il figlio di un nodo rosso deve
essere nero
17611
2
14
15
1
7
5
8
4
p
17711
rotazione sinistra ---gt
2
14
15
1
7
p
5
8
4
178rotazione destra ---gt
11
14
7
15
2
8
p
1
5
4
1797
2
11
14
8
1
5
15
4
FINE...
180metodo generale zio(x) è rosso
p
C
rosso
C
A
D
p
A
D
up
x
B
w
s
x
B
w
s
y
z
y
z
181metodo generale zio(x) è rosso
p
C
rosso
C
p
B
D
B
D
up
A
z
w
s
A
z
w
s
x
y
x
y
182metodo generale zio(x) è nero
p
C
nero
C
p
A
D
B
D
left(A)
x
B
A
z
y
z
x
y
183... e poi ...
C
B
B
right(C)
p
D
A
C
A
z
x
y
z
D
x
y
184Ci sono un certo numero di casi analoghi
riconducibili a quelli esaminati esercizio.
185Cancellazione di un nodo da un RB-tree
- Come nel caso dei BST, possiamo sempre assumere
- di eliminare un nodo che ha al massimo un figlio.
- Infatti se dobbiamo cancellare un nodo x con due
figli, spostiamo la chiave del successore y di x
in x e poi rimuoviamo y dallalbero. - Il successore di un nodo con due figli ha sempre
al massimo un figlio.
186Cancellazione di un nodo con 1 figlio
- Sia x il nodo da cancellare. Sia y il figlio
di x e sia z il padre di x. - 1. rimuoviamo x collegando z con y. 2. se x
era rosso allora y e z sono neri e
non dobbiamo fare altro. 3. se x era nero e y
è rosso allora coloriamo y di nero. - Se x era nero e y è nero allora ricoloriamo
y con un colore nero doppio. Dopodichè
svolgiamo alcune altre operazione descritte
nel seguito.
187Esempio
z
z
z
x
x
y
y
y
ricolora
z
z
x
y
y
doppio nero che va poi ridistribuito su un nodo
rosso annerendolo.
188Cancellazione di un nodo con 1 figlio
- Idea cercare di far salire il doppio nero
nellalbero fino a trovare un nodo rosso sul
quale scaricare una parte del nero del nodo - doppio nero e riottenere una colorazione
legale. - Per far ciò operiamo operazioni di
ristrutturazioni locali - dellalbero e ricolorazioni che possono propagare
- il doppio nero due livelli più in alto
189Caso 1 fratello nero con almeno un figlio rosso
y
s
rotazione sinistra
y
t
x
s
x
t
y
t
x
s
y
s
rotazione derstra e poi sinistra
x
t
a
b
a
b
190Caso 2 fratello nero con figli neri
y
y
x
s
x
s
y
y
x
s
x
s
191Caso 3 fratello rosso
y
s
rotazione sinistra
x
s
y
b
x
a
b
a
192Programmazione Dinamica
193Programmazione Dinamica
- Divide et impera si suddivide il problema in
sotto problemi indipendenti, si calcola
ricorsivamente una soluzione per i sottoproblemi
e poi si fondono le soluzioni così trovate per
calcolare la soluzione globale per il problema
originale. - Programmazione dinamica simile allapproccio
divide et impera, ma in questo caso si tiene
traccia (in una tabella) delle soluzioni dei
sottoproblemi perchè può capitare di dover
risolvere il medesimo sottoproblema per più di
una volta.
194Prodotto di una sequenza di matrici
- Dobbiamo calcolare AA1A2 Am
- dove Ai sono matrici di opportune
- dimensioni (righe x colonne).
- In che ordine conviene effettuare le
moltiplicazioni ?
195Moltiplicazioni di matrici
- Matrix-multiply(A,B)
- if columns(A)? rows(B)
- then error
- else for i1 to rows(A)
- do for j1 to columns(B)
- do Ci,j0
- for k1 to columns(A)
- do Ci,jCi,jAi,kBk,j
- ?(rows(A) columns(B) columns(C))
- moltiplicazioni.
-
196Esempio
- AMNQ
- M 10 righe, 100 colonne
- N 100 righe, 5 colonne
- Q 5 righe, 50 colonne
Primo metodo A((MN)Q). Numero di
moltiplicazioni 101005 per calcolare AMN
101550 per calcolare AAQ Totale 7500
Secondo metodo A(M(NQ)). Numero di
moltiplicazioni 100550 per calcolare ANQ
1010050 per calcolare AMA Totale 75000
197Numero di possibili parentesizzazioni
- Il numero di possibili parentesizzazioni P(n) può
essere ottenuto come segue
n1
1
P(n)
n-1
? P(k)P(n-k)
ngt1
k1
numero di parentesizzazioni delle altre n-k
matrici
numero di parentesizzazioni delle prime k
matrici
198P(n) risulta essere ?(4n/n3/2) Quindi
esponenziale in n. Lalgoritmo di enumerazione
non può essere usato !!!
Osservazione chiave Supponiamo che la soluzione
ottima sia ottenuta 1. moltiplicando le prime k
matrici tra loro in qualche modo 2. moltiplicando
le altre n-k matrici tra loro in qualche modo 3.
moltiplicando le due matrici ottenute ai primi
due passi
Le parentesizzazioni dei passi 1 e 2 sono ottime
199Soluzione ricorsiva
- mi,j costo minimo per moltiplicare
le matrici Ai,...,Aj
ij
0
mi,j
iltj
min mi,k mk1,j pi-1pkpj
ikltj
200Costo della soluzione ricorsiva
- Esercizio
- Determinare il costo computazionale
dellalgoritmo ricorsivo progettato a partire
dallequazione ricorsiva del lucido precedente. - Esponenziale o polinomiale ???
201Numero di sottoproblemi
- Quanti sottoproblemi abbiamo?
- uno per ogni coppia di indici i,j nel range
1,...n ovvero ?(n2) (pochi !). - Quindi lalgoritmo ricorsivo deve risolvere più
volte lo stesso sottoproblema altrimenti non si
spiega il costo esponenziale !
202A1 30x35 A2 35x15 A3 15x5 A4 5x10 A5
10x20 A6 20x25
15125
11875
10500
m
7125
9375
5375
7875
4375
2500
3500
15750
2625
750
1000
5000
0
0
0
0
0
0
A1
A2
A3
A4
A5
A6
2033
s
3
3
3
3
3
1
3
3
5
2
1
3
4
5
si,j contiene lindice ottmo per spezzare la
moltiplicazione AiAj in due AiAsi,j
e Asi,j 1Aj
204Pseudo codice
Matrix-chain-order(p) nlength(p)-1 for i1 to
n do mi,i0 for l2 to n do for
i1 to n-l1 do jil-1
mi,j8 for ki to j-1
do qmi,kmk1,jpi-1pkpj
if qltmi,j
then mi,jq
si,jk return m,s
205Pseudo codice
Matrix-chain-multiply(A,s,i,j) if jgti then X
Matrix-chain-multiply(A,s,i,si,j)
Y Matrix-chain-multiply(A,s,si,j1,j)
return Matrix-multiply(X,Y) else
return Ai Parentesizzazione ottima dellesempio
((A1(A2A3))((A4A5)A6)) Costo
computazionale Matrix-chain-order tempo
?(n3) spazio ?(n2) Matrix-chain-multiply
tempo esercizio spazio esercizio
206Passi fondamentali della programmazione dinamica
- Caratterizzazione della struttura di una
soluzione ottima - Definizione ricorsiva del valore di una soluzione
ottima - Calcolo del valore di una soluzione ottima con
strategia bottom-up - Costruzione di una soluzione ottima a partire
dalle informazioni già calcolate.
207nellesempio della moltiplicazione di matrici.....
- Una parentesizzazione ottima associata a una
lista A1,A2,...,Am di matrici da moltiplicare può
essere sempre suddivisa in due parentesizzazioni
ottime associate alle liste A1,...,Ak e
Ak1,...,Am per un opportuno valore di k. - Una parentesizzazione ottima costa quanto la
somma dei costi delle due sotto parentesizzazioni
ottime più il costo dovuto alla moltiplicazione
delle matrici associate alle due sotto
parentesizzazioni - vedi come procedere con la matrice m nei lucidi
precedenti - vedi come procedere con la matrice s nei lucidi
precedenti
208Caratteristiche del problema perapplicare la
programmazione dinamica
- Sottostruttura ottima.
- Una soluzione ottima per il problema contiene al
suo interno le soluzioni ottime dei sottoproblemi - Sottoproblemi comuni.
- Un problema di ottimizzazione ha sottoproblemi
comuni quando un algoritmo ricorsivo richiede di
risolvere più di una volta lo stesso sottoproblema
209Versione ricorsiva con memorizzazione dei
risultati parziali in una tabella
- Mem-matrix-chain(p)
- nlength(p)-1
- for i1 to n
- do for j1 to n
- do mi,j8
- return Lookup-chain(p,1,n)
- Lookup-chain(p,i,j)
- if mi,jlt8 then return mi,j
- if ij then mi,j0
- else for k1 to j-1
- do qLookup-chain(p,i,k)
- Lookupchain(p,k1,j)
pi-1pkpj - if qltmi,j then mi,jq
- return mi,j
-
210Esercizi
- Determinare il costo computazionale di
- Mem-matrix-chain ???
- Lookup-chain ???
211Sottosequenza comune più lunga
X ABCDBDAB Y BDCABA
Z BCBA è LCS(X,Y)
- Problema di ottimizzazione.
- Possiamo applicare la programmazione dinamica ??
212Sotto struttura ottima
- Siano Xltx1,...,xmgt e Ylty1,...,yngt
- Sia Zltz1,...,zkgt una qualunque LCS di X e Y.
- Se xmyn, e zkxmyn allora Zk-1 è LCS di Xm-1 e
Yn-1 - Se xm?yn, e zk ? xm allora Zk-1 è LCS di Xm-1 e Y
- Se xm?yn, e zk ? yn allora Zk-1 è LCS di X e Yn-1
213 0 1 2 3 4 5 6
B D C A B A
0
0
0
0
0
0
0
0
A
1
0
0
0
0
1
1
1
B
2
0
1
1
1
1
2
2
C
3
0
1
1
2
2
2
2
B
4
0
1
1
2
2
3
3
D
5
0
1
2
2
2
3
3
A
6
0
1
2
2
3
3
4
B
7
0
1
2
2
3
4
4
214LCS-length(X,Y) mlength(X) nlength(Y) for
i1 to m do ci,00 for j1 to n do
c0,j0 for i1 to m do for j1 to n
do if xiyj then ci,jci-1,j-1
1 bi,j ? else if
ci-1,jci,j-1 then
ci,jci,j-1 bi,j ?
else ci,jci,j-1 bi,j
? return b,c
215Costruzione di una LCS
- Print-LCS(b,X,i,j)
- if i0 or j0 then return
- if bi,j ? then Print-LCS(b,X,i-1,j-1)
- print xi
- else if bi,j ?
- then Print-LCS(b,X,i-1,j)
- else Print-LCS(b,X,i,j-1)
216Algoritmi Greedy
217Selezione di attività
- S1,...,n insieme di attività. Ogni attività
ha un tempo di inizio si e un tempo di fine fi. - Problema Selezionare un sottoinsieme S di
attività in modo tale che - se i e j appartengono a S allora
- sifj oppure sjfi.
- La cardinalita di S è massimizzato.
21811
10
9
8
7
6
5
4
3
2
1
0 1 2 3 4 5
6 7 8 9