Wojciech Horzelski - kolos.math.uni.lodz.plkolos.math.uni.lodz.pl/~archive/Algorytmy i struktury...
Transcript of Wojciech Horzelski - kolos.math.uni.lodz.plkolos.math.uni.lodz.pl/~archive/Algorytmy i struktury...
1
Zaawansowane algorytmy
Wojciech Horzelski
2
Organizacja
Wykład: poniedziałek 815-10 – Aula
Ćwiczenia: …
Każdy student musi realizować projekty (treść podawana na wykładzie) :
– Ilość projektów : 5-7
– Na realizację każdego projektu studenci będą mieli 2 tygodnie
– Ocena projektów: od 0 do 10 punktów (0 –brak projektu, 7 – projekt poprawnie
wykonany, bez zastrzeżeń, 10 – wybitne rozwiązanie)
– Oddanie projektu tydzień po terminie powoduje utratę 2 punktów (później nie będzie
już oceniany)
Zaliczenie ćwiczeń:
– Minimalna ilość punktów na zaliczenie: (ilość projektów-1) * 5+2
– Dokładna punktacja dla poszczególnych ocen – później (zależna od ilości projektów)
Egzamin – pisemny ( termin „zerowy” - ?)
3
Tematyka wykładu
Wprowadzenie (przypomnienie podstaw)
Drzewa binarne i drzewa BST
Drzewa AVL i 2-3-4
Drzewa zbalansowane (czerwono-czarne)
Tablice z haszowaniem
Kompresja danych
Wyszukiwanie wzorca w tekście
Algorytmy grafowe:
– Przeszukiwanie (wszerz i w głąb)
– Drzewo rozpinające
– Znajdowanie najlepszej drogi
– Znajdowanie najkrótszych ścieżek pomiędzy wszystkimi wierzchołkami
NP - zupełność
4
Literatura
T. Cormen, Ch. Lieserson, R. Rivest, Wprowadzenie do Algorytmów, WNT, 1997
R. Sedgewick, Algorytmy w C++, RM, 1999
R. Sedgewick, P. Rzechonek, Algorytmy w C++. Grafy , RM, 2003
5
O co w tym wszystkim chodzi?
Rozwiązywanie problemów:
– Układanie planu zajęć
– Balansowanie własnego budżet
– Symulacja lotu samolotem
– Prognoza pogody
Dla rozwiązania problemów potrzebujemy procedur, recept, przepisów –
inaczej mówiąc algorytmów
6
Historia
Nazwa pochodzi od perskiego matematyka Muhammeda ibn Musa
Alchwarizmiego (w łacińskiej wersji Algorismus) – IX w n.e.
Pierwszy dobrze opisany algorytm – algorytm Euklidesa znajdowania
największego wspólnego podzielnika, 400-300 p.n.e.
XIX w. – Charles Babbage, Ada Lovelace.
XX w. – Alan Turing, Alonzo Church, John von Neumann
7
Struktury danych i algorytmy
Algorytm – metoda, zestaw działań (instrukcji) potrzebnych do
rozwiązania problemu
Program – implementacja algorytmu w jakimś języku programowania
Struktura danych – organizacja danych niezbędna dla rozwiązania
problemu (metody dostępu etc.)
8
Ogólne spojrzenie
Cele algorytmiczne:- poprawność, - efektywność,
Cele implementacji:- zwięzłość- możliwość powtórnego wykorzystania
Wykorzystanie komputera:
Projektowanie programów (algorytmy, struktury danych)
Pisanie programów (kodowanie)
Weryfikacja programów (testowanie)
9
Problemy algorytmiczne
Ilość instancji danych spełniających
specyfikację wejścia może być nieskończona, np.:
posortowana niemalejąco sekwencja liczb naturalnych, o skończonej długości:
1, 20, 908, 909, 100000, 1000000000.
3, 44, 211, 222, 433.
3.
…
Specyfikacja wejścia
?Specyfikacja wyjścia, jako funkcji wejścia
10
Rozwiązanie problemu
– Algorytm opisuje działania, które mają zostać przeprowadzone na danych
– Może istnieć wiele algorytmów rozwiązujących ten sam problem
Instancja wejściowa (dane), odpowiadająca specyfikacji
algorytm Wyniki odpowiadające danym wejściowym
11
Definicja algorytmu
Algorytmem nazywamy skończoną sekwencję jednoznacznych
instrukcji pozwalających na rozwiązanie problemu, tj. na
uzyskanie pożądanego wyjścia dla każdego legalnego wejścia.
Własności algorytmów:
– określoność
– skończoność
– poprawność
– ogólność
– dokładność
12
Pseudokod
Zbliżony do Ady, C, Javy czy innego języka programowania:
– struktury sterujące (if … then … else, pętle while i for)
– przypisanie (←)
– dostęp do elementów tablicy: A[i]
– dla typów złożonych (record lub object) dostęp do pól: A.b
– zmienna reprezentująca tablicę czy obiekt jest traktowana jak wskaźnik do
tej struktury (podobnie, jak w C).
13
Warunki początkowe i końcowe (precondition, postcondition)
Ważne jest sprecyzowanie warunków początkowego i końcowego dla
algorytmu:
– INPUT: określenie jakie dane algorytm powinien dostać na wejściu
– OUTPUT: określenie co algorytm powinien wyprodukować. Powinna zostać
przewidziana obsługa specjalnych przypadków danych wejściowych
14
Sortowanie przez wstawianie (Insertion Sort)
A1 nj
3 6 84 9 7 2 5 1
i
Strategia
• zaczynamy od “pustej ręki”
• wkładamy kartę we właściwe
miejsce kart poprzednio już
posortowane
• kontynuujemy takie postępowanie
aż wszystkie karty zostaną
wstawione
Strategia
• zaczynamy od “pustej ręki”
• wkładamy kartę we właściwe
miejsce kart poprzednio już
posortowane
• kontynuujemy takie postępowanie
aż wszystkie karty zostaną
wstawione
INPUT: A[1..n] – tablica liczb całkowitych
OUTPUT: permutacja A taka, że A[1]≤A[2]≤ …≤A[n]
for j←2 to n
do key←A[j]
wstaw A[j] do posortowanej
sekwencji A[1..j-1]i←j-1
while i>0 and A[i]>key
do A[i+1]←A[i]
i--
A[i+1]←key
INPUT: A[1..n] – tablica liczb całkowitych
OUTPUT: permutacja A taka, że A[1]≤A[2]≤ …≤A[n]
for j←2 to n
do key←A[j]
wstaw A[j] do posortowanej
sekwencji A[1..j-1]i←j-1
while i>0 and A[i]>key
do A[i+1]←A[i]
i--
A[i+1]←key
15
Analiza algorytmów
Efektywność:
– Czas działania
– Wykorzystanie pamięci
Efektywność jako funkcja rozmiaru wejścia:
– Ilość danych wejściowych (liczb, punktów, itp.)
– Ilość bitów w danych wejściowych
16
Analiza sortowania przez wstawianie
for j←2 to n
do key←A[j]
wstaw A[j] do posortowanej
sekwencji A[1..j-1]i←j-1
while i>0 and A[i]>key
do A[i+1]←A[i]
i--
A[i+1]:=key
czas
c1
c2
?
c3
c4
c5
c6
c7
ile razy
n
n-1
n-1
n-1
n-1
2
n
jjt
=∑2( 1)
n
jjt
=−∑
2( 1)
n
jjt
=−∑
Określany czas wykonania jako funkcję rozmiaru wejścia
17
Przypadki: najlepszy/najgorszy/średni
Najlepszy przypadek: elementy już są posortowane →→→→ tj=1, czas wykonania
liniowy (Cn).
Najgorszy przypadek: elementy posortowane nierosnąco (odwrotnie
posortowane) →→→→ tj=j, czas wykonania kwadratowy (Cn2)
Przypadek „średni” : tj=j/2, czas wykonania kwadratowy (Cn2)
18
Przypadki: najlepszy/najgorszy/średni
– Dla ustalonego n czas wykonania dla poszczególnych instancji:
1n
2n
3n
4n
5n
6n
19
Przypadki: najlepszy/najgorszy/średni
– Dla różnych n:
1n
2n
3n
4n
5n
6n
Rozmiar wejścia
Cza
s dzi
ałan
ia
1 2 3 4 5 6 7 8 9 10 11 12 …..
najlepszy przypadek
„średni” przypadek
najgorszy przypadek
20
Przypadki: najlepszy/najgorszy/średni
Analizę najgorszego przypadku stosuje się zwykle wtedy, kiedy czas działania
jest czynnikiem krytycznym (kontrola lotów, sterowanie podawaniem leków itp.)
Dla pewnych zadań „najgorsze” przypadki mogą występować dość często.
Określenie przypadku „średniego” (analiza probabilistyczna) jest często bardzo
kłopotliwe
21
Poprawność – praktyczna i całkowita
Praktyczna
Poprawne dane algorytm Wynik
Jeśli ten punkt został
osiągnięty to otrzymaliśmy poprawny wynik
Całkowita poprawność
Poprawne dane algorytm Wynik
i otrzymaliśmy poprawny wynikTen punkt został
osiągnięty
22
Dowodzenie
W celu dowiedzenia poprawności algorytmu wiążemy ze specyficznymi
miejscami algorytmu stwierdzenia (dotyczące stanu wykonania).
– np., A[1], …, A[k] są posortowane niemalejąco
Warunki początkowe (Precondition) – stwierdzenia, których prawdziwość
zakładamy przed wykonaniem algorytmu lub podprogramu (INPUT)
Warunki końcowe (Postcondition) – stwierdzenia, które muszą być
prawdziwe po wykonaniu algorytmu lub podprogramu (OUTPUT)
23
Niezmienniki pętli
Niezmienniki – stwierdzenia prawdziwe za każdym razem kiedy osiągany
jest pewien punkt algorytmu (może to zdarzać się wielokrotnie w czasie
wykonania algorytmu, np. w pętli)
Dla niezmienników pętli należy pokazać :
– Inicjalizację – prawdziwość przed pierwszą iteracją
– Zachowanie – jeśli stwierdzenie jest prawdziwe przed iteracją to
pozostaje prawdziwe przed następną iteracją
– Zakończenie – kiedy pętla kończy działanie niezmiennik daje własność
przydatną do wykazania poprawności algorytmu
24
Przykład: sortowanie przez wstawianie
niezmiennik: na początku
każdego wykonania pętli for,
A[1…j-1] składa się z
posortowanych elementów
for j=2 to length(A)
do key ← A[j]
i ← j-1
while i>0 and A[i]>key
do A[i+1] ← A[i]
i--
A[i+1] ← key
for j=2 to length(A)
do key ← A[j]
i ← j-1
while i>0 and A[i]>key
do A[i+1] ← A[i]
i--
A[i+1] ← key
inicjalizacja: j = 2, niezmiennik jest trywialny, A[1] jest zawsze posortowana
zachowanie: wewnątrz pętli while przestawia się elementy A[j-1], A[j-2], …,
A[j-k] o jedną pozycję bez zmiany ich kolejności. Element A[j] jest wstawiany na k-tą pozycję, tak że A[k-1]≤A[k]≤A[k+1]. Stąd A[1..j-1] jest posortowane.
zakończenie: kiedy pętla się kończy (j=n+1) niezmiennik oznacza, że cała tablica została posortowana.
25
Notacje asymptotyczne
Cel: uproszczenie analizy czasy wykonania, zaniedbywanie „szczegółów”,
które mogą wynikać ze specyficznej implementacji czy sprzętu
– “zaokrąglanie” dla liczb: 1,000,001 ≈ 1,000,000
– “zaokrąglanie” dla funkcji: 3n2 ≈ n2
Główna idea: jak zwiększa się czas wykonania algorytmu wraz ze
wzrostem rozmiaru wejścia (w granicy).
– Algorytm asymptotycznie lepszy będzie bardziej efektywny dla prawie
wszystkich rozmiarów wejść (z wyjątkiem być może „małych”)
26
Notacje asymptotyczne
Notacja O (duże O)
– Asymptotyczne ograniczenie górne
– f(n) = O(g(n)), jeżeli istnieje stała c i n0,
takie, że f(n) ≤≤≤≤ c g(n) dla n ≥ n0
– f(n) i g(n) są nieujemnymi funkcjami
całkowitymi
Korzysta się z niej przy analizie
najgorszego przypadku.
)(nf( )c g n⋅
0n Rozmiar wejścia
Cza
s d
ział
ania
27
Notacja ΩΩΩΩ (duża ΩΩΩΩ)
– Asymptotyczne ograniczenie dolne
– f(n) = Ω(g(n)) jeśli istnieje stała c i n0,
takie, że c g(n) ≤≤≤≤ f(n) dla n ≥ n0
Opisuje najlepsze możliwe zachowanie się
algorytmu
Rozmiar wejścia
Cza
s d
ział
ania )(nf
( )c g n⋅
0n
Notacje asymptotyczne
28
Notacje asymptotyczne
Prosta zasada: odrzucamy mniej istotne dla czasu składniki i czynniki
stałe.
– 50 n log n jest O(n log n)
– 7n - 3 jest O(n)
– 8n2 log n + 5n2 + n jest O(n2 log n)
O jest ograniczeniem górnym więc np. (50 n log n) jest typu O(n5), ale
interesuje nas najlepsze możliwe oszacowanie – w tym przypadku jest to
O(n log n)
29
Notacja ΘΘΘΘ ((((duża ΘΘΘΘ )
– Dokładne oszacowanie asymptotyczne
– f(n) = Θ(g(n)) jeżeli istnieją stałe c1, c2, i
n0, takie, że c1 g(n) ≤≤≤≤ f(n) ≤≤≤≤ c2 g(n) dla
n ≥ n0
f(n) = ΘΘΘΘ(g(n)) wtedy i tylko wtedy,
gdy f(n) = ΟΟΟΟ(g(n)) i f(n) = ΩΩΩΩ(g(n))
Rozmiar wejścia
Cza
s d
ział
ania )(nf
0n
Notacje asymptotyczne
)(ngc ⋅2
)(ngc ⋅1
30
Notacje asymptotyczne
Analogie do zależności pomiędzy liczbami:
– f(n) = O(g(n)) ≅ f ≤≤≤≤ g
– f(n) = Ω(g(n)) ≅ f ≥ g
– f(n) = Θ(g(n)) ≅ f = = = = g
– f(n) = o(g(n)) ≅ f < < < < g
– f(n) = ω(g(n)) ≅ f > > > > g
Zwykle zapisujemy: f(n) = O(g(n)) , co formalnie powinno być rozumiane
jako f(n) ∈∈∈∈O(g(n))
31
Porównanie czasów wykonania
3125192n
2448831n4
4242654777072n2
7826087166666409620n log n
90000001500002500400n
1 godzina1 minuta1 sekunda
Maksymalny rozmiar problemu (n)