pojęcia podstawowe. złożonośd czasowa algorytmów....

39
2010-10-13 1 Pojęcia podstawowe. Złożonośd czasowa algorytmów. Rekurencja Algorytmy i struktury danych Wykład 1. Rok akademicki: 2010/2011 2 Ramowy plan wykładów Pojęcie podstawowe. Poprawnośd i złożonośd algorytmów Rekurencja Algorytmy tablicowe Zbiory Tablice asocjacyjne Struktury listowe Drzewa Grafy Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

Upload: vuliem

Post on 28-Feb-2019

217 views

Category:

Documents


0 download

TRANSCRIPT

2010-10-13

1

Pojęcia podstawowe. Złożonośd czasowa algorytmów.

Rekurencja

Algorytmy i struktury danych

Wykład 1.

Rok akademicki: 2010/2011

2

Ramowy plan wykładów

• Pojęcie podstawowe.

• Poprawnośd i złożonośd algorytmów

• Rekurencja

• Algorytmy tablicowe

• Zbiory

• Tablice asocjacyjne

• Struktury listowe

• Drzewa

• Grafy

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

2

3

Literatura

• Cormen T., Leiserson C., Rivest R., Stein C., Wprowadzenie do algorytmów, Wydawnictwo Naukowo-Techniczne, 2004

• Lafore R., Java. Algorytmy i struktury danych, Helion, 2004

• Koffman E., Wolfgang P., Struktury danych i techniki obiektowe na przykładzie Javy 5.0, Helion, 2006

• Wirth N., Algorytmy + struktury danych = programy, dowolne wydanie

• Sysło M., Algorytmy, Wydawnictwo Szkolne i Pedagogiczne, Warszawa, 1997

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

4

Informacje organizacyjne

• Wymiar godzinowy: 30 + 30

• Terminy zajęd: sroda, 13.05, s. 441 Budynek BG

• Egzamin: pisemny (nie ma zwolnieo z egzaminu)

• Materiały do wykładu: http://www.uek.krakow.pl/~lulap

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

3

5

Algorytm

• sposób postępowania umożliwiający rozwiązanie zadania określonego typu

• podany w postaci zestawu kolejnych czynności do wykonania

• wykonawcą algorytmu może byd człowiek lub urządzenie (np. komputer)

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

6

Struktura danych

Zestaw powiązanych ze sobą danych wraz z mechanizmamiokreślającymi sposób tworzenia, likwidowania i wykorzystaniazdefiniowanego zestawu jako całości oraz poszczególnych jegoelementów.

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

4

7

Program komputerowy

• zrozumiały dla komputera sposób zapisu algorytmu i opisu struktur danych

• zapisywany przy użyciu języków programowania.

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

Ewolucja metod programowania (1)

• Programowanie w języku maszynowym

– Programista posługuje się pojęciami charakterystycznymi dla systemu komputerowego, a nie dla dziedziny zastosowao (operuje rozkazami wchodzącymi w skład listy rozkazów procesora)

– Rozkazy składające się na program programista zapisu w postaci binarnych kodów

– Programista operuje bezpośrednio na komórkach pamięci operacyjnej. Odpowiedzialny jest za określenie sposobu binarnej reprezentacji informacji.

8Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

5

Ewolucja metod programowania (2)

• Programowanie w języku symbolicznym (asemblerze)– Programista posługuje się rozkazami

pochodzącymi z listy rozkazów procesora (ale są one zapisywane w postaci instrukcji, a nie w postaci binarnych kodów).

– Języki symboliczne wprowadziły zmiany w sposobie notacji programu, ale nie spowodowały zasadniczych zmian w zestawie pojęd wykorzystywanych do opisu algorytmów.

– Pojawiła się możliwośd przypisywania nazw komórkom pamięci (definiowanie zmiennych)

9Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

Ewolucja metod programowania (3)

• Programowanie w językach wysokiego poziomu I generacji– Pojawiła się możliwośd stosowania instrukcji:

• podstawienia (przypisania), • warunkowej, • pętli (iteracji), • skoku.

– Przy opisie algorytmy następuje rezygnacja ze stosowania rozkazów z listy rozkazów procesora i pojawia się możliwośd stosowania pojęd o znacznie większym stopniu ogólności.

– Wprowadzenie mechanizmu deklarowania zmiennych

– Ułatwione zostało operowanie na wartościach tekstowych

– Pojawiła się możliwośd korzystania ze złożonych typów danych (tablice, pliki)

10Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

6

Ewolucja metod programowania (4)

• Programowanie proceduralne– Możliwośd definiowania podprogramów.

– Zdefiniowanie nowego podprogramu pozwala na rozszerzenie zbioru instrukcji dostępnych w stosowanym języku programowania.

– Mechanizm parametrów zwiększył uniwersalnośd definiowanych instrukcji.

– Pojawiła się możliwośd definiowania danych lokalnych (dostępnych tylko w podprogramie) oraz danych globalnych (dostępnych w całym programie)

11Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

Ewolucja metod programowania (5)

• Programowanie strukturalne

– Zwiększenie liczby instrukcji sterujących (np.: różne postaci pętli, instrukcji warunkowych, wyboru, podstawienia) –dzięki czemu można było wyeliminowad instrukcję skoku bezwarunkowego

– Podział programu na dwie części: opis struktur danych i opis algorytmu

– Zwiększenie liczby dostępnych typów danych (tablice, rekordy, zbiory, pliki),

– Możliwośd stosowania dynamicznych struktur danych (stos, kolejka, listy, drzewa),

– Możliwośd definiowania własnych struktur danych.

12Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

7

Ewolucja metod programowania (6)

Programowanie obiektowe

• Równoległe definiowanie algorytmów i struktur danych i ich połączenie w jedną całośd(klasę):– reprezentuje w programie fragment rzeczywistości

(jego cechy, jego zachowania),

– pozwala programiście posługiwad się pojęciami charakterystycznymi dla dziedziny problemu (oderwad się od pojęd związanych ze sprzętem komputerowym),

– pozwala ukryd szczegóły implementacji

• klasa – abstrakcyjny typ danych (ABSTRAHOWANIE - operacja myślowa polegająca na uwzględnianiu tylko wybranych cech sytuacji (przedmiotu, osoby), z pominięciem cech uznanych za nieistotne)

13Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

Wymagania wobec algorytmów

• poprawnośd – algorytm generuje prawidłowe rezultaty (nie zawiera błędów),

• wydajnośd – realizacja algorytmu wymaga użycia akceptowalnej ilości zasobów:– czasu,

– pamięci.

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie 14

2010-10-13

8

15

Pojęcie błędu

• niezgodnośd z obowiązującymi regułami pisania, liczenia, wymowy itp.; odstępstwo od normy; pomyłka

• postępek, działanie, które przynosi komuś złe skutki; niewłaściwe posunięcie, przedsięwzięcie

• mylne, fałszywe mniemanie o czymś (przestarz.)

Źródło: Słownik języka polskiego PWN

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

16

Błędy w programowaniu

• błędy logiczne – na etapie projektowania algorytmu (środki zaradcze: stosowanie sprawdzonych algorytmów, formalne dowodzenie poprawności algorytmu, testowanie programu)

• błędy wykonania programu – ujawniające się w trakcie realizacji algorytmu zapisanego w postaci programu (ujawniające się w postaci wyjątków)

• błędy syntaktyczne – polegające na niezgodności tekstu programu z gramatyką języka programowania (wykrywane przez kompilator)

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

9

17

Złożonośd obliczeniowa

• Złożonośd obliczeniowa algorytmu – ilośd zasobów systemu komputerowego niezbędnych do jego realizacji.

• Zasoby systemu komputerowego niezbędne do realizacji algorytmu:

– czas pracy procesora (złożonośd czasowa algorytmu),

– pamięd operacyjna (złożonośd pamięciowa algorytmu).

• Złożonośd obliczeniowa jest uzależniona od wielkości zadania.

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

18

Sortowania przez wybieranie (1)

import java.io.*;

public class SortowaniePrzezWybieranie static void sortuj(int [] liczby)

int k, pomoc;for (int i = 0; i < liczby.length - 1; i++)

k = i;for (int j = i; j < liczby.length; j++)

if (liczby[k] > liczby[j])k = j;

pomoc = liczby[i];liczby[i] = liczby[k];liczby[k] = pomoc;

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

10

19

Sortowania przez wybieranie (2)

static int czytajLiczbe() throws IOException

BufferedReader klaw = new BufferedReader (new

InputStreamReader (System.in));

return Integer.parseInt(klaw.readLine());

static void drukujWektor(int [] tab)

for (int i = 0; i < tab.length; i++)

System.out.print(tab[i] + " ");

System.out.print("\n");

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

20

Sortowania przez wybieranie (3)

public static void main(String [] args) throws IOException System.out.print("Liczba elementow w wektorze: ");int n = czytajLiczbe();

int [] wektor = new int[n];

for (int i = 0; i < wektor.length; i++)wektor[i] = (int) (100 * Math.random());

long czas1, czas2;czas1 = System.currentTimeMillis();// czas w milisekundach, jaki upłynął od // 1 stycznia 1970 roku, godz. 0:00

sortuj(wektor);czas2 = System.currentTimeMillis();System.out.println("Czas realizacji obliczen: " + (czas2 - czas1));

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

11

21

Sortowania przez wybieranie (4)

Rezultat działania programu:

Liczba elementow w wektorze: 10000

Czas realizacji obliczen: 250

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

22

Czas realizacji algorytmu (1)

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

12

23

Czas realizacji algorytmu (2)

Czas (milisekundy)

0

20000

40000

60000

80000

100000

120000

0 50000 100000 150000 200000 250000

y = 0,000002 n2 – 0,0094 n + 286,41

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

Oszacowanie czasu realizacji algorytmu (1)

24Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

13

Oszacowanie czasu realizacji algorytmu (2)

• Analiza powyższych danych pozwala stwierdzid, że czas obliczeo uzależniony jest przede wszystkim od składnika:

0,000002 n2

Składnik ten nazywany jest składnikiem dominującym.

• Po pominięciu stałych współczynników można stwierdzid, że zależnośd pomiędzy czasem wykonania a wielkością zadania ma charakter funkcji kwadratowej. Kwadratowy charakter zależności uwidacznia się w coraz większym stopniu wraz ze wzrostem wielkości zadania.

25Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

Cechy empirycznego określania złożoności

• Zalety:– otrzymane czasy obliczeo są proste w interpretacji

• Wady:– koniecznośd wielokrotnego uruchamiania programu (dla złożonych algorytmów

może to byd bardzo czasochłonne),– uzyskane wyniki dotyczą zastosowanego w obliczeniach zestawu danych (trudno

jest określid czas realizacji dla przypadku „najlepszego”, najgorszego” oraz „przeciętnego”),

– wyniki dotyczą zwykle stosunkowo niewielkich zbiorów danych – nie wiadomo, czy dla zbiorów o większym rozmiarze charakter zależności się nie zmieni,

– czas jest uzależniony od szybkości i architektury komputera, języka programowanie, techniki translacji, systemu operacyjnego – trudna porównywalnośd wyników

– z uwagi na wielozadaniowy charakter systemów operacyjnych trudno jest określid, jaka częśd czasu była rzeczywiście przeznaczona na realizację analizowanego programu.

26Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

14

27

Bezpośrednia analiza algorytmów

Analiza dotyczy:

• charakteru zależności (np. zależnośd liniowa lub kwadratowa), a nie jej dokładnej postaci (wzór funkcji) – uwzględniany jest element dominujący, pomijane są współczynniki stałe

• górnego i dolnego ograniczenia czasu realizacji algorytmu (a nie czasu realizacji algorytmu)

– górne ograniczenie – czas realizacji algorytmu jest nie większy niż ... (ale może byd krótszy) – przypadek pesymistyczny,

– dolne ograniczenie – czas realizacji algorytmu jest nie mniejszy niż ... (ale może byd dłuższy) – przypadek optymistyczny,

• zachowania się algorytmu dla zbiorów danych o dużej wielkości (czyli dla wszystkich n większych od pewnej wartości n0)

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

Górne ograniczenie czasu realizacji algorytmu (1)

• f(n) – czas realizacji algorytmu (zależny od n)

• f(n) zależy od wielu czynników i podanie dokładnego charakteru zależności jest trudne

• łatwiej jest zdefiniowad ograniczenie górne dla f(n).

28

f(n)

n

c g(n)

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

15

Górne ograniczenie czasu realizacji algorytmu (2)

• Czas realizacji algorytmu jest rzędu co najwyżej g(n), jeśli istnieją stała rzeczywista c > 0 i stała naturalna n0 takie, że nierównośd f(n) ≤ c g(n) zachodzi dla każdego n ≥ n0.

• Zbiór wszystkich funkcji f(n) spełniających powyższe ograniczenie określany jest jako O(g(n)).

• O(g(n)) = f(n): istnieją dodatnie stałe c oraz n0 takie, że 0 ≤ f(n) ≤ c g(n) dla wszystkich n ≥ n0

29Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

Górne ograniczenie czasu realizacji algorytmu (3)

Stwierdzenie:

czas realizacji algorytmu wynosi O(g(n))

lub

czas realizacji algorytmu jest rzędu co najwyżej g(n)

lub

algorytm jest klasy O(g(n))

oznacza: że istnieje taka stała c, że dla n ≥ n0 czas realizacji algorytmu wynosi co najwyżej c g(n).

30Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

16

Dolne ograniczenie czasu realizacji algorytmu (4)

• Czas realizacji algorytmu jest rzędu co najmniej g(n), jeśli istnieją stała rzeczywista c > 0 i stała naturalna n0 takie, że nierównośd f(n) ≥ c g(n)zachodzi dla każdego n ≥ n0.

• Zbiór wszystkich funkcji spełniających to ograniczenie określany jest jako Ω(g(n))

• Ω(g(n)) = f(n): istnieją dodatnie stałe c i n0 takie, że 0 ≤ cg(n) ≤ f(n) dla wszystkich n ≥ n0

31

f(n)

n

c g(n)

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

Dolne i górne ograniczenie czasu realizacji algorytmu (1)

• Czas realizacji algorytmu jest dokładnie rzędu g(n) jeśli istnieją stała rzeczywista c1 > 0, c2 > 0 i stała naturalna n0 takie, że nierównośd c1 g(n) ≤ f(n) ≤ c2 g(n) zachodzi dla każdego n ≥ n0.

32

f(n)

n

c1 g(n)

c2 g(n)

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

17

Dolne i górne ograniczenie czasu realizacji algorytmu (2)

• Zbiór wszystkich funkcji spełniających to ograniczenie określany jest jako Θ(g(n))

• Θ(g(n)) = f(n); istnieją dodatnie stałe c1, c2 i n0 takie, że 0 ≤ c1

g(n) ≤ f(n) ≤ c2 g(n) dla wszystkich n ≥ n0

33Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

34

Średnia złożonośd obliczeniowa

• Średnia złożonośd czasowa uwzględnia prawdopodobieostwa pojawienia się każdego możliwego zestawu danych wejściowych

• Zi(n) – i-ty możliwy zestaw danych n-elementowy

• pi – prawdopodobieostwo wystąpienia i-tego zestawu

• Ti(n) – złożonośd czasowa algorytmu dla i-tego zestawu danych

• Średnia złożonośd czasowa algorytmu dana jest formułą:

i

iiśr nTpnT

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

18

Złożonośd obliczenia sortowania przez wybieranie (1)

static void sortuj(int [] liczby) int k, pomoc;for (int i = 0; i < liczby.length - 1; i++)

//koszt K1k = i;for (int j = i; j < liczby.length; j++)

//koszt K2if (liczby[k] > liczby[j])

k = j;//koszt K3pomoc = liczby[i];liczby[i] = liczby[k];liczby[k] = pomoc;

35Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

Złożonośd obliczenia sortowania przez wybieranie (2)

for (int i = 0; i < n - 1; i++)

K1

for (int j = i; j < n; j++)

K2

K3

36Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

19

Złożonośd obliczenia sortowania przez wybieranie (3)

for (int i = 0; i < n - 1; i++)

K1

(n – 1) * K2

K3

37Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

Złożonośd obliczenia sortowania przez wybieranie (4)

(n – 1) * K1 + (n – 1) [n * K2 + (n-1) * K2 + ... + 2 * K2] + (n – 1) * K3 =

= n * K1 – K1 + *½ * (2 + n) * (n – 1) * K2] + n * K3 – K3 =

= n * K1 – K1 + n * K2 – K2 + ½ * n2 * K2 – ½ * n * K2 + n * K3 –K3 =

= ½ * K2 * n2 + (K1 + ½ * K2 + K3) * n – (K1 + K2 + K3) = O(n2)

38Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

20

39

Rodzaje złożoności (1)

• Złożoność logarytmiczna – log n

• W każdym kroku algorytmu zadanie o rozmiarze n jest sprowadzane do zadania o rozmiarze n / 2

• Przykład:

• algorytm wyszukiwania binarnego jest klasy O(log n)

• Przykładowa realizacja wyszukiwania binarnego: Mamy odszukad wartośd 11 w ciągu liczb:

1, 2, 7, 9, 9, 11, 12, 15, 22, 34, 52, 67, 87, 90, 99

1, 2, 7, 9, 9, 11, 12

9, 11, 12

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

40

Rodzaje złożoności (2)

• Złożoność liniowa – n

• gdy dla każdego elementu pochodzącego z n – elementowego zbioru danych wykonywana jest stała liczba operacji

• Przykłady:– wyszukiwanie sekwencyjne

– sumowanie liczb w wektorze

– wyznaczanie minimum, maksimum

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

21

41

Rodzaje złożoności (3)

• złożoność liniowo – logarytmiczna – n log n

• gdy w każdym kroku zadanie o rozmiarze n jest sprowadzane do dwóch zadao o rozmiarze n/2, a uzyskane wyniki są ponownie scalane

• Przykład:

– sortowanie przez łączenie jest klasy O(n log n)

– sortowanie szybkie – jest klasy O(n2), ale przeciętny czas realizacji algorytmu jest rzędu n log n

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

42

Rodzaje złożoności (4)

• złożoność kwadratowa – n2

• gdy dla każdej pary elementów realizowana jest pewna, stała liczba operacji (zwykle algorytmy takie są zapisywane za pomocą dwóch zagnieżdżonych pętli for)

• Przykłady:– proste metody sortowania (przez wstawianie, wybieranie, bąbelkowe)

są klasy O(n2), również średni czas realizacji tych metod jest rzędu O(n2)

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

22

43

Rodzaje złożoności (5)

• złożoność wielomianowa stopnia wyższego niż dwa (n3, n4, ...)

• Przykład:

• mnożenie macierzy w sposób tradycyjny jest algorytmem klasy O(n3)

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

44

Rodzaje złożoności (6)

• Złożoność wykładnicza postaci 2n

• gdy realizowanych jest n kroków, a liczba operacji w każdym z nich wzrasta w sposób geometryczny

• Przykład:– wieże Hanoi

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

23

45

Rodzaje złożoności (7)

• Złożoność wykładnicza typu n!

• gdy pewna, stała liczba operacji realizowana jest dla każdej permutacji n elementów

• Przykład:

• Tworzenie magicznych kwadratów z n elementów (pierwiastek z n musi byd wartością całkowitą)

• Algorytm postępowania: tworzymy kolejną permutację, wpisujemy do kwadratu i sprawdzamy, czy spełnia konieczne warunki.

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

46

Rodzaje złożoności (8)

Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie

2010-10-13

24

47

Rekurencja

• Rekurencyjny sposób zapisu kodu programu - z poziomu podprogramu wywoływany jest ten sam podprogram.

48

Przykład (1)

public class Rekurencja01

static void f()

System.out.println("Poczatek");

f();

System.out.println("Koniec");

public static void main(String [] args)

f();

2010-10-13

25

49

Przykład (2)

Początek

f(x)

Koniec

Początek

f(x)

Koniec

Początek

f(x)

Koniec

Początek

f(x)

Koniec

main()

f()

i.t.d.

50

Przykład (3)

Efekt uruchomienia programu:

Poczatek

Poczatek

Poczatek

....

Poczatek

Exception in thread "main"

java.lang.StackOverflowError

2010-10-13

26

51

Warunek stopu

• Wywołania rekurencyjne muszą się zakooczyd (w podprogramie musi zostad zdefiniowany warunek zatrzymania się algorytmu /warunek stopu/).

52

Przykład (1)

public class Rekurencja02 static int licznik = 0;static void f()

licznik++;System.out.println("Poczatek");if (licznik <=5) f();System.out.println("Koniec");

public static void main(String [] args)

f();

2010-10-13

27

53

Przykład (2)

licznik = 1

Początek

f(x)

Koniec

licznik = 2

Początek

f(x)

Koniec

licznik = 3

Początek

f(x)

Koniec

licznik = 4

Początek

f(x)

Koniec

licznik = 5

Początek

f(x)

Koniec

main()

f()

licznik = 6

Początek

Koniec

54

Przykład (3)

Efekt uruchomienia programu:

Poczatek

Poczatek

Poczatek

Poczatek

Poczatek

Poczatek

Koniec

Koniec

Koniec

Koniec

Koniec

Koniec

2010-10-13

28

55

Rekurencyjne obliczanie silni (1)

public class Rekurencja03 static int silnia(int n)

int pomoc;System.out.println("Wywolanie: silnia(" + n + ")");if ((n == 0) || (n == 1)) pomoc = 1;else pomoc = n * silnia(n-1);System.out.println("Zwrocenie wyniku: " + n + "! = " + pomoc);return pomoc;

public static void main(String [] args) System.out.println("4! = " + silnia(4));

56

Rekurencyjne obliczanie silni (2)

2010-10-13

29

57

Rekurencja może byd kosztowna ...

public class Rekurencja04 static int licznik = 0;static int fib(int n)//obliczanie n-tej liczby Fibonacciego

licznik++;if (n == 0) return 0;else

if (n == 1) return 1;else return fib(n-1) + fib(n-2);

public static void main(String [] args) System.out.println("5-ta liczba Fibonacciego to: " + fib(5));System.out.println("Liczba wywolan funkcji:" + licznik);

58

Efekt działania:

5-ta liczba Fibonacciego to: 5

Liczba wywolan funkcji: 15

2010-10-13

30

Sposób wyznaczania liczb Fibonacciego

59

Jeśli istnieje oczywiste rozwiązanie iteracyjne, to należy je wybrad.

Sterowanie kolejnością wykonywania działao (1)

public class Rekurencja05 static void sekwencja(int n)

System.out.print(n + " ");if (n > 0) sekwencja(n-1);

public static void main(String [] args)

sekwencja(5);System.out.println();

Efekt działania programu:5 4 3 2 1 0

60

2010-10-13

31

Sterowanie kolejnością wykonywania działao (2)

public class Rekurencja06 static void sekwencja(int n)

if (n > 0) sekwencja(n-1);System.out.print(n + " ");

public static void main(String [] args)

sekwencja(5);System.out.println();

Efekt działania programu0 1 2 3 4 5

61

62

Wieże Hanoi

public class Rekurencja08 static void przesun(int ile, char wiezaZrodlowa, char wiezaDocelowa, char wiezaPomocnicza)

if (ile == 1)System.out.println(wiezaZrodlowa + " => " + wiezaDocelowa);

else

przesun(ile-1,wiezaZrodlowa,wiezaPomocnicza,wiezaDocelowa);

System.out.println(wiezaZrodlowa + " => " +wiezaDocelowa);

przesun(ile-1,wiezaPomocnicza,wiezaDocelowa,wiezaZrodlowa);

2010-10-13

32

63

Złożonośd algorytmu: Wieże Hanoi (1)

• Analizowana jest liczba przesunięd potrzebna do rozwiązania zadania z n krążkami (liczbę przesunięd oznaczymy przez P(n))

• gdy n = 1 to P(1) = 1

• gdy n > 1 to P(n) = 2 * P(n – 1) + 1

64

Złożonośd algorytmu: Wieże Hanoi (2)

P(n-3) P(n-3) P(n-3) P(n-3) P(n-3)P(n-3)P(n-3)P(n-3)1 1 11

P(n-2) P(n-2) P(n-2) P(n-2)1 1

P(n-1) P(n-1)1

P(n)

Liczba

przesunięć

1

2

4

Poziom

0

1

2

3

2010-10-13

33

65

Złożonośd algorytmu: Wieże Hanoi (3)

• P(n) = P1 + P2 + P3 + ... + Pn = 2n – 1

• W powyższym wzorze zastosowany został wzór na sumę npierwszych elementów ciągu geometrycznego (o elementach b1, b2, ..., bn i ilorazie q)

• Sn = b1 * (qn – 1) / (q – 1)

Inwersja elementów w wektorze (1)

public class Rekurencja07

static void wyswietlWektor(int [] w)

for(int i = 0; i < w.length; i++)

System.out.print(w[i] + " ");

System.out.println();

66

2010-10-13

34

Inwersja elementów w wektorze (2)

static void inwersja(int poczatek, int koniec, int [] w)

if (poczatek < koniec)

int pomoc = w[poczatek];

w[poczatek] = w[koniec];

w[koniec] = pomoc;

inwersja(poczatek+1,koniec-1,w);

67

Inwersja elementów w wektorze (3)

public static void main(String [] args)

int [] tab = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11;

wyswietlWektor(tab);

inwersja(0,tab.length-1,tab);

wyswietlWektor(tab);

Efekt działania programu:

1 2 3 4 5 6 7 8 9 10 11

11 10 9 8 7 6 5 4 3 2 1

68

2010-10-13

35

69

Sortowanie szybkie (1)

• Hoare, 1960

void quickSort(int tab[], int first, int last)

• wybierz jedną z wartości znajdujących się w wektorze (w poniższym algorytmie wybierana jest wartośd znajdująca się na pozycji o numerze first)

• dokonaj przemieszczenia elementów w wektorze, tak aby uzyskad:

elementy < x | x | elementy >= x• za pomocą tej samej procedury uporządkuj częśd wektora

znajdującą się na lewo od wartości „x” oraz częśd znajdującą się na prawo od wartości „x”.

• średnia złożonośd obliczeniowa: O(n * log(n))• pesymistyczna złożonośd obliczeniowa O(n2)

70

Sortowanie szybkie (2)

public class QuickSort

public static void swap (int tab[], int x, int y)

int temp = tab[x];

tab[x] = tab[y];

tab[y] = temp;

2010-10-13

36

71

Sortowanie szybkie (3)

public static int partition(int tab[], int first, int last)

int pivot = tab[first]; int up = first;int down = last;

do while ((up < last) && (pivot >= tab[up])) up++;while (pivot < tab[down]) down--;if (up < down) swap(tab,up,down); while (up < down);

swap(tab,first,down);

return down;

72

Sortowanie szybkie (4)

public static void quickSort(int tab[], int first,

int last)

if (first >= last) return;

int pivot = partition(tab, first, last);

quickSort(tab, first, pivot-1);

quickSort(tab, pivot+1, last);

2010-10-13

37

73

Sortowanie szybkie (5)

public static void main(String argv[]) int n = 10;

int tab[] = new int[n];for (int i=0 ; i < n; i++)

tab[i] = (int) (100 * Math.random());

quickSort(tab, 0, n-1);

for (int i=0 ; i < n; i++) System.out.print(tab[i] + " ");

System.out.println();

Sortowanie przez łączenie – Mergesort (1)

• sort(int poczatek, int koniec, int [] w),

• podziel wektory na dwie połowy,

• posortuj każdą z nich (za pomocą tej samej metody, o ile ich długośd > 1),

• połącz posortowane części w całośd,

• złożonośd obliczeniowa: O(n * log(n)).

74

2010-10-13

38

Sortowanie przez łączenie – Mergesort (2)

public class MergeSort

static void wyswietlWektor(int [] w)

for(int i = 0; i < w.length; i++)

System.out.print(w[i] + " ");

System.out.println();

75

Sortowanie przez łączenie – Mergesort (3)

static void sort(int poczatek, int koniec, int [] w)

if (poczatek >= koniec) return;

int srodek = (poczatek + koniec) / 2;

sort(poczatek, srodek, w);sort(srodek+1, koniec, w);

scal(poczatek, srodek, koniec, w);

76

2010-10-13

39

Sortowanie przez łączenie – Mergesort (3)

static void scal(int poczatek, int srodek, int koniec, int [] w) int pocz1 = poczatek; int kon1 = srodek;int pocz2 = srodek + 1;int kon2 = koniec;

while ((pocz1 <= kon1) && (pocz2 <= kon2)) if (w[pocz1] < w[pocz2]) pocz1++;else

int pomoc = w[pocz2];for (int i = pocz2 - 1; i >= pocz1; i--)

w[i+1] = w[i];w[pocz1] = pomoc;

pocz1++;kon1++;pocz2++;

77

Sortowanie przez łączenie – Mergesort (4)

public static void main(String [] args)

int [] tab = 1, 5, 3, 7, 7, 9, 2, 3, 2, 2, 3;wyswietlWektor(tab);sort(0,tab.length-1,tab);wyswietlWektor(tab);

Wynik działania programu1 5 3 7 7 9 2 3 2 2 31 2 2 2 3 3 3 5 7 7 9

78