Rekurencja. Dla rozwiązania danego problemu, algorytm wywołuje sam siebie przy rozwiązywaniu podobnych podproblemów. Przykład: silnia: n! = n(n-1)!

Podobne dokumenty
Efektywna metoda sortowania sortowanie przez scalanie

Możliwości i ograniczenia komputerów

Strategia "dziel i zwyciężaj"

Sortowanie przez scalanie

Algorytmy i Struktury Danych

Sortowanie w czasie liniowym

Sortowanie bąbelkowe

Analiza algorytmów zadania podstawowe

Definicja. Ciąg wejściowy: Funkcja uporządkowująca: Sortowanie polega na: a 1, a 2,, a n-1, a n. f(a 1 ) f(a 2 ) f(a n )

Algorytmy i Struktury Danych.

Sortowanie - wybrane algorytmy

Wykład 5. Sortowanie w czasie liniowologarytmicznym

Sortowanie danych. Jolanta Bachan. Podstawy programowania

Podstawy algorytmiki i programowania - wykład 6 Sortowanie- algorytmy

Kolejka priorytetowa. Często rozważa się kolejki priorytetowe, w których poszukuje się elementu minimalnego zamiast maksymalnego.

Teoretyczne podstawy informatyki

ALGORYTMY I STRUKTURY DANYCH

Rekurencje. Jeśli algorytm zawiera wywołanie samego siebie, jego czas działania moŝe być określony rekurencją. Przykład: sortowanie przez scalanie:

Programowanie w VB Proste algorytmy sortowania

Sortowanie. Bartman Jacek Algorytmy i struktury

Algorytm selekcji Hoare a. Łukasz Miemus

Algorytmy i struktury danych Sortowanie IS/IO, WIMiIP

KOPCE KOLEJKI PRIORYTETOWE - PRZYPOMNIENIE KOPCE WYSOKOŚĆ KOPCA KOPCE I KOLEJKI PRIORYTETOWE PROJEKTOWANIE ALGORYTMÓW I METODY SZTUCZNEJ INTELIGENCJI

Podstawy Informatyki. Sprawność algorytmów

Podstawowe algorytmy i ich implementacje w C. Wykład 9

ZASADY PROGRAMOWANIA KOMPUTERÓW ZAP zima 2014/2015. Drzewa BST c.d., równoważenie drzew, kopce.

Algorytmy i Struktury Danych, 2. ćwiczenia

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

Matematyczne Podstawy Informatyki

Laboratoria nr 1. Sortowanie

TEORETYCZNE PODSTAWY INFORMATYKI

Algorytmy sortujące 1

Algorytmy sortujące i wyszukujące

Wykład 2. Poprawność algorytmów

Laboratoria nr 1. Sortowanie

Algorytmy i str ruktury danych. Metody algorytmiczne. Bartman Jacek

EGZAMIN - Wersja A. ALGORYTMY I STRUKTURY DANYCH Lisek89 opracowanie kartki od Pani dr E. Koszelew

Programowanie proceduralne INP001210WL rok akademicki 2017/18 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Zadanie projektowe 1: Struktury danych i złożoność obliczeniowa

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 9. Karol Tarnowski A-1 p.

Teoretyczne podstawy informatyki

Zaawansowane algorytmy i struktury danych

prowadzący dr ADRIAN HORZYK /~horzyk tel.: Konsultacje paw. D-13/325

Wstęp do programowania

Analiza algorytmów zadania podstawowe

REKURENCJA W JĘZYKU HASKELL. Autor: Walczak Michał

Wykład 3. Metoda dziel i zwyciężaj

INFORMATYKA SORTOWANIE DANYCH.

Wykład 3. Złożoność i realizowalność algorytmów Elementarne struktury danych: stosy, kolejki, listy

Jeszcze o algorytmach

KODY SYMBOLI. Kod Shannona-Fano. Algorytm S-F. Przykład S-F

Sortowanie. Kolejki priorytetowe i algorytm Heapsort Dynamiczny problem sortowania:

Wstęp do Programowania potok funkcyjny

Porównanie czasów działania algorytmów sortowania przez wstawianie i scalanie

Sortowanie. LABORKA Piotr Ciskowski

Algorytmy i struktury danych. Co dziś? Tytułem przypomnienia metoda dziel i zwyciężaj. Wykład VIII Elementarne techniki algorytmiczne

Programowanie Proceduralne

Podyplomowe Studium Programowania i Systemów Baz Danych

Problemy porządkowe zadania

Teoretyczne podstawy informatyki

liniowa - elementy następują jeden za drugim. Graficznie możemy przedstawić to tak:

Algorytmy i Struktury Danych.

Wyszukiwanie. Wyszukiwanie binarne

Algorytmy i Struktury Danych.

Wstęp do programowania

Rekurencja. Przygotowała: Agnieszka Reiter

Algorytmy i struktury danych

Algorytmy i Struktury Danych. (c) Marcin Sydow. Introduction. QuickSort. Sortowanie 2. Limit. CountSort. RadixSort. Summary

Struktury danych: stos, kolejka, lista, drzewo

5. Podstawowe algorytmy i ich cechy.

Struktury danych i złożoność obliczeniowa Wykład 2. Prof. dr hab. inż. Jan Magott

WYKŁAD 9. Algorytmy sortowania elementów zbioru (tablic) Programy: c4_1.c... c4_3.c. Tomasz Zieliński

Laboratorium nr 7 Sortowanie

Złożoność obliczeniowa algorytmu ilość zasobów komputera jakiej potrzebuje dany algorytm. Pojęcie to

Struktury Danych i Złożoność Obliczeniowa

Sortowanie zewnętrzne

Podyplomowe Studium Informatyki

Uwaga: Funkcja zamień(a[j],a[j+s]) zamienia miejscami wartości A[j] oraz A[j+s].

Porządek symetryczny: right(x)

Algorytmy i struktury danych Matematyka III sem.

Sortowanie przez wstawianie Insertion Sort

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Algorytmy i struktury danych Laboratorium Nr 4

5. Rekurencja. Przykłady

Zasady analizy algorytmów

wstęp do informatyki i programowania część testowa (25 pyt. / 60 min.)

funkcje rekurencyjne Wykład 12. Podstawy programowania (język C) Funkcje rekurencyjne (1) Funkcje rekurencyjne (2)

Drzewa poszukiwań binarnych

dodatkowe operacje dla kopca binarnego: typu min oraz typu max:

TEORETYCZNE PODSTAWY INFORMATYKI

Algorytmy i Struktury Danych. Co dziś? Drzewo decyzyjne. Wykład IV Sortowania cd. Elementarne struktury danych

Drzewa poszukiwań binarnych

[12] Metody projektowania algorytmów (dziel i rządź, programowanie dynamiczne i algorytmy zachłanne).

Algorytmika i programowanie. Wykład 2 inż. Barbara Fryc Wyższa Szkoła Informatyki i Zarządzania w Rzeszowie

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Algorytmy i struktury danych Laboratorium 7. 2 Drzewa poszukiwań binarnych

Rekurencja. Przykład. Rozważmy ciąg

Teoretyczne podstawy informatyki

Wykład 4: Iteracja, indukcja i rekurencja

operacje porównania, a jeśli jest to konieczne ze względu na złe uporządkowanie porównywanych liczb zmieniamy ich kolejność, czyli przestawiamy je.

ALGORYTMY Algorytm poprawny jednoznaczny szczegółowy uniwersalny skończoność efektywność (sprawność) zmiennych liniowy warunkowy iteracyjny

Programowanie dynamiczne

Transkrypt:

Rekurencja Dla rozwiązania danego problemu, algorytm wywołuje sam siebie przy rozwiązywaniu podobnych podproblemów. Przykład: silnia: n! = n(n-1)! Pseudokod: silnia(n): jeżeli n == 0 silnia = 1 w przeciwnym wypadku silnia = n * silnia(n-1) 1

Realizacja w C++ #include <iostream> using namespace std; double silnia(int n){ // funkcja typu double, aby zwiększyć zakres wyniku if (n == 0) return 1; else return n * silnia(n-1); } int main(){ int n; cin >> n; cout << silnia(n); } 2

Metoda dziel i zwyciężaj Dzielimy problem na kilka mniejszych podproblemów podobnych do problemu wyjściowego i rozwiązujemy je rekurencyjnie. Na koniec rozwiązania są łączone w celu utworzenia rozwiązania całego problemu. Dziel: Dzielimy problem na podproblemy. Zwyciężaj: Rozwiązujemy podproblemy rekurencyjnie, o ile nie są zbyt małego rozmiaru. W takim przypadku używamy metod bezpośrednich. Połącz: Łączymy rozwiązania podproblemów, aby otrzymać rozwiązanie całego problemu. 3

Metoda dziel i zwyciężaj dla sortowania przez scalanie: Dziel: Dzielimy n-elementowy ciąg na dwa podciągi, po n/2 elementów każdy. Zwyciężaj: Sortujemy otrzymane podciągi, używając rekurencyjnie sortowania przez scalanie. Połącz: Łączymy posortowane podciągi w jeden posortowany ciąg. 4

Procedura scalania Mamy dwa posortowane podciągi, chcemy je połączyć w jeden posortowany ciąg. W tym celu cyklicznie bierzemy mniejszą z liczb znajdujących się na początku obu podciągów i wstawiamy ją do ciągu posortowanego. Operacja ta odbywa się w czasie Θ(n). Pseudokod mergesort(t,d,g): // T-tablica, d,g - przedział jeżeli d<g s = (d+g) div 2 // dzielenie całkowite mergesort(t,d,s) mergesort(t,s+1,g) merge(t,d,s,g) Początkowe wywołanie procedury: mergesort(t,1,n) 5

Analiza algorytmu Dla tablicy jednoelementowej sortowanie działa oczywiście w czasie stałym Θ(1). Załóżmy, że n>1. Niech F(n) będzie czasem potrzebnym na rozwiązanie problemu o rozmiarze n. Dla sortowania przez scalanie: F(n) = Θ(1) + 2 F(n/2) + Θ(n) = 2 F(n/2) + Θ(n) = Θ(n log 2 n) (dziel) (zwyciężaj) (połącz) Przypomnienie: sortowanie przez wstawianie działa w czasie Θ(n 2 ). 6

Sortowanie szybkie quicksort Aby posortować tablicę, dzielimy ją na dwie części ze względu na wybrany element tablicy tak, żeby wszystkie elementy mniejsze od tego wybranego znalazły się po lewej stronie a większe po prawej. Następnie sortujemy rekurencyjnie każdą z części. Rekurencja kończy się, gdy przedział ma mniej niż 2 elementy. Szkielet kodu procedury sortującej: qsort(d,g): jeżeli fragment tablicy składa się z co najmniej 2 elementów, to: podziel elementy tablicy np. ze względu na wartość T[d] // w wyniku podziału wartość T[d] powinna znaleźć się // na właściwym miejscu s wewnątrz tablicy // oraz powinien spełniony być warunek: // T[d]... T[s-1] < T[s] <= T[s+1]... T[g] qsort(d, s-1) // posortuj dolną część tablicy qsort(s+1, g) // posortuj górną część tablicy Złożoność obliczeniowa: O(n log 2 n) 7

Przykładowy szkielet kodu rozdzielającego elementy tablicy: element_graniczny = T[d] // rozdzielamy względem pierwszego elementu srodek = d pętla od i = d+1 do i = g jeżeli element T[i] < element_graniczny srodek = srodek+1 zamień T[srodek] z T[i] zamień T[d] z T[srodek] Optymalizacja 1. Udoskonalenie metody znajdowania elementu środkowego, według którego rozdzielane są elementy tablicy (pytanie: kiedy przyjęta wyżej metoda rozdzielania względem pierwszego elementu tablicy jest mało efektywna?); 2. Poszukanie efektywniejszych metod rozdzielania elementów tablicy lub usprawnienie zaproponowanej powyżej; 3. Zoptymalizowanie kodu programu (np. rozwijanie kodu funkcji wewnątrz pętli zamiast jej wywołań); 4. Zastosowanie sortowania przez wstawianie dla wstępnie posortowanych metodą szybką małych fragmentów tablic. 8

Sortowanie przez kopcowanie (sortowanie stogowe) Kopiec (stóg, sterta), ang. heap Struktura danych reprezentacja zbioru elementów (np. liczb), mająca postać tzw. drzewa binarnego. Zastosowania: sortowanie przez kopcowanie porządkuje n-elementową tablicę w czasie Θ(n log n), kolejki priorytetowe: określanie operacji w zbiorze, służących do dodawania nowego elementu oraz usuwania elementu najmniejszego w czasie O(log n). Przykład kopca: 9

Własności kopca: 1. Uporządkowanie. Wartość każdego wierzchołka (ojca) jest nie większa niż wartości jego synów. Wniosek: najmniejszy element zbioru znajduje się w korzeniu drzewa. Nic jednak nie wiemy o wzajemnym uporządkowaniu lewego i prawego syna. 2. Kształt Synowie znajdują się na jednym lub więcej poziomach, a te na najniższym poziomie (liście) są przesunięte jak najbardziej w lewo. Wniosek: jeżeli drzewo zawiera n wierzchołków, to żaden z nich nie jest bardziej oddalony od korzenia niż o (log n) węzłów. Własności 1 i 2 są warunkami na tyle silnymi, żeby umożliwić szybkie odnalezienie elementu najmniejszego w zbiorze a jednocześnie umożliwiają szybką reorganizację struktury kopca po dodaniu lub usunięciu z niego elementu. 10

Realizacja kopca za pomocą tablicy: korzeń = 1 wartość(i) = x[i] lewysyn(i) = 2*i prawysyn(i) = 2*i+1 ojciec(i) = i div 2 Tablica x={12,20,15,29,23,17,22,35,40,26,51,19} Uwaga: w C/C++ tablice indeksujemy od zera a nie od jedynki! Ściśle: Tablica x[1...n] jest kopcem, jeżeli 2 i n x[i div 2] x[i]. Mówimy, że zachodzi kopiec(1,n). Fragment tablicy x[d...g] jest kopcem (czyli zachodzi kopiec(d,g)), jeżeli 2d i g x[i div 2] x[i]. 11

Procedury porządkowania kopca 1. Załóżmy, że x[1...n-1] jest kopcem i dodajmy nowy element x[n]. Prawdopodobnie x[1...n] nie jest już kopcem. Procedura przywracania własności kopca dla tablicy x[1...n]: Procedura dogóry(n): Przemieszczamy nowy element w górę drzewa tak daleko, jak powinien dotrzeć, zamieniając go po drodze z ojcem. Kończymy, gdy przemieszczany element stanie się większy lub równy ojcu. Uwaga: droga w górę drzewa to malejące indeksy w tablicy. Koszt operacji: O(log n). 12

2. Jeżeli w kopcu x[1...n] na pozycji x[1] przypiszemy nową wartość, to warunek kopiec(2,n) pozostanie prawdziwy. Procedura przywracania własności kopiec(1,n): Procedura nadół(n): Przemieszczamy element x[1] w dół drzewa (indeksy rosną!), zamieniając go po drodze z mniejszym synem, aż do chwili kiedy nie ma on już żadnych synów albo jest od nich mniejszy lub równy. Koszt operacji: O(log n). 13

Kolejki priorytetowe Kolejka umożliwia operację dodania i usunięcia elementu z pewnej ich sekwencji, w naszym przypadku struktury kopca. Początkowo kolejkę stanowi pusty zbiór S. Procedura wstaw(t) wstawia do kolejki nowy element t: wstaw(t): S = S {t} n++ dogóry(n) 14

Procedura usunmin() usuwa najmniejszy element zbioru: usunmin(): S = S \ {t} i t = min(s) S[1] = S[n] n-- nadół(n) Ostateczna postać algorytmu sortowania przez kopcowanie: pętla od i=1 do n wstaw(x[i]) // Utworzenie kopca pętla od i=1 do n usunmin() // Zdejmowanie z kopca el. najmn. Pesymistyczny i średni koszt operacji: Θ(n log n). 15

Sortowanie za pomocą porównań Porządek wyjściowy jest wyznaczany jedynie na podstawie wyników porównań między elementami. sortowanie przez wstawianie sortowanie przez scalanie sortowanie przez kopcowanie sortowanie szybkie (quicksort) Dolne ograniczenie sortowania za pomocą porównań Twierdzenie: Dolne ograniczenie sortowania n elementów za pomocą porównań, wynosi Ω(n log n). Wniosek: Sortowanie przez kopcowanie, scalanie oraz quicksort są asymptotycznie optymalnymi algorytmami sortującymi za pomocą porównań. 16

Sortowanie przez zliczanie Założenie: każdy z n sortowanych elementów jest liczbą całkowitą z przedziału od 1 do k dla pewnego ustalonego k. Idea: dla każdego elementu wejściowego x należy wyznaczyć, ile elementów jest mniejszych od x. Znając te liczbę, znamy jednocześnie dokładną pozycję liczby x w ciągu posortowanym. Przykład: jeżeli od x jest mniejszych 17 elementów, to x powinien się znaleźć na miejscu 18 w ciągu posortowanym (przy założeniu, że elementy nie mogą się powtarzać). 17

Implementacja Tablica A elementy wejściowe; B elementy wyjściowe (posortowane); C dane pomocnicze Counting-Sort(A, B, k): pętla od i=1 do k C[i]=0 pętla od j=1 do n C[A[j]] = C[A[j]]+1 // C[i] zawiera teraz liczbę elementów równych i pętla od i=2 do k C[i] = C[i] + C[i-1] // C[i] zawiera liczbę elementów mniejszych lub równych i pętla od i=n do 1 B[C[A[i]]] = A[i] C[A[i]] = C[A[i]]-1 Pętla 1: inicjalizacja. Pętla 2: zliczenie elementów równych indeksowi tablicy. Pętla 3: zliczenie elementów mniejszych lub równych indeksowi tablicy. Pętla 4: zapisanie wyników do wyjściowej tablicy; zmniejszenie zawartości tablicy C w celu uniknięcia konfliktu przy powtarzających się liczbach. 18

Ilustracja działania procedury a) stan po wykonaniu drugiej pętli, b) stan po wykonaniu 3 pętli, c) d) e) stan po wykonaniu odpowiednio 1, 2, 3 iteracji w czwartej pętli, f) ostateczna zawartość tablicy wyjściowej. 19

Czas działania W algorytmie nie występują porównania elementów, zatem nie ma tu zastosowania twierdzenie dotyczące dolnego ograniczenia dla metod sortowania przez porównanie. Pierwsza pętla: Druga pętla: Trzecia pętla: Czwarta pętla: k wykonań, n wykonań, k wykonań, n wykonań, Razem liczba operacji: O(n+k). W praktyce najczęściej k=o(n), zatem czas działania procedury wynosi w takim przypadku O(n) mniej niż czas Ω(n log n). Algorytm jest stabilny (nie zmienia kolejności takich samych liczb w tablicy wynikowej). 20

Sortowanie pozycyjne polega na sortowaniu liczby według najmniej znaczącej cyfry, proces jest powtarzany dla wszystkich cyfr 329 720 720 329 457 355 329 355 657 436 436 436 839 457 839 457 436 657 355 657 720 329 457 720 355 839 657 839 dla pewnych długości elementów do posortowania oraz ich liczby, algorytm działa w czasie liniowym (oczywiście przy odpowiednim wyborze algorytmu sortującego wg kolejnej cyfry najczęściej stosuje się zliczanie) 21

Sortowanie kubełkowe polega na utworzeniu kubełków pojemników, w których są przechowywane liczby przeznaczone do posortowania kubełki tworzymy poprzez podzielenie przedziału, do jakiego należą sortowane liczby na szereg podprzedziałów liczby wrzucamy do odpowiedniego kubełka, sortujemy w każdym z nich i wypisujemy od kubełka pierwszego do ostatniego a) tablica do posortowania b) 10 kubełków i liczby, które do nich należą; liczby (po posortowaniu np. przez wstawianie) są wyświetlane od kubełka o najniższym numerze (B[0]) do tego o najwyższym. Operacja ta wykonywana jest w czasie liniowym O(n). 22