Uploaded by muppetsanhehe

Wyklad 2 - złożoność

advertisement
Jak porównywać algorytmy?
Kryteria
• prostota
• czytelność
• długość kodu
• poprawność
• czas realizacji
złożoność obliczeniowa
• zajętość pamięci
Idealny algorytm to taki, który ma prosty kod, jest napisany w ogólnie
dostępnym języku programowania, łatwo go zrozumieć, liczy szybko, nie
wymaga dużo miejsca w pamięci i zawsze daje poprawne wyniki.
AiSD - Wykład 2
Slajd 1
Koszt algorytmu
Miary kosztu
Pamięć
Czas
• liczba zmiennych
• liczba instrukcji
• ilość miejsca potrzebna dla danych
• liczba operacji arytmetycznych
• liczba wywołań procedury
Złożoność pamięciowa
Złożoność czasowa
Ogólnie: wybór miary zależy od typu problemu, rodzaju rozwiązania.
AiSD - Wykład 2
Slajd 2
Rozmiar danych wejściowych
Rozmiar danych wejściowych (input size) - liczba elementów w ciągu wejściowym
lub całkowita liczba bitów potrzebnych do reprezentowania tych danych.
Przykłady
1. W problemie sortowania, wyszukiwania, dodawania elementów macierzy, mnożenie
macierzy – liczba elementów w ciągu wejściowym, np. liczba n elementów do
posortowania
2. Gdy na wejściu algorytmu jest graf – liczba jego wierzchołków |V| i krawędzi |E|
3. Poszukiwanie n-tego wyrazu ciągu Fibonacciego lub obliczanie n! – n jest daną a nie
rozmiarem! W tym przypadku rozmiarem jest liczba bitów wymaganych do
zakodowania wartości n:
ln n  1
AiSD - Wykład 2
Slajd 3
Przykład analizy algorytmu
Insertion-Sort(A)
1. for j:=2 to N
2.
do key:=A[j]
3.
i:= j-1
4.
while i>0 i A[i] > key
5.
do A[i+1] := A[i]
6.
7.
i:= i-1
A[i+1] := key
koszt liczba wykonań
c1
n
c2
n-1
c3
n-1
n
t j
c4
j 2
c5
c6
c7
n
 (t j  1)
j 2
n
 (t j  1)
j 2
n-1
tj - liczba sprawdzeń warunku wejścia do pętli while (wiersz 4) dla danej wartości j
Animacja 1
AiSD - Wykład 2
Animacja 2
Slajd 4
Przykład analizy algorytmu cd.
T (n)  c1n  c2 (n  1)  c3 (n  1)  c4
n
n
n
j 2
j 2
j 2
 t j  c5  (t j  1)  c6  (t j  1)  c7 (n  1)
W najgorszym przypadku:
n(n  1)
1
j
2
j 2
n
n
 ( j  1) 
j 2
n(n  1)
2
Wtedy:
 n(n  1) 
 n(n  1) 
 n(n  1) 
T (n)  c1n  c2 (n  1)  c3 (n  1)  c4 
 1  c5 

c
 6
  c7 (n  1)
 2

 2 
 2 
c
c 
c
c
c
c


  4  5  6 n 2   c1  c2  c3  4  5  6  c7 n  (c2  c3  c4  c7 )
2
2
2
2
2
 2


T (n)  an2  bn  c  (n 2 )
AiSD - Wykład 2
Slajd 5
Uproszczenia w określaniu złożoności
Zliczanie tylko operacji dominujących
Operacja dominująca to taka operacja o, że liczba wszystkich operacji wykonanych
przez algorytm jest nie większa niż cliczba operacji o, dla pewnej stałej c.
Przykłady
1. W algorytmach sortowania jako operację dominującą przyjmuje się zwykle
porównanie elementów ciągu wejściowego (czasem przestawienie elementów).
2. W algorytmach grafowych jako dominującą operację przyjmuje się przejście do
dowiązanego węzła.
Asymptotyczne oszacowanie funkcji T(n)
AiSD - Wykład 2
Slajd 6
Notacja asymptotyczna
cg(n)
f(n)
Mówimy, że f jest co najwyżej rzędu g,
co zapisujemy jako f(n) = O(g(n)), jeśli istnieją
stała rzeczywista c > 0 i stała naturalna n0 takie,
że dla każdego n  n0 zachodzi nierówność
f(n)  cg(n).
Np. n2 + 2n = O(n2) , bo n2 + 2n  3n2 dla każdego
naturalnego n.
f(n)=O(g(n))
n
n0
Mówimy, że f jest co najmniej rzędu g, co zapisujemy jako f(n) = (g(n)), jeśli
g(n) = O(f(n)),
c2g(n)
f(n)
Mówimy, że f jest dokładnie rzędu g, co
zapisujemy jako f(n) = (g(n)), jeśli zarówno
f(n) = O(g(n)), jak i f(n) = (g(n)), tzn. istnieją takie
stałe rzeczywiste dodatnie c1 i c2 oraz stała
naturalna n0, że dla każdego n  n0 zachodzi
nierówność c1g(n)  f(n)  c2g(n)
Mówimy też, że f jest asymptotycznie równoważne g
i piszemy f(n)  g(n)
AiSD - Wykład 2
c1g(n)
f(n)=(g(n))
n0
n
Slajd 7
Notacja asymptotyczna c.d.
Używa się też oznaczenia f(n) = g(n) + O(h(n)), gdy f(n) - g(n) = O(h(n))
Np. ½n2 + 5n +1 = ½n2 +O(n) ← zachowujemy w ten sposób współczynnik przy najbardziej
znaczącym składniku sumy
Rzędy wielkości dwóch funkcji f(n) i g(n) mogą być porównywane przez obliczenie granicy:
f (n)
E  lim
n g(n)
Jeśli E = +∞, to g(n) = O(f(n)), ale nie f(n) = O(g(n))
Jeśli E = c > 0, to f(n)  g(n)
Jeśli E = 0, to f(n) = O(g(n)), ale nie g(n) = O(f(n))
Np.
nlog n
ln n
1/ n

lim

lim
0
2
n n
n nln2 n ln2
lim
czyli nlogn = O(n2), ale nie n2 = O(nlogn)
Dla każdego wielomianu p(n) 
d
 ai ni
mamy p(n) = (nd)
i 0
AiSD - Wykład 2
Slajd 8
Typowe złożoności czasowe
1
– złożoność stała – liczba wykonanych operacji nie zależy od rozmiaru zadania
lg n
– złożoność logarytmiczna (algorytmy typu: zadanie rozmiaru n zostaje sprowadzone
do zadania rozmiaru n/2 + pewna stała liczba działań,
np. poszukiwanie binarne w ciągu uporządkowanym)
n
– złożoność liniowa (algorytmy, w których jest wykonywana stała liczba działań dla
każdego z n elementów danych wejściowych, np. algorytm Hornera wyznaczania
wartości wielomianu)
n lgn – złożoność liniowo-logarytmiczna (algorytmy typu: zadanie rozmiaru n zostaje
sprowadzone do dwóch podzadań rozmiaru n/2 plus pewna liczba działań liniowa
względem n, potrzebnych do wykonania najpierw rozbicia,
a następnie scalenia rozwiązań rozmiaru n/2 w rozwiązanie rozmiaru n,
np. algorytm sortowania przez scalanie – mergesort)
n2
– złożoność kwadratowa (np. algorytmy, w których stała liczba działań jest
wykonywana dla każdej pary elementów danych wejściowych)
n3, n4 itd. – złożoności wielomianowe
nlgn
– złożoność podwykładnicza
2n
– złożoność wykładnicza 2n (stała liczba działań dla każdego podzbioru danych)
n!
– złożoność wykładnicza n! (algorytm, w którym wykonywana jest stała liczba
działań dla każdej permutacji danych wejściowych)
AiSD - Wykład 2
Slajd 9
Złożoność a czas
Ile czasu potrzeba na rozwiązanie zadania o ustalonym rozmiarze i złożoności?
T(n)
lg n
n
n lg n
n2
n3
2n
102
6.6 ms
0.1 ms
0.6 ms
10 ms
1s
106 lat
104
13.3 ms
10 ms
0.1 s
100 s
11 dni
10100 lat
n
Jaki jest maksymalny rozmiar problemu, który można rozwiązać w ustalonym czasie,
znając złożoność algorytmu?
T(n)
czas
1s
1 godz
AiSD - Wykład 2
lg n
n
n lg n
n2
n3
2n
2 1000000
106
63·103
103
102
19
13·107
60·103
15·102
31
23600000000 36·108
Slajd 10
Czy szybkość może pokonać złożoność?
Mamy 5 algorytmów A1, A2, A3, A4, A5 rozwiązujących ten sam problem. Niech si
oznacza maksymalny rozmiar problemu, który można rozwiązać na komputerze 1
przy pomocy algorytmu Ai w ustalonym czasie t. Jaki jest maksymalny rozmiar
problemu, który można rozwiązać w tym samym czasie t na drugim komputerze
100 razy szybszym?
lg n
n
n2
n3
2n
Komputer 1
s1
s2
s3
s4
s5
Komputer 2
s1 100
100·s2
10·s3
4,642·s4
6,644+s5
Przykład A5.
Dla komputera 1:
Dla komputera 2:
Szukamy takiego x, że T(A5,x)= t.
Mamy więc 2x = 100·2s5 = 2 s5+lg100 .
T(A5,s5) = 2s5 = t .
T(A5,x) = 2x = t *100.
Czyli x = s5 + lg100 ≈ s5 + 6,644
Dla komputera 1000000-krotnie szybszego rozmiar problemu dla algorytmu
A5 wzrasta o lg 1000000 ≈ 19,932
AiSD - Wykład 2
Slajd 11
Zależność złożoności czasowej od danych
Przykład (wyszukiwanie sekwencyjne)
Problem: czy klucz x znajduje się w tablicy S, zawierającej n kluczy?
Dane wejściowe: całkowita liczba dodatnia n, tablica kluczy S indeksowana od
1 do n oraz klucz x.
Dane wyjściowe: location – lokalizacja klucza x w tablicy S (0, jeśli x nie
występuje w S)
int seqsearch ( int n,
const keytype S[],
keytype x)
{
int location = 1;
while (location <= n && S[location] != x)
location++;
if (location > n)
location = 0; operacja podstawowa
return location;
}
AiSD - Wykład 2
Slajd 12
Zależność złożoności czasowej od danych
Przypadek najgorszy: operacja podstawowa jest wykonywana n razy, co odpowiada
przypadkowi, gdy x jest ostatnim elementem w tablicy lub nie występuje w tablicy.
W(n) – złożoność czasową w najgorszym przypadku (worst-case time complexity)
definiujemy jako maksymalną liczbę wykonań operacji podstawowej przez algorytm dla
danych wejściowych o rozmiarze n.
W przykładzie seqsearch: W(n) = n
A(n) – złożoność czasową w średnim przypadku (average-case time complexity) definiujemy
jako średnią (wartość oczekiwaną) liczbę wykonań operacji podstawowej przez algorytm dla
danych wejściowych o rozmiarze n.
Proces określania A(n) to analiza złożoności czasowej w średnim przypadku (average-case
time complexity analysis)
Jaka jest złożoność czasowa w średnim przypadku algorytmu seqsearch?
AiSD - Wykład 2
Slajd 13
Analiza złożoności czasowej w średnim przypadku
Złożoność czasowa w średnim przypadku algorytmu seqsearch
Przypadek 1.
Zakładamy, że x na pewno występuje w S oraz, że wystąpienie x w S na każdej pozycji jest tak
samo prawdopodobne. Oznacza to, że dla 1  k  n prawdopodobieństwo tego, że x
występuje na pozycji k wynosi 1/n. Zatem złożoność czasowa w przypadku średnim
n
n
1 1
1 n(n  1) n  1
A(n)  k  
k 

n
n
n
2
2
k 1
k 1


Zgodnie z intuicją średnio przeszukiwana jest połowa tablicy.
Przypadek 2.
Zakładamy, że x występuje w S z prawdopodobieństwem p i że wystąpienie x w S na każdej
pozycji jest nadal tak samo prawdopodobne. Oznacza to, że dla 1  k  n
prawdopodobieństwo tego, że x występuje na pozycji k wynosi p/n. Prawdopodobieństwo
tego, że x nie występuje w tablicy S wynosi 1 – p. Zatem złożoność czasowa w przypadku
średnim
n
p
p n(n  1)
p p
A(n)  k   n(1  p)  
 n(1  p)  n 1   
n
n
2
 2 2
k 1

Dla p = ½: A(n) = 3n/4 + ¼ , tzn. średnio przeszukiwane jest około ¾ tablicy.
AiSD - Wykład 2
Slajd 14
Porównanie złożoności – przykład z egzaminu
AiSD - Wykład 2
Slajd 15
Porównanie złożoności – przykład z egzaminu
Niech A będzie algorytmem, którego złożoność wyraża się funkcją n2, gdzie n jest
rozmiarem zadania. Czas wykonania tego algorytmu (na pewnym komputerze) dla problemu
o rozmiarze 10 wynosi 1 sek.
a) Ile czasu zajmie wykonanie algorytmu dla problemu o rozmiarze 30?
Odp. 9 sek.
b) Jaki jest maksymalny rozmiar zadania, które można rozwiązać przy pomocy
tego algorytmu (na tym samym komputerze) w ciągu 196 sek ?
Odp. 140
c) Ile czasu zajmie wykonanie algorytmu dla danych o rozmiarze 40 na komputerze
2 razy szybszym?
Odp. 8 sek.
A  102 ~ 1 s
A  302 ~ x s
A  302  1 s = A  102  x
x = 302/ 102 s = 9 s
A  102 ~ 1 s
A  n2 ~ 196 s
A  102  196 s = A  n2  1 s
n2 = 102  142
n = 140
AiSD - Wykład 2
Slajd 16
Download