Strategia "dziel i zwyciężaj"

Podobne dokumenty
Algorytmy i Struktury Danych.

Sortowanie przez scalanie

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

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 )

Sortowanie. LABORKA Piotr Ciskowski

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

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

Efektywna metoda sortowania sortowanie przez scalanie

Analiza algorytmów zadania podstawowe

Sortowanie danych. Jolanta Bachan. Podstawy programowania

Wstęp do programowania

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

Algorytmy sortujące i wyszukujące

Teoretyczne podstawy informatyki

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

Programowanie w VB Proste algorytmy sortowania

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

TEORETYCZNE PODSTAWY INFORMATYKI

Matematyczne Podstawy Informatyki

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

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

Algorytmy i str ruktury danych. Metody algorytmiczne. Bartman Jacek

Wstęp do programowania. Dziel i rządź. Piotr Chrząstowski-Wachtel

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

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

np. dla p=1 mamy T1(N) N/2 średni czas chybionego wyszukiwania z prawdopodobieństwem q:

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

Rekurencja. Rekurencja zwana także rekursją jest jedną z najważniejszych metod konstruowania rozwiązań i algorytmów.

Algorytmy i Struktury Danych, 2. ćwiczenia

Algorytm selekcji Hoare a. Łukasz Miemus

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

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

Zaawansowane algorytmy i struktury danych

Algorytmy sortujące 1

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

Problemy porządkowe zadania

Podstawy programowania 2. Temat: Drzewa binarne. Przygotował: mgr inż. Tomasz Michno

Techniki konstruowania algorytmów. Metoda dziel i zwyciężaj

TEORETYCZNE PODSTAWY INFORMATYKI

TEORETYCZNE PODSTAWY INFORMATYKI

Sortowanie - wybrane algorytmy

Wstęp do programowania

Podstawy algorytmiki i programowania - wykład 3 Funkcje rekurencyjne Wyszukiwanie liniowe i binarne w tablicy

Programowanie dynamiczne

Wykład 5. Sortowanie w czasie liniowologarytmicznym

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

Programowanie Równoległe i Rozproszone. Algorytm Kung a. Algorytm Kung a. Programowanie Równoległe i Rozproszone Wykład 8. Przygotował: Lucjan Stapp

Metoda "DZIEL i ZWYCIĘŻAJ"

Metodyki i Techniki Programowania 2

Zaawansowane algorytmy i struktury danych

Analiza algorytmów zadania podstawowe

Wykład 4: Iteracja, indukcja i rekurencja

Teoretyczne podstawy informatyki

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

Sortowanie przez wstawianie Insertion Sort

Struktury Danych i Złożoność Obliczeniowa

Algorytmy i Struktury Danych

Programowanie dynamiczne cz. 2

Rekurencja/rekursja. Iluzja istnienia wielu kopii tego samego algorytmu (aktywacji) Tylko jedna aktywacja jest aktywna w danej chwili

Wykład 1_2 Algorytmy sortowania tablic Sortowanie bąbelkowe

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

E S - uniwersum struktury stosu

Informatyka A. Algorytmy

Programowanie dynamiczne i algorytmy zachłanne

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

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

Temat 7. Najlżejsze i najcięższe algorytmy sortowania

PRÓBNY EGZAMIN MATURALNY Z INFORMATYKI

Wstęp do programowania

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

Algorytmy i Struktury Danych

Algorytmy i złożoność obliczeniowa. Wojciech Horzelski

Wybrane algorytmy tablicowe

Jeśli czas działania algorytmu zależy nie tylko od rozmiaru danych wejściowych i przyjmuje różne wartości dla różnych danych o tym samym rozmiarze,

Laboratorium nr 7 Sortowanie

Algorytmy komputerowe. dr inŝ. Jarosław Forenc

Programowanie Proceduralne

Wykład 2. Poprawność algorytmów

Algorytmy i Struktury Danych. (c) Marcin Sydow. Sortowanie Selection Sort Insertion Sort Merge Sort. Sortowanie 1. Listy dowiązaniowe.

Wstęp do programowania

Wstęp do programowania

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 9 Rekurencja

5. Podstawowe algorytmy i ich cechy.

Rekurencja (rekursja)

1.1. Uzupełnij poniższą tabelę: i wynik(i)

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

Sortowanie zewnętrzne

EGZAMIN MATURALNY Z INFORMATYKI. 10 maja 2017 POZIOM ROZSZERZONY. Godzina rozpoczęcia: 14:00 CZĘŚĆ I

Równoleg le sortowanie przez scalanie

Algorytmy i Struktury Danych, 2. ćwiczenia

Rekurencja. Rekurencja zwana także rekursją jest jedną z najważniejszych metod konstruowania rozwiązań i algorytmów.

Algorytmy sortujące. sortowanie kubełkowe, sortowanie grzebieniowe

Sortowanie bąbelkowe

Podstawy Informatyki. Sprawność algorytmów

Złożoność obliczeniowa zadania, zestaw 2

Sortowanie. Bartman Jacek Algorytmy i struktury

Wstęp do programowania

Poprawność semantyczna

Programowanie dynamiczne

PDF stworzony przez wersję demonstracyjną pdffactory Pro Program 15

Transkrypt:

Strategia "dziel i zwyciężaj" W tej metodzie problem dzielony jest na kilka mniejszych podproblemów podobnych do początkowego problemu. Problemy te rozwiązywane są rekurencyjnie, a następnie rozwiązania wszystkich podproblemów są łączone w celu utworzenia rozwiązania całego problemu. W strategii dziel i zwyciężaj każdy poziom rekurencji składa się z następujących trzech etapów: Dziel: Dzielimy problem na podproblemy. Zwyciężaj: Rozwiązujemy podproblemy rekurencyjnie, chyba że są one małego rozmiaru i już nie wymagają zastosowania rekursji używamy wtedy bezpośrednich metod. Połącz: Łączymy rozwiązania podproblemów, aby otrzymać rozwiązanie całego problemu. Wyszukiwanie binarne Wyszukiwanie binarne znajduje element x w posortowanej (w porządku niemalejącym) tablicy poprzez porównanie w pierwszej kolejności x ze środkowym elementem tablicy. Jeżeli są one sobie równe to algorytm kończy działanie. Jeżeli nie, to tablica jest dzielona na dwie podtablice, z których jedna zawiera wszystkie elementy znajdujące się na lewo od elementu środkowego, a druga wszystkie elementy znajdujące się na prawo od tego elementu. Jeżeli x jest mniejsze od elementu środkowego, to ta sama procedura zostaje zastosowana względem lewej podtablicy. W przeciwnym wypadku względem prawej podtablicy. Oznacza to, że x jest porównywane ze środkowym elementem odpowiedniej podtablicy. Jeżeli są sobie równe to algorytm kończy działanie. Jeżeli nie, podtablica jest dzielona na dwie części. Procedura jest powtarzana do momentu znalezienia x lub wykazania, że x nie występuje w tablicy. Kolejne etapy postępowanie: Jeżeli x jest równe elementowi środkowemu, kończymy. W przeciwnym razie: Dzielimy tablicę na dwie podtablice o rozmiarze mniej więcej dwa razy mniejszym od oryginalnej. Jeżeli x jest mniejsze od elementu środkowego, wybieramy lewą podtablicę. Jeżeli x jest większe od elementu środkowego, wybieramy prawą podtablicę. Zwyciężamy (rozwiązujemy) podtablicę poprzez określenie, czy x do niej należy. O ile podtablica nie posiada dostatecznie małych rozmiarów, należy wykorzystać rekurencję. Otrzymujemy rozwiązanie problemu tablicy na podstawie rozwiązania problemu podtablicy.

Przykład Wyszukiwanie binarne dla x=18 oraz poniższej 13 elementowej tablicy liczb. 10 12 13 14 18 20 25 27 30 35 40 45 47 Wybieramy lewą podtablicę, ponieważ x<25 Porównujemy x z 25 10 12 13 14 18 20 Porównujemy x z 13 Wybieramy prawą podtablicę, ponieważ x>13 14 18 20 Porównujemy x z 18 Określamy, że x występuje, ponieważ x=18 int binarne( int tab[],int poczatek, int koniec, int x){ if (poczatek > koniec) return -1; else { int srodek=(poczatek+koniec)/2; if (x == tab[srodek]) return srodek; else if (x < tab[srodek]) return binarne(tab,0,srodek-1,x); else return binarne(tab,srodek+1,koniec,x);

Porównanie wyszukiwania sekwencyjnego z wyszukiwaniem binarnym Jeżeli tablica zawiera 32 elementy i x nie występuje w tablicy, to algorytm sekwencyjny porówna x ze wszystkimi elementami zanim określi, że element ten nie występuje w tablicy. Zatem wyszukiwanie sekwencyjne dokonuje n porównań w celu określenia, że x nie występuje w tablicy o rozmiarze n. Oznacza to, że jeżeli x występuje w tablicy, liczba porównań jest nie większa niż n. Natomiast algorytm wyszukiwania binarnego w tym przypadku wykona tylko 6 porównań. tab[16] tab[24] tab[28] tab[30] tab[31] tab[32] Zauważmy, że. Zatem jest to maksymalna liczba porównań wykonywanych przez algorytm wyszukiwania binarnego. Załóżmy, że podwojono rozmiar tablicy tak, że zawiera teraz 64 elementy. Algorytm wykonuje tylko o jedno porównanie więcej, ponieważ pierwsze porównanie podzieli tablicę na pół dając w rezultacie podtablicę o rozmiarze 32. Zatem jeśli x jest większe od wszystkich elementów występujących w tablicy o rozmiarze 64 algorytm wykona 7 porównań,. Ogólnie za każdym razem gdy podwoimy rozmiar tablicy dodajemy tylko jedno porównanie. Dlatego, jeśli n jest potęgą liczby 2, a x jest większe od wszystkich elementów występujących w tablic o rozmiarze n to liczba porównań wykonywanych przez algorytm wynosi. rozmiar tablicy algorytm sekwencyjny algorytm binarny 128 128 8 1024 1024 11 1048576 1048576 21 4294967296 4294967296 33 Zatem T(n)= Jeśli T(n) jest potęgą liczby 2 to T(n)= T(n)=. +1. Natomiast jeśli n nie jest potęgą liczby 2 to Sortowanie przez scalanie W tym algorytmie również stosujemy metodę dziel i zwyciężaj. 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.

Przykład 12 9 11 6 9 12 3 9 12 7 14 6 11 2 6 11 10 5 3 7 9 12 14 2 5 6 10 11 2 3 5 6 7 9 10 11 12 14 Podstawową operacją algorytmu jest scalanie dwóch posortowanych ciągów dokonywane w kroku "połącz". W celu dokonania scalania korzysta się z pomocniczej funkcji void Scalaj (int tab[], int początek, int srodek, int koniec), która łączy dwa posortowane ciągi zgodnie z zasadą: Dopóki jeden z ciągów nie jest pusty to porównuj pierwsze elementy obu ciągów i mniejszy wstaw do ciągu wynikowego. Pozostałe elementy niepustego ciągu dołącz do ciągu wynikowego.

Przykład scalenia dwóch tablic T1 i T2 do jednej tablicy Tab. T1 T2 Tab 10 12 20 27 13 15 22 25 10 10 12 20 27 13 15 22 25 10 12 10 12 20 27 13 15 22 25 10 12 13 10 12 20 27 13 15 22 25 10 12 15 10 12 20 27 13 15 22 25 10 12 15 20 10 12 20 27 13 15 22 25 10 12 15 20 22 10 12 20 27 13 15 22 25 10 12 15 20 22 25 10 12 20 27 13 15 22 25 10 12 15 20 22 25 27 Z funkcji Scalaj korzysta się w algorytmie sortowania przez scalanie. void merge_sort(int tablica[], int poczatek, int koniec){ int srodek; if (poczatek < koniec){ srodek = (poczatek + koniec) / 2; merge_sort(tablica, poczatek, srodek); merge_sort(tablica, srodek + 1, koniec); Scalaj(tablica, poczatek, srodek, koniec); Wyznaczmy teraz złożoność obliczeniową algorytmu czyli T(n). Jeżeli tablica jest jednoelementowa to jest spełniony warunek końcowy i nie jest wykonywane żadne scalenie. Zatem T(1)=0 (0 operacji). Gdy ciąg nie jest jednoelementowy: dziel - wyznaczenie środka - O(1), zwyciężaj - rozwiązanie dwóch problemów o rozmiarze -2T, scal - liczba porównań zależy od wartości elementów - Ɵ(n), Zatem

Sortowanie szybkie - quicksort Zaimplementuj algorytm sortowania szybkiego QuickSort oraz określ jego złożoność obliczeniową. Sortowanie szybkie przypomina sortowanie przez scalanie o tyle, że cały proces polega na dzieleniu tablicy na dwie części, a następnie rekurencyjnym sortowaniu każdej z nich. Jednak w przypadku sortowaniu szybkiego tablica jest dzielona przez umieszczenie wszystkich elementów mniejszych niż pewien element odniesienia przed tym elementem oraz wszystkich elementów które są od niego większe za nim. Elementem odniesienia (ang. pivot ) może być dowolny element i dla wygody można użyć elementu pierwszego. Przykład (podtablice są umieszczone w ramkach, natomiast punkty odniesienia są bez ramek) 15 22 13 27 12 10 20 25 15 10 13 12 22 27 20 25 10 13 12 15 20 22 27 25 10 12 13 Algorytm sortowania szybkiego 15 20 22 25 27 void quicksort(int tab[],int poczatek, int koniec){ int punkt_podzialu; if(poczatek<koniec){ podzial(tab,poczatek,koniec,punkt_podzialu); quicksort(tab,poczatek,punkt_podzialu-1); quicksort(tab,punkt_podzialu+1,koniec); return;

W powyższym algorytmie występuje funkcja podzial, która dokonuje podziału tablicy. Funkcja ta działa poprzez sprawdzanie każdego elementu w tablicy po kolei. Kiedy zostanie znaleziony element o wartości mniejszej niż element odniesienia, zostaje on przeniesiony na lewą stronę tablicy. Poniższa tabela pokazuje sposób działania tej funkcji (elementy porównywane są pogrubione, natomiast elementy zamienione są podkreślone) i j tab[0] tab[1] tab[2] tab[3] tab[4] tab[5] tab[6] tab[7] - - 15 22 13 27 12 10 20 25 1 0 15 22 13 27 12 10 20 25 2 1 15 22 13 27 12 10 20 25 3 1 15 13 22 27 12 10 20 25 4 2 15 13 22 27 12 10 20 25 5 3 15 13 12 27 22 10 20 25 6 3 15 13 12 10 22 27 20 25 7 3 15 13 12 10 22 27 20 25-3 13 12 15 22 27 20 25