algor3

background image

algorytmy

algorytmy

i

i

złożoność

złożoność

wykład 3

background image

ZŁOŻONOŚĆ OBLICZENIOWA

Dokonując oceny różnych algorytmów rozwiązujących dane
zagadnienia chcemy wiedzieć, jaka jest ich złożoność
obliczeniowa
, czyli inaczej, jaka ilość zasobów komputerowych
potrzebna jest do ich wykonania.

Za podstawowe zasoby komputerowe uważa się:

czas działania algorytmu

ilość zajmowanej pamięci.

background image

Czy stwierdzenie:

Mój program (algorytm) jest szybki, bo rozwiązał zadanie w
55 sekund !

może posłużyć za obiektywną ocenę jego sprawności ?

Dodatkowo powinniśmy bowiem wiedzieć:

na jakim komputerze program był wykonywany

jaki miał procesor (częstotliwość zegara)

co działo się w pamięci komputera podczas jego wykonywania

jakiego kompilatora użyto do napisania programu, itp.

Ocena sprawności algorytmu przy pomocy kryteriów sprzętowych
nie jest oceną

obiektywną!

background image

miara uniwersalna, która ma decydujący wpływ na czas
wykonywania
określonego algorytmu

Parametrem tym jest rozmiar danych wejściowych algorytmu.

Pojęcie to ma różne znaczenie dla różnych zagadnień, np.:

w sortowaniu ciągu n-elementowego jest to ilość elementów tego ciągu, czyli n.

dla zadań grafowych jest to liczba krawędzi rozpatrywanego grafu

przy wyznaczaniu wartości wielomianu - stopień tego wielomianu

dla operacji na macierzach - wymiary macierzy

dla wyliczenia wartości funkcji n! -wartość danej n.

background image

Dla złożoności pamięciowej jednostką jest słowo pamięci.

Dla złożoności czasowej problem jest bardziej złożony, ponieważ
jednostka ta powinna być własnością samego tylko algorytmu jako
metody rozwiązania problemu, a nie powinna zależeć od komputera,
języka programowania, kodowania , itp.
W tym celu wyróżnia się w klasie algorytmów charakterystyczne dla
niego operacje - nazywane są one operacjami dominującymi.

Przykłady operacji dominujących:

# w algorytmach sortowania
porównanie dwóch elementów w ciągu wejściowym
przestawienie dwóch elementów w ciągu

# w algorytmach numerycznych, np. obliczania wartości wielomianu
operacje arytmetyczne: +, -, /, *

# w algorytmach przeglądanie drzewa binarnego
przejście do wiązania pomiędzy dwoma węzłami w drzewie.

Za jednostkę złożoności czasowej przyjmuje się wykonanie jednej
operacji dominującej.

background image

Czy postęp w szybkości obliczeń komputerów zmniejsza znaczenie
efektywności algorytmów?

Rozważmy pięć algorytmów A1, A2,..., A5, rozwiązujących ten sam problem
i mających następujące złożoności czasowe:

gdzie n - rozmiar danych wejściowych.

background image

Zakładając, że jednostką czasu jest jedna milisekunda, pokażemy,
jakiego maksymalnego rzędu zadania mogą rozwiązać te algorytmy
odpowiednio w: 1 sekundzie, 1 minucie, 1 godzinie.

background image

Przypuśćmy, że nowa generacja komputerów jest 10-krotnie szybsza.
Pokażemy, jaki jest wzrost rozmiaru zadań, które mogą być rozwiązane
dzięki wzrostowi szybkości komputerów:

WNIOSEK: Bardziej opłacalne jest konstruowanie szybszych algorytmów.

background image

Rozpatrywane wyżej funkcje złożoności czasowej są tzw. złożonościami
asymptotycznymi
, tzn. nie uwzględniają stałej proporcjonalności. Może się,
więc zdarzyć, że analizując faktyczne funkcje złożoności czasowej, algorytm
asymptotycznie gorszy jest szybszy dla małych zadań niż algorytm
asymptotycznie lepszy.

Dla ilustracji przypuśćmy, że rozważane algorytmy A1, ..., A5 mają następujące
faktyczne funkcje złożoności czasowej:

background image

Wyznaczając złożoność czasową algorytmu (jest to funkcja rozmiaru danych n)
rozróżniamy jej dwie postacie:
1) złożoność pesymistyczna
ilość operacji dominujących potrzebnych przy trafieniu na „najgorsze” dane
wejściowe rozmiaru n
2) złożoność oczekiwana
ilość operacji dominujących potrzebnych przy „typowych” danych wejściowych
rozmiaru n.

background image

Formalne definicje tych pojęć:

Przez pesymistyczną złożoność czasową algorytmu rozumie
się funkcję:

gdzie:

sup

- kres górny zbioru

D

n

- zbiór wszystkich możliwych zestawów danych

wejściowych rozmiaru n

t(d)

- liczba operacji dominujących dla zestawu

danych

wejściowych d

}

:

)

(

sup{

)

(

n

D

d

d

t

n

W

background image

Przez oczekiwaną złożoność czasową algorytmu rozumie się funkcję:

gdzie:

p

nk

- rozkład prawdopodobieństwa zmiennej losowej X

n

,

tzn. prawdopodobieństwo,

że dla danych rozmiaru n algorytm

wykona k operacji dominujących (k 0),

X

n

- zmienna losowa, której wartością jest t(d), dla d D

n

czyli jest to wartość oczekiwana ave(X

n

) zmiennej losowej X

n

.

0

)

(

k

nk

p

k

n

A

background image

W celu stwierdzenia, na ile funkcje W(n) i A(n) są reprezentatywne dla
wszystkich
danych wejściowych rozmiaru n, rozważa się dwie wrażliwości algorytmu:

miarę wrażliwości pesymistycznej:

miarę wrażliwości oczekiwanej:

gdzie dev(X

n

) jest standardowym odchyleniem zmiennej losowej X

n

, tzn.

var(X

n

) oznacza wariancję zmiennej losowej X

n

.

n

D

d

d

d

t

d

t

n

2

1

2

1

,

:

)

(

)

(

sup{

)

(

)

(

dev

)

(

n

X

n

nk

k

n

n

n

n

p

X

k

X

X

X

2

0

))

(

ave

(

)

var(

)

var(

)

(

dev

background image

Jak należy interpretować wartości wrażliwości ∆(n) i δ(n):

Im większe wartości (n) i δ(n), tym algorytm jest bardziej wrażliwy na dane
wejściowe
i tym bardziej jego zachowanie w wypadku rzeczywistych danych
może odbiegać od zachowania opisanego funkcjami W(n) i A(n).

background image

przykład - algorytm przeszukiwania

sekwencyjnego ciągu

Problem: Dla podanego n-elementowego ciągu liczb naturalnych oraz liczby x
sprawdzić, czy liczba x jest elementem tego ciągu.

Dane wejściowe:
n, (n
0) liczba naturalna
L[1..n+1] tablica z elementami ciągu (a

1

, ..., a

n

) na miejscach od 1do n ,

x poszukiwany element.

Dane wyjściowe (wynik):
zmienna logiczna p taka, że

p= prawda gdy element x należy do ciągu
p= fałsz, gdy element x nie należy do ciągu

background image

przykład - algorytm przeszukiwania

sekwencyjnego ciągu cd.

Zapis algorytmu w pseudokodzie:

początek
j := 1;
L[n+1] := x;
dopóki L[j] # x wykonuj j:= j+1;
p := j
n
koniec;

background image

przykład - algorytm przeszukiwania

sekwencyjnego ciągu cd.

Realizacja algorytmu (zestaw danych 1)
Dla
: n = 4; ciągu (1,4,2,8), x = 4 mamy:
L[1]=1, L[2]=4, L[3]=2, L[4]=8
j=1 , L[5]=4
1 # 4, TAK j=1+1=2

( L[1]#4 )

4 # 4, NIE

( L[2)#4 )

p=2 4 (prawda)

background image

przykład - algorytm przeszukiwania

sekwencyjnego ciągu cd.

Realizacja algorytmu (zestaw danych 2)
Dla
: n = 4; ciągu (1,4,2,8), x = 5 mamy
L[1]=1, L[2]=4, L[3]=2, L[4]=8
j=1 L[5]=5
1#5, TAK j=1+1=2 (L[1]#5 )
4#5, TAK j=2+1=3 (L[2]#5 )
2#5, TAK j=3+1=4 (L[3]#5 )
8#5, TAK j=4+1=5 (L[4]#5 )
5#5, NIE (L[5]#5 )
p=5
4 (falsz)

background image

przykład - algorytm przeszukiwania

sekwencyjnego ciągu cd.

Analiza złożoności algorytmu:

Rozmiar danych wejściowych :

n

Operacje dominujące :

porównania L[j])#a

Pesymistyczna złożoność czasowa :

W(n)=n+1

Pesymistyczna wrażliwość czasowa:

(n)=n

bo najwięcej porównań n+1

bo najmniej porównań 1

stąd ∆(n)=(n+1)-1=n

background image

przykład - algorytm przeszukiwania

sekwencyjnego ciągu cd.

Jaka jest więc oczekiwana złożoność czasowa ?
Niech prawdopodobieństwo znalezienia elementu x na każdym z n możliwych
miejsc jest takie samo, oraz element x należy do ciągu (a

1

,.... a

n

), tzn.

Wówczas

n

1,2,

k

dla

1

n

p

nk

2

1

2

)

1

(

1

1

1

)

(

1

1

1

n

n

n

n

k

n

n

k

p

k

n

A

n

k

n

k

n

k

nk

background image

przykład - algorytm przeszukiwania

sekwencyjnego ciągu cd.

Do obliczenia oczekiwanej wrażliwości czasowej należy znaleźć wcześniejsze
wariancje zmiennej losowej X

n

2

2

2

2

1

2

1

2

12

1

12

1

3

3

2

4

12

1

2

1

6

)

1

2

)(

1

(

2

1

2

)

1

(

2

)

1

(

2

6

)

1

2

)(

1

(

1

1

)

2

1

(

))

(

ave

(

)

var(

n

n

n

n

n

n

n

n

n

n

n

n

n

n

n

n

n

n

n

n

k

p

X

k

X

n

k

nk

n

k

n

n

 



 

background image

przykład - algorytm przeszukiwania

sekwencyjnego ciągu cd.

i teraz

 

 

n

n

X

X

dev

n

n

n

25

,

0

12

1

var

)

(

2

Wniosek:
Funkcja wrażliwości i funkcja złożoności są liniowe, a więc mocno wrażliwe
na układ danych wejściowych.

background image

Faktyczna złożoność czasowa algorytmu w chwili jego użycia różni się od

wyliczonej teoretycznie, pewnym współczynnikiem proporcjonalności lub pewnymi
elementami stałymi. Ponieważ analiza złożoności interesuje się głównie zależnością
efektywności algorytmu (czasu działania) od rozmiaru problemu w sytuacji, gdy ten
ostatni wzrasta nieograniczenie, nie jest istotna dokładna formuła tej zależności, lecz
jej zachowanie asymptotyczne. Pomijamy w niej stałe elementy i inne, pozostawiając
jedynie najbardziej znaczące składniki formuły, czyli te, które decydują o zachowaniu
się formuły, gdy rozmiar n dąży do nieskończoności.

Reasumując, istotną częścią informacji, która jest zawarta w funkcji złożoności

czasowej W(n) jest jej rząd wielkości, czyli jej zachowania asymptotyczne,
gdy n dąży do nieskończoności. Poniżej omówione będą pewne pojęcia związane
z tym zagadnieniem.

background image

Niech f, g, h : N→R

+

{0},

gdzie: N - zbiór liczb naturalnych

R

+

- zbiór liczb rzeczywistych dodatnich

NOTACJA O

NOTACJA O

Mówimy, że funkcja f jest co najwyżej rzędu funkcji g, co zapisujemy jako

f(n)= O (g (n))

jeżeli istnieje stała rzeczywista c>0 i stała naturalna n

0

takie, że

f(n) ≤ c g(n), dla każdego n n

0

Np. Dla (n) = n

2

+2n mamy, że n

2

+2n=O(n

2

), bo istnieje stała c=3>0 i stała

naturalna n

o

=1 takie, że

n

2

+2n ≤ 3⋅ n

2

= 3g(n) dla każdego n ≥ 1⋅ i g(n)= n

2

Czyli f(n) = n

2

+2n jest co najwyżej rzędu O(n

2

)

background image

NOTACJA Ω

NOTACJA Ω

Mówimy, że funkcja f jest co najmniej rzędu funkcji g, co zapisujemy jako

f(n) = (g(n))

jeżeli istnieje stała c>0 i stała naturalna n

0

, takie, że

c g(n) f(n) dla każdego n ≥ n

0

Inaczej mówiąc: g(n) = O(f(n))

background image

NOTACJA Θ

NOTACJA Θ
Mówimy, że funkcja f jest dokładnie rzędu funkcji g, co zapisujemy jako

f(n) = Θ(g(n))

jeżeli istnieja stałe c

1

>0, c

2

>0 oraz stała naturalna n

o

, takie, że

c

1

g(n) f(n) c

2

g(n) dla każdego n ≥ n

o

Czyli inaczej f(n) = O(g(n)) i f(n) = (g(n)).

Np. Dla funkcji f(n) = 1/2 n

2 -

3n mamy, że f(n)= 1/2 n2 - 3n = Θ(n

2

)

ponieważ istnieją stałe c

1

>0, c

2

>0 i n

o

, dla których

c

1

n

2

≤ 1/2 n

2 -

3n ≤ c

2

n

2

dla każdego n n

o

Można bowiem sprawdzić, że dla c

1

= 1/14, c

2

= 1/2, n

0

=7 zachodzi nierówność

7.

n

dla

2

1

3

2

1

14

1

2

2

2

n

n

n

n

background image

Do porównania rzędów wielkości dwóch danych funkcji f(n) i g(n) można
wykorzystać obliczenia następującej granicy:

Jeżeli
E=+∞, to

g(n) = O(f(n)) ale NIE f(n)=O(g(n))

E=c>0,

to

f(n) = Θ(g(n))

E=0,

to

f(n) = O(g(n)) ale NIE g(n)=O(f(n)).

)

(

)

(

lim

n

g

n

f

E

n

background image

background image

background image

Przyjmijmy, że komputer, na którym wykonujemy te algorytmy może wykonać
1 milion operacji na 1 sek.

dla n!=24! czas jest większy niż obecny wiek wszechświata.


Document Outline


Wyszukiwarka

Podobne podstrony:
ALGOR3

więcej podobnych podstron