Sunteți pe pagina 1din 26

Proiectarea Algoritmilor

Programare dinamic
(2)

http://www.eed.usv.ro/~vatavu 1/26
Proiectarea Algoritmilor

Problem Subsecvena cresctoare de lungime


maxim
(LAS - Longest Ascending Subsequence)
(LIS - Longest Increasing Subsequence)
Fie un ir de numere ntregi, a0, a1, ... an-1.
S se determine subsecvena cresctoare
ai1 ai2 ... air de lungime maxim.

Intrare Ieire
=8 6
=7 1 5 2 8 2 4 1 8 7 10 1 2 2 4 7 10

http://www.eed.usv.ro/~vatavu 2/26
Proiectarea Algoritmilor

Soluie:
Pentru fiecare element [ ] vom calcula lungimea celei mai
lungi subsecvene cresctoare care poate fi format
ncepnd cu [ ] i vom reine aceast lungime ntr-un nou
vector , la poziia (memoizare).
Presupunnd deja calculate valorile [ ] pentru fiecare
j = i + 1, n 1 , construim cea mai lung subsecven
cresctoare din mulimea care ncepe cu elementul [ ],
adugnd aceste element celei mai lungi subsecvene
cresctoare care ncepe cu [ ] ( j = i + 1, n 1 ) cu condiia ca
[ ] [ ].

http://www.eed.usv.ro/~vatavu 3/26
Proiectarea Algoritmilor

1 i = n 1

lung[i] = 1 a[i ] > a[ j ] j = i + 1, n 1
lung[k ] + 1 k = arg max lung[ j ] / a[i] < a[ j ], j = i + 1, n 1
{ }
j

i 0 1 2 3 4 5 6 7 8 9 10
a 7 1 5 2 8 2 4 1 8 7 10
lu
i=10 1
ng
i=9 2 1
i=8 2 2 1
i=7 3 2 2 1
i=6 3 3 2 2 1
i=5 4 3 3 2 2 1
i=4 3 4 3 3 2 2 1
i=3 5 3 4 3 3 2 2 1
i=2 4 5 3 4 3 3 2 2 1
i=1 6 4 5 3 4 3 3 2 2 1
i=0 4 6 4 5 3 4 3 3 2 2 1

http://www.eed.usv.ro/~vatavu 4/26
Proiectarea Algoritmilor

procedura LAS(int[] a, int n)


lung[n-1] 1
pentru i n-2, 0 execut
Pseudo max 0
cod pentru j i+1, n-1 execut
dac a[i] <= a[j] atunci
dac max < lung[j] atunci
max lung[j]
lung[i] max + 1
poz DeterminaMax(lung, n)
ntoarce lung[poz]
sf.procedur

Complexitate temporal?
Complexitate spaial?

http://www.eed.usv.ro/~vatavu 5/26
Proiectarea Algoritmilor

Identificare subsecvenei de lungime maxim

a 7 1 5 2 8 2 4 1 8 7 10
lung 4 6 4 5 3 4 3 3 2 2 1
4 6 4 5 3 4 3 3 2 2 1
4 6 4 5 3 4 3 3 2 2 1
4 6 4 5 3 4 3 3 2 2 1
4 6 4 5 3 4 3 3 2 2 1
4 6 4 5 3 4 3 3 2 2 1

http://www.eed.usv.ro/~vatavu 6/26
Proiectarea Algoritmilor

procedura TipreteLAS(int[] a, int n, int[] lung)


/* caut valoarea lungimii maxime din ir
/* i memoreaz poziia acesteia poz
Pseudo poz DeterminMax(lung, n)
cod scrie Lungimea maxim este , lung[max]
scrie Iar subsecvena este:

/* listeaz el. subsecvenei de lungime


/* maxim ncepnd cu a[poz]
scrie a[poz]
pentru i poz+1, n-1 execut
dac lung[i]==max1 i a[i]>=a[poz] atunci
scrie a[i]
poz i
max max 1
sf.procedur
Complexitate temporal?

http://www.eed.usv.ro/~vatavu 7/26
Proiectarea Algoritmilor

Folosind metoda programrii dinamice, subsecvena


cresctoare de lungime maxim este determinat ntr-un timp
(n 2 ) cu o complexitate spaial (n) .

http://www.eed.usv.ro/~vatavu 8/26
Proiectarea Algoritmilor

Problem Subsecvena comun de lungime maxim


(LCS Longest Common Subsequence)

Fie dou iruri de numere ntregi i de dimensiuni


respectiv . S se determine subsecvena comun irurilor
i de lungime maxim.

Intrare Ieire
=11 4
=7 6 5 2 8 2 8 1 4 7 10 6 2 8 7
=7
=6 9 2 1 8 9 7

7 6 5 2 8 2 8 1 4 7 10
692189 7
http://www.eed.usv.ro/~vatavu 9/26
Proiectarea Algoritmilor

Fie matricea de dimensiune x cu semnificaia:


[ , ] reprezint lungimea celei mai lungi subsecvene
care se poate forma cu elementele
a[0], a[1], ... a[i] i b[0], b[1], ... b[j]

Cazuri particulare:
1 daca a[0] = b[0]
lung[0,0] =
0 altfel

1 daca a[0] = b[ j ]
lung[0, j ] =
lung[0, j 1] altfel

1 daca a[i ] = b[0]


lung [i ,0] =
lung [i 1,0] altfel

http://www.eed.usv.ro/~vatavu 10/26
Proiectarea Algoritmilor

Pentru a calcula [ , ] ( , >=1), reducem problema la


subirurile -1 ( ) respectiv -1 ( ) pentru care avem calculate
valorile [i-1, j], [i, j-1], [i-1, j-1].

http://www.eed.usv.ro/~vatavu 11/26
Proiectarea Algoritmilor

Pentru a ajunge la subsecvena de lungime +1 din mulimea


i de lungime +1 din mulimea avem trei posibiliti:
1) Primelor elemente din le adugm [ ] lungimea
celei mai lungi subsecvene comune va fi [ 1, ].
2) Primelor elemente din le adugm [ ] lungimea
celei mai lungi subsecvene comune va fi [ , 1].
3) Primelor elemente din le adugm [ ] iar primelor
elemente din le adugm [ ], caz n care:
a. dac [ ] = [ ] [ , ]= [ 1, 1] + 1
b. altfel, lungimea celei mai lungi subsecvene comune
va fi [ 1, 1]

http://www.eed.usv.ro/~vatavu 12/26
Proiectarea Algoritmilor

lung[i 1, j ]

lung[i, j ] = max lung[i, j 1]
a[i ] == b[ j ] ? lung[i 1, j 1] + 1 : lung[i 1, j 1]

Lungimea celei mai lungi subsecvene comune irurilor i se va


afla n matricea la locaia [ 1, 1].

http://www.eed.usv.ro/~vatavu 13/26
Proiectarea Algoritmilor

a/b 7 6 5 2 8 2 8 1 4 7 10
6 0 1 1 1 1 1 1 1 1 1 1
9 0 1 1 1 1 1 1 1 1 1 1
2 0 1 1 2 2 2 2 2 2 2 2
1 0 1 1 2 2 2 2 3 3 3 3
8 0 1 1 2 3 3 3 3 3 3 3
9 0 1 1 2 3 3 3 3 3 3 3
7 1 1 1 2 3 3 3 3 3 4 4

a/b 7 6 5 2 8 2 8 1 4 7 10
6 0 1 1 1 1 1 1 1 1 1 1
9 0 1 1 1 1 1 1 1 1 1 1
2 0 1 1 2 2 2 2 2 2 2 2
1 0 1 1 2 2 2 2 3 3 3 3
8 0 1 1 2 3 3 3 3 3 3 3
9 0 1 1 2 3 3 3 3 3 3 3
7 1 1 1 2 3 3 3 3 3 4 4
http://www.eed.usv.ro/~vatavu 14/26
Proiectarea Algoritmilor
procedura LCS(int[] a, int n, int[] b, int m)
lung new int[n,m]

Pseudo lung[0,0] (a[0] == b[0]) ? 1 : 0


pentru i = 1, n 1 execut
cod lung[i, 0] (a[i] == b[0]) ? 1 : lung[i-1,0]
pentru j = 1, m 1 execut
lung[0, j] (a[0] == b[j]) ? 1 : lung[0,j-1]
pentru i = 1, n - 1 execut
pentru j = 1, m 1 execut
lung[i, j] = max
{ (a[i] == b[j]) ? lung[i-1, j-1] + 1 : 0,
lung[i-1, j],
lung[i, j-1]
}
ntoarce lung
sf.procedur

Complexitatea temporal/spaial?
http://www.eed.usv.ro/~vatavu 15/26
Proiectarea Algoritmilor
procedura TipreteLCS(int[] a, int n, int[] b, int m, int[,] lung)
scrie Lungimea maxim este , lung[n-1,m-1]
scrie Subsecvena este:
Pseudo
i n-1
cod j m-1
ct timp i >= 0 i j >= 0 execut
dac a[i] == b[j] atunci
scrie a[i]
i i-1
j j-1
altfel
dac i-1>=0 i lung[i,j] == lung[i-1,j] atunci
i i-1
altfel
j j-1
sf.ct timp
sf.procedur

Complexitatea temporal/spaial?
http://www.eed.usv.ro/~vatavu 16/26
Proiectarea Algoritmilor

Observaie: completarea valorilor matricei lung pentru fiecare


rnd i necesit doar memorarea valorilor rndului 1.
lung[i 1, j ]

lung[i, j ] = max lung[i, j 1]
a[i ] == b[ j ] ? lung[i 1, j 1] + 1 : lung[i 1, j 1]

a/b 7 6 5 2 8 2 8 1 4 7 10
6 0 1 1 1 1 1 1 1 1 1 1
9 0 1 1 1 1 1 1 1 1 1 1
2 0 1 1 2 2 2 2 2 2 2 2
1 0 1 1 2 2 2 2 3 3 3 3
8 0 1 1 2 3 3 3 3 3 3 3
9 0 1 1 2 3 3 3 3 3 3 3
7 1 1 1 2 3 3 3 3 3 4 4

Complexitatea spaial poate fi redus la O (min( n, m)) .


http://www.eed.usv.ro/~vatavu 17/26
Proiectarea Algoritmilor
procedura LCS2(int[] a, int n, int[] b, int m)
dac n < m atunci
*) interschimb a cu b, a b
Pseudo *) interschimb n cu m, n m
cod sf.dac
anterior new int[m]
curent new int[m]
anterior[0] (a[0] == b[0]) ? 1 : 0
pentru j = 1, m 1 execut
anterior[j] (a[0] == b[j]) ? 1 : anterior[j-1]
pentru i = 1, n - 1 execut
curent[0] (a[i] == b[0]) ? 1 : anterior[0]
pentru j = 1, m 1 execut
curent[j] = max { (a[i] == b[j]) ? anterior[j-1] + 1 : 0,
anterior[j],
curent[j-1] }
curent anterior
sf.pentru
ntoarce curent[m-1]
sf.procedur
http://www.eed.usv.ro/~vatavu 18/26
Proiectarea Algoritmilor

Problem Cel mai lung palindrom

Fie un ir de numere ntregi de dimensiune . S se


determine cea mai lung subsecven cu proprietate de
palindrom.

Intrare Ieire
=9 5
=4 1 7 6 3 5 6 2 1 16361

http://www.eed.usv.ro/~vatavu 19/26
Proiectarea Algoritmilor
procedura Palindrom(int[] a, int n)
b = new int[n]
pentru i 0, n-1 execut
Pseudo b[i] a[n-1-i]
cod lung LCS(a, n, b, n)
TipreteLCS(a, n, b, n, lung)
sf.procedur

Complexitate temporal?

http://www.eed.usv.ro/~vatavu 20/26
Proiectarea Algoritmilor

Problem Transformri de cuvinte

Fie dou cuvinte , cu respectiv caractere. S se


transforme cuvntul n cuvntul folosind doar
urmtoarele tipuri de operaii:
A adugarea unei litere
M modificarea unei litere
S tergerea unei litere
S se transforme cuvntul n cuvntul cu un numr
minim de operaii.

Intrare Ieire
CARTE 2
ARTA terge C
Modific E A

http://www.eed.usv.ro/~vatavu 21/26
Proiectarea Algoritmilor

Numrul de operaii necesar conversiei este max(m, n):


min(m,n) modificri +
max(m,n) - min(m,n) tergeri.

Fie matricea cost de dimensiune n x m cu urmtoarea


semnificaie:
cost[i, j] reprezint costul minim al transformrii primelor + 1
caractere din n primele + 1 caractere din :
a[0]a[1]...a[i] b[0]b[1]b[j]

http://www.eed.usv.ro/~vatavu 22/26
Proiectarea Algoritmilor

Cazurile particulare:

0 a[0] == b[0]
cost[0,0] =
1 altfel

j=1,m-1
j a[0] == b[ j ]
cost[0, j ] =
cost[0,j-1] + 1 altfel (j operaii de adugare)

i=1,n-1
i a[i ] == b[0]
cost[i,0] =
cost[i 1,0] + 1 altfel (i operaii de tergere)

http://www.eed.usv.ro/~vatavu 23/26
Proiectarea Algoritmilor

Transformarea de lungime minim a primelor + 1 caractere


din n primele + 1 caractere din se poate realiza calculnd
minimul urmtoarelor posibiliti:
aplicnd operaia de modificare a lui a[i] b[j]+ cost[i-1,j-1]
aplicnd operaia de tergere a lui a[i] + cost[i-1,j]
aplicnd operaia de adaugare a lui a[i] + cost[i,j-1]

http://www.eed.usv.ro/~vatavu 24/26
Proiectarea Algoritmilor

i=1,n-1; j=1,m-1
cost[i 1, j 1] a[i ] == b[ j ]
1 + cost[i 1, j 1]
a[i ] b[ j ]
cost[i, j ] = min
1 + cost[i 1, j ] a[i ] b[ j ]
1 + cost[i, j 1] a[i ] b[ j ]

Numrul minim de operaii pentru a transforma cuvntul n


cuvntul se afl n [ 1, 1].
A R T A A R T A
C 1 2 3 4 C 1 2 3 4
A 1 2 3 3 A 1 2 3 3
R 2 1 2 3 R 2 1 2 3
T 3 2 1 2 T 3 2 1 2
E 4 3 2 2 E 4 3 2 2
http://www.eed.usv.ro/~vatavu 25/26
Proiectarea Algoritmilor
procedura Transform(char[] a, int n, char[] b, int m)
cost new int[n,m]
cost[0,0] (a[0] == b[0]) ? 0 : 1
Pseudo pentru i = 1, n 1 execut
cost[i, 0] (a[i]==b[0])?i:1+cost[i-1,0]
cod pentru j = 1, m 1 execut
cost[0, j] (a[0]==b[j])?j:1+cost[0, j-1]
pentru i 1, n - 1 execut
pentru j 1, m 1 execut
*) caractere egale? sau modific
min cost[i-1][j-1] + (a[i]==b[j]) ? 0 : 1
*) terge a[i]
dac min > 1+cost[i,j-1] atunci
min 1+cost[i,j-1]
*) adaug a[i]
dac min > 1+cost[i-1,j] atunci
min 1+cost[i-1,j]
cost[i][j] min
ntoarce cost
sf.procedur

http://www.eed.usv.ro/~vatavu 26/26

S-ar putea să vă placă și