Uploaded by scooplala

Homeworks set 1 Mennillo - Trapani

advertisement
CORSO DI
ALGORITMI E STRUTTURE DATI
Homeworks set #1
Valerio Mennillo
Alessia Trapani
M63001277
M63001278
Esercizio 1.1 Notazione asintotica
ļ‚·
š’‡(š’) = š‘¶(š’‡(š’)šŸ )?
1
1
Cerchiamo un controesempio. Supponiamo š‘“ (š‘›) = š‘› e š‘“ (š‘›)2 = š‘›2.
š‘“(š‘›)
Se calcoliamo š‘“(š‘›)2 = š‘›, notiamo subito che š‘› è una funzione illimitata e quindi in questo caso š‘“(š‘›) ≠
š‘‚(š‘“(š‘›)2 ) (possiamo arrivare allo stesso risultato applicando la definizione: non riusciremo a trovare una
costante š‘ affinché la disuguaglianza sia valida per š‘› sufficientemente grande).
Considerando, però, š‘“ (š‘›) = š‘› e š‘“ (š‘›)2 = š‘›2 , riusciamo a trovare š‘ tale che 0 ≤ š‘› ≤ š‘š‘›2 per š‘›
sufficientemente grande. Infatti, per š‘ > 0 š‘› = š‘‚(š‘›2 ) ⇒ š‘“ (š‘›) = š‘‚(š‘“(š‘›)2 ).
Possiamo concludere dicendo che š‘“ (š‘›) = š‘‚(š‘“(š‘›)2 ) è a volte vera, dipende da š‘“(š‘›).
Nota: se avessimo considerato solo funzioni crescenti, la relazione sarebbe stata sempre vera.
ļ‚·
š’‡(š’) + š‘¶(š’‡(š’)) = šœ£(š’‡(š’))?
Consideriamo š‘“ (š‘›) + š‘”(š‘›) per š‘”(š‘›) = š‘‚(š‘“(š‘›)). Dato che abbiamo supposto š‘”(š‘›) = š‘‚(š‘“(š‘›)), allora
esiste una costante positiva š‘ tale che 0 ≤ š‘”(š‘›) ≤ š‘š‘“(š‘›) per š‘› sufficientemente grande.
Fatte queste assunzioni possiamo dire che
š‘“ (š‘›) ≤ š‘“(š‘›) + š‘”(š‘›) ≤ (š‘ + 1)š‘“(š‘›)
per š‘› sufficientemente grande.
Possiamo concludere dicendo che š‘“(š‘›) + š‘‚(š‘“(š‘›)) = š›©(š‘“(š‘›)) è sempre vera.
ļ‚·
š’‡(š’) = š›€(š’ˆ(š’)) š’† š’‡(š’) = š’(š’ˆ(š’))?
Se š‘“(š‘›) = Ω(š‘”(š‘›)), allora esiste una costante positiva š‘1 e š‘›1 tale che š‘“(š‘›) ≥ š‘1 š‘”(š‘›) per š‘› > š‘›1 .
Se š‘“(š‘›) = š‘œ(š‘”(š‘›)), allora per ogni costante positiva š‘ e š‘›š‘œ š‘“(š‘›) < š‘š‘”(š‘›) per š‘› > š‘›š‘œ .
Per far valere entrambe contemporaneamente dovremmo avere che per š‘› > š‘šš‘Žš‘„(š‘›1 , š‘›š‘œ )
š‘1 š‘”(š‘›) ≤ š‘“(š‘›) < š‘š‘”(š‘›)
Se š‘ = š‘1 (la relazione o-piccolo vale se è verificata per ogni š‘),
š‘1 š‘”(š‘›) ≤ š‘“ (š‘›) < š‘1 š‘”(š‘›)
Ciò è impossibile, quindi š‘“(š‘›) = Ω(š‘”(š‘›)) š‘’ š‘“(š‘›) = š‘œ(š‘”(š‘›)) non è mai vera.
Esercizio 1.2 Complessità
Dimostriamo che per qualsiasi š‘Ž e š‘, con š‘ > 0, (š‘› + š‘Ž)š‘ = š›©(š‘›š‘ ). Per fare ciò troviamo un limite superiore
e un limite inferiore.
ļ‚·
(š‘› + š‘Ž )š‘ = š‘‚(š‘›š‘ )
Troviamo š‘1 > 0 tale che (š‘› + š‘Ž)š‘ ≤ š‘1 (š‘›š‘ ) per š‘› sufficientemente grande.
(š‘› + š‘Ž)š‘ ≤ (š‘› + |š‘Ž|)š‘ ≤ (š‘› + š‘›)š‘ = (2š‘›)š‘
(š‘› + š‘Ž)š‘ = š‘‚(š‘›š‘ )
š‘š‘’š‘Ÿ š‘› ≥ |š‘Ž|
š‘š‘’š‘Ÿ š‘1 = 2š‘ š‘’ š‘› ≥ |š‘Ž |
ļ‚·
(š‘› + š‘Ž )š‘ = š›ŗ(š‘›š‘ )
Troviamo š‘2 > 0 tale che (š‘› + š‘Ž)š‘ ≥ š‘2 (š‘›š‘ ) per š‘› sufficientemente grande.
š‘› š‘
(š‘› + š‘Ž )š‘ ≥ (š‘› − |š‘Ž|)š‘ ≥ ( )
š‘š‘’š‘Ÿ š‘› ≥ 2|š‘Ž|
2
(š‘› + š‘Ž)š‘ = š›ŗ(š‘›š‘ )
Dato che š‘“(š‘›) = š›©(š‘”(š‘›))
⇔
š‘š‘’š‘Ÿ š‘2 = 2−š‘ š‘’ š‘› ≥ 2|š‘Ž|
š‘“ (š‘›) = š‘‚(š‘”(š‘›)) š‘’ š‘“(š‘›) = š›ŗ(š‘”(š‘›))
(š‘› + š‘Ž)š‘ = š›©(š‘›š‘ )
con š‘1 = 2š‘ , š‘2 = 2−š‘ e per š‘› ≥ 2|š‘Ž|
Esercizio 1.3 Complessità
ļ‚·
šŸš’+šŸ = š‘¶(šŸš’ )?
Affinché š‘“ (š‘›) = š‘‚(š‘”(š‘›)), deve esistere una costante positiva š‘ tale che 2š‘›+1 ≤ š‘2š‘› per š‘›
sufficientemente grande. Cerchiamo š‘.
2š‘›+1 ≤ š‘2š‘›
2 āˆ™ 2š‘› ≤ š‘2š‘›
La costante esiste, š‘ = 2, e quindi 2š‘›+1 = š‘‚(2š‘› ) è vero.
ļ‚·
šŸšŸš’ = š‘¶(šŸš’ )?
Affinché š‘“ (š‘›) = š‘‚(š‘”(š‘›)), deve esistere una costante positiva š‘ tale che 22š‘› ≤ š‘2š‘› per š‘›
sufficientemente grande. Cerchiamo š‘.
22š‘› ≤ š‘2š‘›
2š‘› āˆ™ 2š‘› ≤ š‘2š‘›
Non esiste una costante š‘ tale che š‘ ≥ 2š‘› e quindi 22š‘› = š‘‚(2š‘› ) non è vero.
Esercizio 1.4 Ricorrenze
ļ‚·
š’
Fornire il limite inferiore e superiore per š‘»(š’) = šŸš‘» ( šŸ‘) + š’ š’š’ˆ š’
Applichiamo il terzo caso del metodo dell’esperto.
š‘Ž=2
š‘=3
š‘“ (š‘›) = š‘› lg š‘›
š‘›š‘™š‘œš‘”š‘ š‘Ž = š‘›š‘™š‘œš‘”3 2
Verifichiamo le condizioni del teorema:
1. š‘“(š‘›) = š›ŗ(š‘›š‘™š‘œš‘”š‘ š‘Ž+šœ– ) per šœ– > 0
š‘› š‘™š‘” š‘› = š‘“ (š‘›) = š›ŗ(š‘›š‘™š‘œš‘”3 2+šœ– ) per šœ– ≈ 0.4
š‘›
2. š‘Žš‘“ (š‘ ) ≤ š‘š‘“(š‘›) per una data š‘ < 1 ed š‘› sufficientemente grande
š‘›
š‘›
2
2 ( 3 ) š‘™š‘” ( 3 ) ≤ 3 š‘› š‘™š‘” š‘›
2
per š‘ = 3 < 1
Entrambe le condizioni sono valide, quindi š‘‡ (š‘›) = š›©(š‘› š‘™š‘” š‘›)
ļ‚·
š’
Fornire il limite inferiore e superiore per š‘»(š’) = šŸ‘š‘» ( šŸ“) + š’š’ˆšŸ š’
Applichiamo il primo caso del metodo dell’esperto.
š‘Ž=3
š‘=5
š‘“(š‘›) = lg 2 š‘›
š‘›š‘™š‘œš‘”š‘ š‘Ž = š‘›š‘™š‘œš‘”5 3
Dobbiamo verificare che š‘“ (š‘›) = š‘‚(š‘›š‘™š‘œš‘”š‘ š‘Ž−šœ– ) per šœ– > 0
š‘™š‘”2 š‘› = š‘“ (š‘›) = š‘‚(š‘›š‘™š‘œš‘”3 2−šœ– ) per 0 < šœ– < š‘™š‘œš‘”5 3 = 0.682
La condizione è valida, quindi š‘‡(š‘›) = š›©(š‘›š‘™š‘œš‘”5 3 )
Esercizio 1.5 Ricorrenze
Dimostriamo tramite albero di ricorrenza che la soluzione della ricorrenza
š’
šŸ
š‘»(š’) = š‘» ( ) + +š‘» ( š’) + š’„š’
šŸ‘
šŸ‘
è Ω(n log n).
1
2
L’albero che ne viene fuori non è bilanciato perché vi è un percorso più veloce (a sinistra, (3 < 3),) relativo ai
sottoproblemi più piccoli. Sommando i termini di ogni livello, notiamo che il costo è š‘š‘› per tutti i livelli
completi. Quando abbiamo livelli incompleti, il costo sarà ≤ š‘š‘›.
Per definire il limite inferiore vado, dunque, a considerare il percorso più breve visto che terminerà prima,
1 š‘–
ovvero quello più a sinistra che ha una dimensione pari a ( ) š‘›. La dimensione sarà pari a 1 quando
3
1 š‘–
( ) š‘›=1
3
⇒
š‘– = š‘™š‘œš‘”3 š‘›
š‘‡(š‘›) sarà sicuramente maggiore del costo fino all’albero log 3 š‘› quindi
š‘™š‘œš‘”3 š‘›
š‘‡ (š‘›) ≥ ∑ š‘š‘› = š‘š‘›(š‘™š‘œš‘”3 š‘› + 1) ≥ š‘š‘› š‘™š‘œš‘”3 š‘› =
š‘–=0
š‘
š‘› š‘™š‘œš‘” š‘›
š‘™š‘œš‘” 3
⇒
š‘‡(š‘›) = š›ŗ(š‘› š‘™š‘œš‘” š‘›)
Homework 1.1. Inversioni
ļ‚·
Elencate le cinque inversioni dell’array (2, 3, 8, 6 ,1)
1. (1,5);
2. (2,5);
3. (3,4);
4. (3,5);
5. (4,5).
ļ‚·
Quale array con elementi estratti dall’insieme {šŸ, šŸ, … š’} ha più inversioni? Quante inversioni ha?
L’array con più inversioni è quello che presenta gli elementi in ordine decrescente:
[š‘› š‘› − 1 š‘› − 2 … 2 1]
Calcoliamo il numero di inversioni partendo dal primo elemento (š‘›) e andando avanti:
- š‘› avrà š‘› − 1 inversioni;
- š‘› − 1 avrà š‘› − 2 (š‘› − 1 − 1) inversioni;
- …
- 2 avrà 1 inversione;
- 1 avrà 0 inversioni.
Possiamo quindi scrivere una sommatoria per ottenere il numero massimo di inversioni:
š‘›
š‘›
š‘›
∑š‘– − 1 = ∑š‘– −∑1 =
š‘–=1
š‘–=1
š‘–=1
š‘›(š‘› + 1)
š‘›(š‘› − 1)
−š‘› =
2
2
ļ‚·
Qual è la relazione tra il tempo di esecuzione di Insertion Sort e il numero di inversioni nell’array di
input?
Il numero massimo di inversioni si verifica quando il vettore è in ordine decrescente che coincide anche
con il caso peggiore di Insertion Sort. Il tempo di esecuzione di Insertion Sort è strettamente legato al
numero di volte in cui viene eseguito il ciclo while e, se abbiamo un alto numero di inversioni,
andremmo ad eseguire tale ciclo un elevato numero di volte. Di conseguenza, più inversioni ci sono in
un array, più tempo impiegherà Insertion Sort ad ordinarlo.
ļ‚·
Create un algoritmo che determina il numero di inversioni in una permutazione di n elementi nel
tempo ššÆ(š’ š„šØš  š’) nel caso peggiore.
int Merge-Sort-Inversion(A,p,r)
invers āŸµ 0
if p<r
q āŸµ ⌊(p+r)/2⌋
invers āŸµ invers + Merge-Sort(A,p,q)
invers āŸµ invers + Merge-Sort(A,q+1,r)
invers āŸµ invers + Merge (A,p,q,r)
return invers
int Inversions-Counter(A,p,q,r)
n1 āŸµ q-p+1
n2 āŸµ r-q
//Create L[1 … n1+1] and R[1 … n2+1]
for i āŸµ 1 to n1
do L[i] āŸµ A[p+i-1]
for j āŸµ 1 to n2
do R[j] āŸµ A[q+j]
L[n1+1] āŸµ R[n2+1] āŸµ ∞
iāŸµjāŸµ1
invers āŸµ 0
for k āŸµ p to r
do if L[i]≤R[j]
then A[k] āŸµ L[i]
i āŸµ i+1
else
then A[k] āŸµ R[i]
invers āŸµ invers +n1-i+1
j āŸµ j+1
return invers
Partendo dal Merge-Sort, è stato costruito un algoritmo che identifica le inversioni in A. Il principio su
cui si basa è che il numero di inversioni viene incrementato solo se un elemento del sottoalbero di
destra viene scelto per essere depositato nell’array superiore.
Visto che i sottoarray sono già ordinati, possiamo incrementare il numero di inversioni di un numero
pari a tutti i restanti elementi del sottoarray di sinistra.
Homework 1.2 Unimodal
int Unimodal(A)
first āŸµ 0
last āŸµ lenght[A]-1
while first <= last
do midpoint āŸµ ⌊(first + last)/2⌋
if midpoint + 1 > last
then return midpoint
if midpoint - 1 > first
then return midpoint
if A[midpoint] > A[midpoint-1] and A[midpoint] > A[midpoint+1]
then return midpoint
if A[midpoint] > A[midpoint+1]
then last āŸµ midpoint-1
else first āŸµ midpoint+1
Il ragionamento alla base di questo algoritmo è molto simile a quello utilizzato per la ricerca binaria. Si
prende l’elemento posto al centro dell’array e si controlla la relazione di tale elemento rispetto al
precedente e al successivo. Si possono manifestare 3 casi:
ļ‚·
ļ‚·
ļ‚·
L’elemento centrale è maggiore di entrambi: l’elemento centrale è il massimo.
L’elemento centrale è maggiore del successivo ma non del precedente: la ricerca viene ripetuta sugli
elementi precedenti (da 0 a midpoint-1).
L’elemento centrale è minore del successivo: la ricerca viene ripetuta sugli elementi successivi (da
midpoint+1 a n).
Il tempo di esecuzione dipende da quante volte viene eseguita la condizione del while nel caso peggiore. Il
corpo del while viene eseguito fintanto che lo spazio di ricerca è non vuoto.
Inizialmente lo spazio di ricerca ha dimensione š‘›. Ad ogni esecuzione del while esso viene al più dimezzato,
quindi dopo š‘– iterazioni avrò uno spazio di ricerca pari a
š‘›
š‘›
2š‘–
. Considerando il caso peggiore, la dimensione
sarà pari a 1 quando 2š‘– = 1, ovvero š‘– = š‘™š‘” š‘›.
Nel caso peggiore, il corpo del while viene eseguito lg š‘› volte. Per tale motivo, l’algoritmo Unimodal ha una
complessità pari a š‘‚(š‘™š‘” š‘›).
Homework 1.3 Ricorrenze
ļ‚·
š’
Fornire il limite inferiore e superiore per š‘»(š’) = š‘» ( šŸ) + šŸš’
Applichiamo il terzo caso del metodo dell’esperto.
š‘Ž=1
š‘=2
š‘“ (š‘›) = 2š‘›
š‘›š‘™š‘œš‘”š‘ š‘Ž = š‘›š‘™š‘œš‘”2 1 = š‘›0 = 1
Verifichiamo le condizioni del teorema:
3. š‘“(š‘›) = š›ŗ(š‘›š‘™š‘œš‘”š‘ š‘Ž+šœ– ) per šœ– > 0
2š‘› = š‘“(š‘›) = š›ŗ(š‘›š‘™š‘œš‘”2 1+šœ– ) = š›ŗ (š‘›) per šœ– = 1
š‘›
4. š‘Žš‘“ (š‘ ) ≤ š‘š‘“(š‘›) per una data š‘ < 1 ed š‘› sufficientemente grande
2š‘›/2 ≤ š‘2š‘›
1
2š‘›/2 ≤ 2 2š‘› = 2š‘›−1
1
per š‘ = 2 < 1 e š‘› ≥ 2
Entrambe le condizioni sono valide, quindi š‘‡ (š‘›) = Θ(2š‘› )
Download