950 likes | 1.56k Views
ALGORYTM . SCHEMATY BLOKOWE. KONSTRUKCJE PROGRAMU, PODPROGRAMY, FUNKCJE. Cele : Poznanie zasad rozwiązywania problemów informatycznych przy wykorzystaniu algorytmu. Osiągnięcia : Opracowanie algorytmu i przedstawienie go w postaci schematu blokowego. Definicja i cechy algorytmu.
E N D
ALGORYTM. SCHEMATY BLOKOWE. KONSTRUKCJE PROGRAMU, PODPROGRAMY, FUNKCJE Cele: Poznanie zasad rozwiązywania problemów informatycznych przy wykorzystaniu algorytmu. Osiągnięcia: Opracowanie algorytmu i przedstawienie go w postaci schematu blokowego.
Definicja i cechy algorytmu • Algorytm - uporządkowany i skończony ciąg dokładnie określonych operacji na obiektach, do rozwiązania dowolnego zadania z określonej ich klasy. • Cechy algorytmu: • skończoność (skończony zbiór operacji), • określoność (operacje i porządek ich wykonania powinny być ściśle określone, niezależnie od obiektów, na których są wykonywane), • ogólność (rozwiązywanie klasy zadań a nie pojedynczego zadania), • efektywność (rozwiązanie najmniejszym kosztem).
Euklides - NWD • Słowo algorytm często kojarzone z Euklidesem(365 – 300 p.n.e) i jego słynnym przepisem na obliczanie największego wspólnego dzielnika 2 liczb a i b (NWD) – zapis w pseudokodzie Dane wejściowea i b;krok 1: Czytaj a, b krok 2: Dopóki a <> b, wykonuj krok 3. Inaczej pisz a i zakończ algorytm. krok 3: Jeżeli a > b, to a:= a - b. Inaczej b:= b - a
Algorytm Euklidesa – wersja 2 • Dane są dwie liczby naturalne a i b. • 1. Jeśli b ≠ 0 obliczcjakoresztę z dzielenia a przez b i zastąp a przez b, zaś b zastąp przez c. • 2. Jeżeli b = 0, NWD wynosi a, w przeciwnym wypadku wróć do punktu pierwszego i kontynuuj. • Przykład 1. Znajdź NWD liczb 243 i 111 za pomocą algorytmu Euklidesa, • 243 : 111 = 2, reszty 21 • 111 : 21 = 5, reszty 6 • 21 : 6 = 3, reszty 3 • 6 : 3 = 2, reszty 0 • Ostatnia niezerowa reszta wynosi 3. • NWD(243, 111) = 3 • Przykład 2. Znajdź NWD liczb 15 i 12 za pomocą algorytmu Euklidesa, • 15 : 12 = 1, reszty 3 • 12 : 3 = 4, reszty 0 • NWD(15, 12) = 3
Złożoność obliczeniowa • Złożoność obliczeniowa algorytmu: ilość zasobów komputerowych potrzebnych do jego wykonania. W algorytmach uwzględnia się czas działania i ilość zajmowanej pamięci • czasowa T(n): • złożoność pesymistyczna – ilość zasobów potrzebna przy najgorszych danych wejściowych rozmiaru n, • złożoność oczekiwanaalgorytmu (średnia) dla typowych danych rozmiaru n • pamięciowa – potrzebny rozmiar pamieci (słowa maszyny)
Złożoność czasowa • Przyjętą miarą złożoności czasowej jest liczba operacji podstawowych w zależności od rozmiaru wejścia. Pomiar rzeczywistego czasu zegarowego jest mało użyteczny ze względu na silną zależność od sposobu realizacji algorytmu, użytego kompilatora oraz maszyny na której algorytm wykonujemy. Dlatego w charakterze czasu wykonania rozpatruje się zwykle liczbę operacji podstawowych (dominujących). Operacjami podstawowymi mogą być na przykład: podstawienie, porównanie lub prosta operacja arytmetyczna.
Liniowo- logarytmiczna T=n*log(n) • Czas działania n*log(n) występuje np. dla algorytmów typu:zadanie rozmiaru n zostaje sprowadzone do 2 podzadań rozmiaru n/2plus pewna ilość działań – liniowa względem n, do rozbicia i scalenia rozwiązań. • Przykładem jest megasort
Złożoność pamięciowa • Złożoność pamięciowa jest miarą ilości wykorzystanej pamięci. • Jako tę ilość najczęściej przyjmuje się użytą pamięć maszyny abstrakcyjnej (na przykład liczbę komórek pamięci maszyny RAM) w funkcji rozmiaru wejścia. • Możliwe jest również obliczanie rozmiaru potrzebnej pamięci fizycznej wyrażonej w bitach lub bajtach.
Projektowanie algorytmów • Do metodologii projektowania należy upraszczanie i wyodrębnianie niezależnych części (procedur, funkcji). • Wyróżnia się algorytmy • szeregowe • równoległe (arch. wieloprocesorowa)
Projektowanie algorytmów: • algorytmy zachłanne (nie analizujemy podproblemów dokładnie, tylko wybieramy najbardziej obiecującą w tym momencie drogę rozwiązania • algorytmy wg strategii "dziel i rządź" (dzielimy problem na kilka mniejszych, a te znowu dzielimy, aż ich rozwiązania staną się oczywiste) • algorytmy oparte na technice rekursji (rekurencji) (procedura lub funkcja wywołuje sama siebie, aż do uzyskania wyniku lub błędu) • algorytmy oparte na programowaniu dynamicznym (podproblemy) • algorytmy z powrotem
Podstawowe paradygmaty tworzenia algorytmów komputerowych: • dziel i zwyciężaj – dzielimy problem na kilka mniejszych, a te znowu dzielimy, aż ich rozwiązania staną się oczywiste, • programowanie dynamiczne – problem dzielony jest na kilka, ważność każdego z nich jest oceniana i po pewnym wnioskowaniu wyniki analizy niektórych prostszych zagadnień wykorzystuje się do rozwiązania głównego problemu, • metoda zachłanna – nie analizujemy podproblemów dokładnie, tylko wybieramy najbardziej obiecującą w tym momencie drogę rozwiązania, • programowanie liniowe – oceniamy rozwiązanie problemu przez pewną funkcję jakości i szukamy jej minimum, • poszukiwanie i wyliczanie – kiedy przeszukujemy zbiór danych aż do odnalezienia rozwiązania, • algorytm probabilistyczny – algorytm działa poprawnie z bardzo wysokim prawdopodobieństwem, ale wynik nie jest pewny, • heurystyka– człowiek na podstawie swojego doświadczenia tworzy algorytm, który działa w najbardziej prawdopodobnych warunkach, rozwiązanie zawsze jest przybliżone.
Najważniejsze techniki implementacji algorytmów komputerowych • proceduralność – algorytm dzielimy na szereg podstawowych procedur, wiele algorytmów współdzieli wspólne biblioteki standardowych procedur, z których są one wywoływane w razie potrzeby, • praca sekwencyjna – wykonywanie kolejnych procedur algorytmu, według kolejności ich wywołań, na raz pracuje tylko jedna procedura, • praca wielowątkowa – procedury wykonywane są sekwencyjnie, lecz kolejność ich wykonania jest trudna do przewidzenia dla programisty • praca równoległa – wiele procedur wykonywanych jest w tym samym czasie, wymieniają się one danymi, • rekurencja – procedura lub funkcja wywołuje sama siebie, aż do uzyskania wyniku lub błędu, • obiektowość – procedury i dane łączymy w pewne klasy reprezentujące najważniejsze elementy algorytmu oraz stan wewnętrzny wykonującego je urządzenia.
Strukturydanych • tablica • lista • kolejka • stos • zbiór • graf
Tablice w programowaniu • Arrays (macierz, tablica) jest topodstawowa struktura danych składająca się z jednowymiarowej lub wielowymiarowejtabeli, którą program traktuje jak jeden obiekt. Wszystkie obiekty muszą być tego samego rodzaju.W tablicach mogą być np. liczby, napisy, znaki • Do każdej danej zapisanej w tablicy można się odwołać przez nazwę tablicy i położenie tej danej wewnątrz tablicy.
Tablica • Tablica w informatyce to kontener danych dostępnych, w którym poszczególne komórki dostępne są za pomocą kluczy, które najczęściej przyjmują wartości numeryczne. • Rozmiar tablicy jest albo ustalony z góry (tablice statyczne), albo może się zmieniać w trakcie wykonywania programu (tablice dynamiczne). • Praktycznie wszystkie języki programowania obsługują tablice – jedynie w niektórych językach funkcyjnych zamiast tablic używane są listy (choć tablice zwykle też są dostępne).
Lista Lista- rodzaj kontenera - dynamiczna struktura danych, używana w informatyce. Składa się z podstruktur wskazujących na następniki i/lub poprzedniki. Listy, to struktury, które umożliwiają tworzenie ciągów danych w taki sposób, że każda dana pamięta gdzie się znajduje kolejna. Istnieją dwie popularne implementacje struktury listy: tablicowa i wskaźnikowa. Tablicowa - jak wskazuje nazwa, lista zaimplementowana w ten sposób opiera się na tablicy obiektów (lub rekordów) danego typu. Wskaźnikowa - w tej implementacji każdy obiekt na liście musi (co nie było konieczne w wersji tablicowej) zawierać dodatkowy element: wskaźnik do innego obiektu tego typu. Wynika to z faktu, że to wskaźniki są podstawą nawigacji w tym typie listy, a dostęp do jej elementów jest możliwy wyłącznie przez wskaźnik.
Kolejka • Kolejka (ang. queue) – liniowa struktura danych, w której nowe dane dopisywane są na końcu kolejki, a z początku kolejki pobierane są dane do dalszego przetwarzania (bufor typu FIFO, First In, First Out; pierwszy na wejściu, pierwszy na wyjściu). • StosPrzeciwieństwem kolejki jest stos, bufor typu LIFO (ang. Last In, First Out; ostatni na wejściu, pierwszy na wyjściu), w którym jako pierwsze obsługiwane są dane wprowadzone jako ostatnie.
Graf • Graf to – w uproszczeniu – zbiór wierzchołków, które mogą być połączone krawędziami, w taki sposób, że każda krawędź kończy się i zaczyna w którymś z wierzchołków. • Grafy to podstawowy obiekt rozważań teorii grafów. • Za pierwszego teoretyka i badacza grafów uważa się] Leonarda Eulera, który rozstrzygnął zagadnienie mostów królewieckich.
Sposoby zapisu algorytmów: • w języku naturalnym(opisowo) • zapis przy pomocy pseudo-kodu • graficzny za pomocą schematów blokowych (schematy działania) • przy pomocy języków programowania
Opis słowny • Opis słowny jest to zapis kolejnych kroków algorytmu w języku naturalnym np. polskim • wyszczególniamy, jakie czynności należy wykonać • zaznaczamy, kiedypowiniennastąpić koniec algorytmu
Przykład opisu słownego • Dany jest: • punkt płaszczyzny P(xp,yp) • środek S(a,b) • długość promienia r okręgu o równaniu (x-a)2+(y-b)2=r2. • Określić położenie punktu P względem tego okręgu.
Rys. Dane: P(Xp,Yp), S(a,b), r okręgu Y P(Xp,Yp) b r d S(a,b) a X
Oznaczenia, rozwiązanie • Oznaczamy d - odległość punktu od okręgu. • Jeżeli d<r, to punkt leży wewnątrz okręgu, • jeżeli d=r, to punkt leży na okręgu • a gdy d>r, to punkt leży na zewnątrz okręgu
Opis słowny algorytmu • Pobierz wartości xp ,yp, a, b, r. • Oblicz odległość punktu według wzoru • Sprawdź, czy d<r , jeśli TAK, to „punkt wewnętrzny” i przejdź do KONIEC. • Sprawdź, czy d=r, jeśli TAK, to „punkt leży na okręgu” i przejdź do KONIEC • W innym przypadku (d>r) „punkt leży na zewnątrz okręgu” (d>r) • KONIEC
Pseudokod • Umowny, zwykle nie istniejący i bardzo uproszczony język podobny do jakiegoś jezyka programowania, w którym opisany jest algorytm działania programu. • Definiujepodstawowe pętle, warunki i typy danych. • Stosowany w celach poglądowych, jako uniwersalny i czytelny dla każdego kod programu.
Pseudokod • Pseudokodemnazywany jest taki sposób zapisu algorytmu, który, zachowując strukturę charakterystyczną dla kodu zapisanego w języku programowania, rezygnuje ze ścisłych reguł składniowych na rzecz prostoty i czytelności. • Pseudokod nie zawiera szczegółów implementacyjnych, często też opuszcza się w nim opis działania podprocedur (jeśli powinien być on oczywisty dla czytelnika), zaś nietrywialne kroki algorytmu opisywane są z pomocą formuł matematycznych lub zdań w języku naturalnym. • Nie istnieją w chwili obecnej szerzej przyjęte standardy zapisu pseudokodu. Większość autorów używa przyjętej ad hoc składni, często opierając się na składni istniejących języków programowania (Pascal, ALGOL, C).
Pseudokod • Opis słowny algorytmu w języku częściowo sformalizowanym, podobnym np. do Pascala • Elementy: • pseudosłowa kluczowe → odpowiadają słowom kluczowym składającym się na instrukcje sterujące w językach proceduralnych, np.: jeśli – if, wtedy – then, powtórz – repeatdopóki – while, czytaj – read, pisz - write • wyrażenia arytmetyczne → pozwalają na reprezentację obliczeń arytmetycznych
Pseudokod Pseudokod - elementy • 1. Początek i koniec • 2. Zmienne: całkowite, rzeczywiste, … • 3. Instrukcja warunkowa: jeśli – if … then, if … then … else • 4. Skok do instrukcji: goto • 5. Etykiety • 6. Czytaj i pisz: read, write • 7. Pętle: powtarzaj - repeat, dopóki - while, dla - for • 8. Programowanie strukturalne – procedury i funkcje
Schemat blokowy Reprezentacja graficzna algorytmu sekwencyjnego • Elementy schematu blokowego: • elipsa (lub zaokrąglony prostokąt) → początek/koniec algorytmu • prostokąt → operacja • romb → decyzja/warunek • równoległobok → wczytanie/wyprowadzenie danych • strzałki → kolejność sterowania/przepływu • etykiety → oznaczenia, komentarz • W języku angielskim schemat blokowy nazywamy flowchart.
START lub END • Początek lub koniec algorytmu. • W każdym algorytmie musi się znaleźć dokładnie jedna taka figura z napisem "Start" oznaczająca początek algorytmu oraz dokładnie jedna figura z napisem "Stop" oznaczająca koniec algorytmu. • Blok symbolizujący początek algorytmu ma dokładnie jedną strzałkę wychodzącą a blok symbolizujący koniec ma co najmniej jedną strzałkę wchodzącą.
Proces • W obrębie bloku procesu umieszczamy wszelkie obliczenia lub podstawienia. • Proces ma dokładnie jedną strzałkę wchodzącą i dokładnie jedną strzałkę wychodzącą.
Decyzja • Romb symbolizuje blok decyzyjny. • Umieszcza się w nim jakiś warunek (np. "x>2"). • Z dwóch wybranych wierzchołków rombu wyprowadzamy dwie możliwe drogi: gdy warunek jest spełniony (strzałkę wychodzącą z tego wierzchołka należy opatrzyć etykietą "Tak") oraz gdy warunek nie jest spełniony („Nie”). • Każdy romb ma dokładnie jedną strzałkę wchodzącą oraz dokładnie dwie strzałki wychodzące.
Odczyt, zapis • Równoległobok jest stosowany do odczytu lub zapisu danych. • W jego obrębie należy umieścić stosowną instrukcję np. Read(x) lub Write(x) (można też stosować opis słowny np. „Czytaj x ”, "Drukuj x "). • Figura ta ma dokładnie jedną strzałkę wchodzącą i jedną wychodzącą.
Proces już zdefiniowany • Ta figura symbolizuje proces, który został już kiedyś zdefiniowany. • Można ten blok porównać do procedury, którą definiuje się raz w programie, by następnie móc ją wielokrotnie wywoływać. Warunkiem użycia jest więc wcześniejsze zdefiniowanie procesu. • Podobnie jak w przypadku zwykłego procesu i tu mamy jedno wejście i jedno wyjście.
Łącznik stronicowy Koło symbolizuje tzw. łącznik stronicowy. • Może się zdarzyć, że chcemy "przeskoczyć" z jednego miejsca na kartce na inne (np. by nie krzyżować strzałek). Możemy w takim wypadku posłużyć się łącznikiem. Umieszczamy w jednym miejscu łącznik z określonym symbolem w środku (np. cyfrą, literą) i doprowadzamy do niego strzałkę. Następnie w innym miejscu kartki umieszczamy drugi łącznik z takim samym symbolem w środku i wyprowadzamy z niego strzałkę. • Łączniki występują więc w parach, jeden ma tylko wejście a drugi wyjście.
Łącznik między-stronicowy • Działa analogicznie jak stronicowy, lecz nie w obrębie strony. • Przydatne w złożonych algorytmach, które nie mieszczą się na jednej kartce. • Uwaga: jeśli stosujemy oba typy łączników w schemacie, to najlepiej jest stosować liczby do identyfikowania jednych i litery do drugich. Dzięki temu nie dojdzie do pomyłki.
Przykład: Obliczenie n! - pseudokod • Policzenie silni z zadanej liczby naturalnej • Pseudokod • wczytaj n • jeżeli n<0 idź do 1 • licznik=0, silnia=1 • jeżeli licznik != n wtedy powiększ licznik o 1, silnia=silnia*licznik, idź do 4 • wypisz silnia
Implementacja Realizacja algorytmu w postaci funkcji: int silnia (int n) { int l, s = 1; if ( n < 0) return -1; for (l=1; l <= n; l++) s = s * l; return s; }
Zapis programu na obliczenie n! w języku C #include <stdio.h> int silnia (int); intmain(void) { intn,s; printf("\nPodajliczbe \"n\" do policzenia silni: "); scanf("%d", &n); s = silnia(n); if ( s == -1 ) { printf("Bladobliczen!\n"); return 1; } printf("\nSilnia wynosi: %d.\n", s); return 0; } //------------------- funkcja int silnia (int n) { int l,s=1; if ( n < 0) return -1; for (l=1; l <= n; l++) s = s * l; return s; }
Algorytmy - konwencja notacyjna • 1) Deklaracja zmiennych • stałe P; • całkowite N; • rzeczywiste N; • logiczne N; {gdzie N - lista zmiennych, P - lista podstawień}
Deklaracje tablic: • całkowitetablicaN [W1:W2], W[W1:W2, W3:W5]; • rzeczywistetablicaN [W1:W2], W[W1:W2, W3:W5]; gdzie: N - nazwa tablicy, W1, W2 W3, W4 - wyrażenia o wartościach całkowitych wyznaczające odpowiednio najmniejszy i największy numer elementu tablicy