• Nie Znaleziono Wyników

ALGORYTMY I STRUKTURY DANYCH

N/A
N/A
Protected

Academic year: 2021

Share "ALGORYTMY I STRUKTURY DANYCH"

Copied!
22
0
0

Pełen tekst

(1)

ALGORYTMY I STRUKTURY DANYCH

WYKŁAD 13

Techniki konstruowania algorytmów – przykłady Grażyna Mirkowska

PJWSTK, 2002/2003

(2)

Plan wykładu

 Kody Huffmana

 Mnożenie macierzy

 Najdłuższy wspólny podciąg

(3)

Problem kodowania

Dany jest ciąg znaków. Chcemy tak zapisać ten ciąg, by zajmował jak najmniej miejsca i by dało się go potem łatwo odtworzyć.

Znak = liczba 0-255, czyli 8 bitów

100 000 znaków zajmuje 800 000 bitów.

Jeśli w naszych danych występuje tylko 6 różnych znaków, to 3 bity wystarczą do ich zakodowania, np.: 000,001,010,011,100,101

100 000 znaków

zajmuje 300 000

bitów.

(4)

Kody stałej i zmiennej długości

Kody o stałej długości -- wszystkie słowa kodowe mają tę samą długość

Kody o zmiennej długości -- długość słowa kodowego zależy od częstości

występowania danego znaku w ciągu danych.

Znaki występujące często mają kod możliwie krótki.

Niech będzie tekst 100000 znakowy, w którym występują tylko litery a,b,c,d,e,f i a-45tys razy, b-13tys., c-12tys.,

d-16tys., e - 9tys., f-5tys. razy.

Używając kodu

a= 0, b= 101,c= 100, d=111, e=1101, f=1100 nasz tekst można

zakodować na 224000bitach.

Przykład

Przykład

(5)

Kody prefiksowe

Żadne słowo kodowe nie jest prefiksem żadnego innego słowa kodowego.

ZASADA

ZASADA tzn,. Nie istnieją takie

dwa słowa a i b a=(a

1

,...a

n

) i b=(b

1

,b

2

...,b

m

) n<m , że a

1

=b

1

, a

2

= b

2

... a

i

= b

i

dla i=1...n.

Chodzi o to by można było jednoznacznie odczytać zakodowany

tekst.

Twierdzenie Twierdzenie

Jeśli istnieje optymalne

kodowanie, to zawsze można

znaleźć kod prefiksowy, który

go realizuje.

(6)

Drzewo kodowe (1)

A:45

100

86 14

58 28 14

B:13 C:12 D:16 E:9 F:5

Kod stałej długości

Każda ścieżka odpowiada jednemu słowu kodowemu.

W lewo = 0 w prawo = 1

F ma kod 101 F ma kod 101

Znak + częstość

występowania

(7)

Drzewo kodowe(2)

Kod zmiennej długości 100

A:45

25 30

C:12 B:13 14 D:16

F:5 E:9

55

Optymalny kod zawsze jest reprezentowany przez

lokalnie pełne drzewo binarne.

Ciąg:

0100110110101100

A 0 B 101 C 100 D 111 E 1101 F 1100 Odczytujemy

jako:ACEBAF

(8)

Konstrukcja kodu Huffmana

1.Utworzyć kolejkę priorytetową PQ

zawierającą wszystkie znaki alfabetu wraz z ich częstością wystąpienia

lewy prawy f

Znak f 2. For i :=1 to n-1 do

a := min(PQ); PQ := delmin(PQ);

b := min(PQ); PQ := delmin(PQ);

z := New node (a,b);

z.f := a.f + b.f;

PA := insert(PQ, z);

od;

return min (PQ);

liść liść

Wierzchołek Wierzchołek wewnętrzny wewnętrzny

Koszt

Koszt O(n lgn)

Algorytm zachłanny

Algorytm zachłanny

(9)

Przykład

A:45

C:12 B:13 D:16

F: 5 E: 9

14 A:45

C:12 B:13 D:16

F: 5 E: 9 14

25

A:45

C:12 B:13

D:16

F: 5 E: 9

14 25

30 A:45

C:12 B:13 D:16

F: 5 E: 9 14

25 30

55 A:45

0 100 1

1

1 0

0 1 0

0 1

(10)

Mnożenie macierzy

Dany jest ciąg macierzy A

1

, A

2

,...,A

n

. Obliczyć iloczyn A

1

 A

2

...  A

n

tak by koszt mnożenia był najmniejszy.

Uwaga: Możemy pomnożyć macierz A

1

przez A

2

wttw

gdy A

1

ma tyle kolumn ile A

2

wierszy .

Koszt = A

1

.w *A

1

.k*A

2

.k

Przykład Przykład

Obliczyć A  B  C.

A(10  100) B(100  5) C(5  50) (A  B)  C = A  ( B  C)

Koszt prawej strony =

(100 *5*5 0) + (10*100*50) = 75000 mnożeń skalarnych

Koszt lewej strony =

(10 *100*5 ) + (10*5*50)=

7500 mnożeń skalarnych

(11)

Prosty Algorytm?

Rozważyć wszystkie możliwe ustawienia

nawiasów w ciągu, a potem wykonać mnożenia zgodnie z ustawieniem nawiasów.

Za każdym razem wyliczyć koszt mnożenia przy danym ustawieniu nawiasów i wybrać to

ustawienie, które ma koszt najmniejszy.

A ile jest możliwych ustawień nawiasów?

A ile jest możliwych ustawień nawiasów?

Niech P(n) będzie liczbą ustawień

nawiasów w ciągu n elementowym.

(A

1

,..., A

k

) ( A

k+1

..,A

n

)

 

 

 

 1 1

. )

(

* ) (

1 ,

1 )

(

n

k

wpp k

n P k P

n gdy n

P

n-1- sza liczba Catalana

(4

n

/n

3/2

)

Za duży koszt!

(12)

Paradygmat programowania dynamicznego

1. Scharakteryzować strukturę rozwiązania optymalnego .

Rozwiązanie optymalne zawiera w sobie optymalne rozwiązania dla

podproblemów.

2. Zdefiniować rekurencyjnie wartość rozwiązania optymalnego, jako funkcję rozwiązań optymalnych dla podproblemów.

W naszym przykładzie: dla pewnego k, policzymy najpierw optymalne

ustawienie nawiasów dla iloczynu (A

1

,..., A

k

) potem optymalne

ustawienie nawiasów dla iloczynu

(A

k+1

..,A

n

), a potem dodamy do tego

koszt mnożenia 2 macierzy.

(13)

Liczymy minimalny koszt



 

 

 

m i k m k j p p p dla i j

j i

j gdy i

m

j k j i

k

i

{ [ , ] [ 1 , ]

1

min ] 0

, [

Niech m[i,j] będzie minimalną liczbą mnożeń skalarnych potrzebnych do policzenia iloczynu ( A

i

..,A

j

), oraz macierz A

i

ma wymiar (p

i-1

 p

i

).

Niech s[i,j] = to k, które realizuje minimum dla m[i,j].

Rekurencyjny algorytm obliczania m[i,j] nie jest możliwy, nie jest możliwy, bo jego koszt jest wykładniczy, ale...

Przecież

można zapamiętywać policzone

wcześniej wartości

m[i,j]!

(14)

Algorytm MCM

for i :=1 to n do m[i,i] :=0; od;

for x := 2 to n do

for i := 1 to n-x+1 do j := i+x-1

m[i,j] := +;

for k := i to j-1do

q := m[i,k]+m[k+1,j] + p

i-1

*p

k

*p

j

;

if q < m[i,j] then m[i,j] := q; s[i,j] :=k fi od

od od

return m,s; Koszt O(n Koszt O(n 3 3 ) )

Ustawienie

początkowej wartości elementów tablicy m.

Dwie pętle odpowiedzialne za wypełnienie wszystkich elementów m[i,j].

Wyszukiwanie

minimum

(15)

15125 10500

5375

3500

5000

0

11875 7125

2500

1000

0

9375 4375

750

0

7875

2625

0

15750

0 0

1 2

3 4

5 6 1

2 3

4 5

6

A

1

A

2

A

3

A

4

A

5

A

6

Tablica m

Tablica s

3 3

3

5

5

3 3

3

4

3 3

3

1

2

1

1 2

3 4

5 6 2

3 4

5 6

m[2,5]= min {

m[2,2] + m[3,5] + p

1

*p

2

*p

5

,

,

m[2,3] + m[4,5] + p

1

*p

3

*p

5

,

m[2,4] + m[5,5] + p

1

*p

4

*p

5

}

(16)

W jakiej kolejności mnożyć?

Zasada 3 paradygmatu programowania dynamicznego:

Skonstruować rozwiązanie problemu na bzie wyliczonych wielkości.

mnóż(A,s,i,j) {

If j>i then

X := Mnóż(A,s,i,s[i,j]);

Y:= mnóż(A,s,s[i,j]+1,j);

return wynik mnożenia macierzy (XY) else

return A

i

}

W naszym przykładzie :|

Mnóż (A,s,1,6) daje :

(A (A 1 1 (A (A 2 2 A A 3 3 ))((A ))((A 4 4 A A 5 5 ) A ) A 6 6 ) )

(17)

Najdłuższy wspólny podciąg

Dane są dwa ciągi znaków X i Y

X=(x

1

,…x

m

) Y = (y

1

,…,y

n

)

Znaleźć ciąg Z=(z

1

,…z

k

) taki, że Z jest najdłuższym podciągiem zarówno ciągu X jak i Y, ozn. Z = nwp(X,Y)

X = aawbbsccpddoln Y = xxwsyyypozzlny nwp(X,Y) = wspólny

Przykład Przykład

• Wygenerować wszystkie podciągi ciągu X.

• Dla każdego z tych ciągów sprawdzić czy występuje w Y, zapamiętując

jednocześnie najdłuższy z takich ciągów.

Ale

to zbyt dużo kosztuje

O(2

m

)

(18)

Analiza zadania

Niech X= (x

1

,…x

m

) Y= (y

1

,…,y

n

) oraz nwp(X,Y) = Z , gdzie Z=(z

1

,…z

k

).

Jeżeli x

m

=y

n

, wtedy z

c

=x

m

=y

n

oraz Z

k-1

= nwp(X

m-1

, Y

n-1

), Jeżeli x

m

 y

n

, wtedy

Z = nwp(X

m-1

,Y), gdy z

k

 x

m

oraz Z = nwp(X,Y

n-1

), gdy z

k

 y

n

.

Oznaczenie: X

i

= (x

1

,…x

i

)

(19)

Algorytm2

Function nwp(X,Y :string) : string;

begin

if x(m)=y(n) then Z := nwp(X

m-1

1, Y

n-1

)o x(m) else

Z1 := nwp(X

m-1

, Y);

Z2 := nwp(X,Y

n-1

);

Z := dluższy z ciągów Z1 i Z2;

fi end;

konkatenacja

Koszt tego algorytmu

będzie w najgorszym

razie wykładniczy.

(20)

Jak wyliczyć długość nwp(X,Y)?

długość najdłuższego wspólnego podciągu ciągów X,Y.

d(X,Y) = d( X

m-1

,Y

n-1

) +1, gdy x

m

=y

n

d(X,Y) = max (d(X

m-1

,Y),d(X ,Y

n-1

), gdy x

m

y

n

Koszt obliczenia d(X,Y) wynosi

card(X) * card(Y) porównań.

Przykład Przykład

1 2 3 4 5 6 B D C A B A 1 A 0 0 0 1 1 2 2 B 1 1 1 1 2 2 3 C 1 1 2 2 2 2

Koszt Koszt

0

1 1

(21)

Algorytm

Begin

for i :=1 to m do d(i,0):=0 od;

for j :=0 to n do d(0,j) := 0 od;

for i :=1 to m do for j :=1 to n do if x(i)=y(j) then

d(i,j) := d(i-1,j-1) +1; b(i,j) := „\”

else

if d(i-1,j)  d(i,j-1) then

d(i,j) := d(i-1,j); b(i,j) := „”

else

d(i,j) := d(i,j-1); b(i,j) := „ ”

fi fi

od od end

Po przekątnej zadanie, które trzeba rozwiązać,żeby

otrzymać optymalny wynik.

„w górę” zadanie, które trzeba rozwiązać, żeby otrzymać optymalny wynik

„w lewo” zadanie, które

trzeba rozwiązać, żeby

otrzymać optymalny wynik

(22)

Wypisanie nwp

Procedure Drukuj(b,i,j);

begin

if i=0 or j=0 then return fi;

if b(i,j) = „\” then

call drukuj(b,i-1,j-1);

write(x(i)) else

if b(i,j) = „  ” then

call drukuj(b,i-1,j) else

call drukuj (b,i,j-1) fi

fi end

Przykład

b(i,j) 1 2 3 4 5 6 B D C A B A 0 0 0 0 0 0 1 A 0 0 0 0 1 1 2 2 B 0 1 1 1 1 2 2 3 C 0 1 1 2 2 2 2 4 B 0 1 1 2 2 3 3 5 D 0 1 2 2 2 3 3 6 A 0 2 2 3 3 4 4 7 B 0 1 2 2 3 4 44 4

3 3 2 2 1

0 1

Cytaty

Powiązane dokumenty

producent, nazwa handlowa, wraz z zalączeniem kart katalogowych.. produktu

[r]

Wykonawca powinien umieścić ofertę w zamkniętej, nieprzeźroczystej kopercie, opatrzonej pieczęcią firmową wykonawcy oraz dopiskiem: Oferta przetargowa: „Prawo jazdy kat.

Jeżeli podano więcej niż dwie nazwy roślin (np. Poprawna odpowiedź:. Części owocu lub nasienia

- Punkty przyznaje się za każdą poprawną merytorycznie odpowiedź, nawet, jeśli nie została uwzględniona w schemacie.. - Wymagana jest pełna poprawność zapisu

Jeżeli podano więcej niż trzy odpowiedzi, ocenie podlegają tylko trzy kolejne, pierwsze odpowiedzi...

Za każde poprawne i pełne rozwiązanie (również inne niż podane w kluczu odpowiedzi) przyznajemy maksymalną liczbę punktów należnych za zadanie.. Uwagi dotyczące sprawdzania

W ka»dej przestrzni topologicznej suma dowolnej ilo±ci zbiorów otwartch jest zbiorem otwartym.. Czy to samo mo»na powiedzie¢ o cz e±ci wspól- nej dowlonej ilo±ci