Prosta dokumentacja - Instytut Informatyki Teoretycznej i Stosowanej
Transkrypt
Prosta dokumentacja - Instytut Informatyki Teoretycznej i Stosowanej
Narzędzie pomocnicze do przedmiotu Podstawy Informatyki - złożoność obliczeniowa Piotr Jeruszka1 25 listopada 2013 1 Instytut Informatyki Teoretycznej i Stosowanej Politechnika Częstochowska [email protected] 1 Wstęp Przedstawione narzędzie jest prostym programem (właściwie - kodem źródłowym), mającym pomóc studentom przedmiotu Podstawy Informatyki w zrozumieniu i analizie złożoności obliczeniowej. Głównym zadaniem przedstawionego kodu jest wyliczenie liczby porównań w warunku pętli zewnętrznej (Lz ), wewnętrznej (Lw ) oraz sumarycznej liczby porównań w całym programie (Lc ). W przypadku, gdy użytkownik wyliczył odpowiednie wzory (na Lz , Lw i Lc ) możliwe jest sprawdzenie ich poprawności. Z punktu widzenia użytkownika program składa się z trzech części: • części deklaracyjnej, w której użytkownik podaje liczbę N . Podawane jest również (w formie zmiennej logicznej) opcjonalne wyświetlenie wartości zmiennych przy każdym porównaniu (zmienna dodatki): /* poniżej podaj n */ n = 6; /* jeżeli dodatki = true, to zostaną wypisane kolejne kroki */ dodatki=true; • kodu źródłowego, który jest właściwym obiektem analizy. W tym prostym dokumencie analizowane będzie zadanie 1.1 z 5 listy zadań. Należy samodzielnie „przepisać” algorytm podany w formie pseudokodu/kodu źródłowego na kod źródłowy w języku Java/C++ 1 . • części wypisującej statystyki (w formie wywołania funkcji wypiszStatsyDlaN). Tylko te trzy części powinny być edytowane przez użytkownika. 1 Na obecnym etapie poznawania języków programowania składnia Javy i C++ jest identyczna. 1 2 Wymagania Program został napisany w języku Java. Do kompilacji i uruchomienia programu wymagane są: • kompilator javac; na Windowsie dostępny w pakiecie JDK (dostępny na stronie Oracle), na Linuksach w formie pakietu (Ubuntu: default-jdk). • maszyna wirtualna Javy, zintegrowana z wymienionymi pakietami. 3 Uruchomienie Aby wygodnie pracować z dostarczonym kodem, należy wykonać poniższe kroki. 1. Otworzyć plik Main.java w ulubionym edytorze tekstu bądź wybranym środowisku programistycznym. 2. Ustawić żądaną wartość n - wystarczy po prostu zmienić liczbę, która stoi po prawej stronie operatora =. 3. Można zmienić wartość dodatki na true - spowoduje to wypisanie przy każdym porównaniu aktualnych wartości zmiennych i, j (w przypadku pętli wewnętrznej) i n. 4. W wyznaczonym miejscu: /* Poniżej wpisz kod źródłowy */ ... /* tutaj zakończ wpisywanie kodu źródłowego */ zamiast kropek należy zapisać kod źródłowy. 5. Przed pętlą zewnętrzną należy zapisać literkę z, przed pętlą wewnętrzną należy dopisać literkę w. Z technicznego punktu widzenia jest to wywołanie odpowiednio (statycznych) funkcji z i w, które inkrementują odpowiednie liczniki. 6. Gotowy program należy skompilować, używając programu javac: $ javac Main.java 7. Po poprawnej kompilacji program należy uruchomić w konsoli: $ java Main W przypadku systemów z powłoką bash kompilację i uruchomienie można zastąpić uruchomieniem dostarczonego skryptu o.sh: $ ./o.sh Poprawne uruchomienie spowoduje wyświetlenie odpowiednich wartości, przykładowo: 2 N = 6 Lw = 36 Lz = 7 Lc = 43 a w przypadku ustawienia zmiennej dodatki na true - wartości zmiennych przy każdym porównaniu, przykładowo: Z | i = W | i = W | i = W | i = W | i = W | i = W | i = Z | i = (...) W | i = W | i = Z | i = N = 6 Lw = 36 Lz = 7 Lc = 43 0 0 0 0 0 0 0 1 | | | | | | | | N j j j j j j N = = = = = = = = 5 | j = 5 | j = 6 | N = 6 1 2 3 4 5 6 6 ; | | | | | | ; N N N N N N = = = = = = 5 | N = 6 | N = 6 ; 6 6 6 6 6 6 ; ; ; ; ; ; 6 ; 6 ; (Z oznacza porównanie w pętli zewnętrznej, W - porównanie w pętli wewnętrznej). 4 Przykład Zostanie przedstawione przykładowe użycie programu do sprawdzenia wyliczonych wartości dla zadania 1.1 (5 lista zadań). Zadanie to ma następującą treść: Na podstawie fragmentu pseudokodu podaj liczbę porównań i oszacuj złożoność w sensie notacji O(·) 1. • i=0; • dopóki (i<n) wykonuj: – j=0; – wykonuj: ∗ j=j+1; – dopóki (j<n); – i=i+1; Wyliczamy (co będzie przedstawione na ćwiczeniach) wzory na odpowiednie wartości: Lz = N + 1; Lw = N 2 ; Lc = N 2 + N + 1 (1) co pozwala nam podać złożoność obliczeniową: O(N 2 ). Dla pewności zostanie to sprawdzone dla N = 6. 1. Należy otworzyć plik Main.java i ustawić n=6. Chcemy również, by wyświetlane było każde porównanie: 3 /* poniżej podaj n */ n = 6; /* jeżeli dodatki = true, to zostaną wypisane kolejne kroki */ dodatki=true; 2. Wpisujemy kod źródłowy, który jest tożsamy z pseudokodem. Języki Java/C++ oferują m.in. pętle: while — odpowiednik pętli dopóki (warunek) wykonuj: do...while — odpowiednik pętli wykonuj: ... dopóki (warunek) Dla osób, które nie czują się zbyt pewnie w pisaniu programów w C++ proponowany jest następujący sposób zapisu kodu źródłowego: • należy (w miejsce, gdzie powinien być kod źródłowy) przepisać treść zadania, pamiętając o wcięciach: i=0; dopóki (i<n) wykonuj: j=0; wykonuj: j=j+1; dopóki (j<n); i=i+1; • pętla wykonuj: ... dopóki (warunek) zostanie zapisana w ten sposób: i=0; dopóki (i<n) wykonuj: j=0; do { j=j+1; } while (j<n); i=i+1; • pętla dopóki (warunek) wykonuj: zostanie zapisana w ten sposób: i=0; while (i<n) { j=0; do { j=j+1; } while (j<n); i=i+1; } 4 3. Kolejnym krokiem jest dopisanie odpowiednich literek przed warunkami w pętlach: i=0; while z(i<n) //pętla zewnętrzna { j=0; do { j=j+1; } while w(j<n); //pętla wewnętrzna i=i+1; } (znak // oznacza początek komentarza, nie jest on wymagany w kodzie źródłowym) 4. Ponieważ warunki muszą być zapisane w nawiasach - należy zawrzeć to, co jest podane przy słowie while w dodatkową parę nawiasów: i=0; while (z(i<n)) //pętla zewnętrzna { j=0; do { j=j+1; } while (w(j<n)); //pętla wewnętrzna i=i+1; } Kod analizowanego programu, łącznie z ustawionymi przez użytkownika wartościami powinien wyglądać podobnie do poniższego: public static void main(String[] args) { /* poniżej podaj n */ n = 6; /* jeżeli dodatki = true, to zostaną wypisane kolejne kroki */ dodatki=true; /* Poniższego kodu nie zmieniaj */ (...) */ Poniżej wpisz kod źródłowy */ 5 i=0; while (i<n) { j=0; do { j=j+1; } while (j<n); i=i+1; } /* tutaj zakończ wpisywanie kodu źródłowego */ wypiszStatsyDla(n); } Skompilowanie i uruchomienie spowoduje wyświetlenie na wyjściu programu następującego ciągu znaków: Z W W W W W W Z W W W W W W Z W W W W W W Z W W W W W W Z W W W | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3 3 3 3 4 4 4 4 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | N j j j j j j N j j j j j j N j j j j j j N j j j j j j N j j j = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 6 1 2 3 4 5 6 6 1 2 3 4 5 6 6 1 2 3 4 5 6 6 1 2 3 4 5 6 6 1 2 3 ; | | | | | | ; | | | | | | ; | | | | | | ; | | | | | | ; | | | N N N N N N = = = = = = 6 6 6 6 6 6 ; ; ; ; ; ; N N N N N N = = = = = = 6 6 6 6 6 6 ; ; ; ; ; ; N N N N N N = = = = = = 6 6 6 6 6 6 ; ; ; ; ; ; N N N N N N = = = = = = 6 6 6 6 6 6 ; ; ; ; ; ; N = N = N = 6 ; 6 ; 6 ; 6 W | i = W | i = W | i = Z | i = W | i = W | i = W | i = W | i = W | i = W | i = Z | i = N = 6 Lw = 36 Lz = 7 Lc = 43 4 4 4 5 5 5 5 5 5 5 6 | | | | | | | | | | | j j j N j j j j j j N = = = = = = = = = = = 4 5 6 6 1 2 3 4 5 6 6 | | | ; | | | | | | ; N = N = N = 6 ; 6 ; 6 ; N N N N N N 6 6 6 6 6 6 = = = = = = ; ; ; ; ; ; Jeżeli do sekwencji wzorów (1) zostanie podstawione N = 6, to wartości będą następujące: Lz = 7; Lw = 36; Lc = 43; (2) czyli dokładnie to, co zostało obliczone w programie. 5 Zaawansowana analiza porównań Program oferuje dokładną prezentację porównań. W tym celu przygotowano funkcje (statyczne): Funkcja wieksze(a, b) mniejsze(a, b) wieksze_rowne(a, b) mniejsze_rowne(a, b) rowne(a, b) rozne(a, b) Warunek zastępowany a > b a < b a >= b a <= b a == b a != b które przy zmiennej dodatki==true spowodują wyświetlenie dodatkowych informacji. Należy ich użyć zamiast wbudowanych warunków (funkcji) porównujących. Dla przykładu zostanie użyty utworzony kod do zadania 1.1: i=0; while (z(i<n)) //pętla zewnętrzna { j=0; do { j=j+1; } while (w(j<n)); //pętla wewnętrzna i=i+1; } 7 W przypadku pierwszej pętli while (z(i<n)) //pętla zewnętrzna warunek można zastąpić wywołaniem funkcji mniejsze: while (z(mniejsze(i,n)) //pętla zewnętrzna Podobne działanie można wykonać w pętli wewnętrznej: while (w(mniejsze(j,n)); //pętla wewnętrzna Analizowany kod źródłowy powinien być podobny do poniższego: i=0; while (z(mniejsze(i,n))) { j=0; do { j=j+1; } while (w(mniejsze(j,n))); i=i+1; } Ze względu na sposób działania funkcji orzekających zmodyfikowany kod jest równoznaczny z przeanalizowanym programem z poprzedniego rozdziału. Przy ustawieniu zmiennej dodatki=true wyjście programu powinno być podobne do poniższego: Z | i = W | i = W | i = W | i = W | i = W | i = W | i = Z | i = (...) W | i = W | i = W | i = W | i = W | i = W | i = Z | i = N = 6 Lw = 36 Lz = 7 Lc = 43 0 0 0 0 0 0 0 1 | | | | | | | | N j j j j j j N = = = = = = = = 6 1 2 3 4 5 6 6 ; | | | | | | ; porównanie 0 < 6, wynik: PRAWDA N = 6 ; porównanie 1 < 6, wynik: PRAWDA N = 6 ; porównanie 2 < 6, wynik: PRAWDA N = 6 ; porównanie 3 < 6, wynik: PRAWDA N = 6 ; porównanie 4 < 6, wynik: PRAWDA N = 6 ; porównanie 5 < 6, wynik: PRAWDA N = 6 ; porównanie 6 < 6, wynik: FAŁSZ porównanie 1 < 6, wynik: PRAWDA 5 5 5 5 5 5 6 | | | | | | | j j j j j j N = = = = = = = 1 2 3 4 5 6 6 | | | | | | ; N = 6 ; porównanie 1 < N = 6 ; porównanie 2 < N = 6 ; porównanie 3 < N = 6 ; porównanie 4 < N = 6 ; porównanie 5 < N = 6 ; porównanie 6 < porównanie 6 < 6, wynik: 6, wynik: 6, wynik: 6, wynik: 6, wynik: 6, wynik: 6, wynik: FAŁSZ PRAWDA PRAWDA PRAWDA PRAWDA PRAWDA FAŁSZ Jak można zauważyć - dodatkowym ułatwieniem dla użytkownika jest wyświetlenie dodatkowych informacji o aktualnie porównywanych w warunku pętli wartościach (porównanie 0 < 6) oraz wyniku tego porównania (wynik: PRAWDA). 8 Dodatek: uruchomienie programu w systemie Windows Najłatwiejszym rozwiązaniem jest instalacja pakietu JDK ze środowiskiem programistycznym NetBeans. 1. Na stronie Oracle wyszukujemy pakiet nazwany JDK 7uXX with NetBeans. W chwili pisania tego dokumentu żądany pakiet jest dostępny na tej stronie. Ściągamy wersję dostosowaną do naszego systemu operacyjnego. 2. Instalujemy JDK wraz ze środowiskiem NetBeans. 3. Uruchamiamy NetBeans, następnie z menu File wybieramy kolejno: New Project, Java, Java Application, Next. W polu Create Main Class wpisujemy Main i wciskamy Finish. 4. W nowo otwartym pliku Main.java wklejamy zawartość pliku o tej samej nazwie. 5. Uruchomienie polega na kliknięciu ikony zielonej strzałki w górnym menu środowiska. 9