Zaawansowane algorytmy i struktury danych u dr Barbary Marszał-Paszek Opracowanie pytań praktycznych z egzaminów. Strona 1 z 12
Pytania praktyczne z kolokwium zaliczeniowego z 19 czerwca 2014 (studia dzienne) oraz 27 lutego 2015 (studia zaoczne). 1. Rozwiąż poniższe równanie rekurencyjne: { 2. Poniżej zaprezentowano algorytm wyszukiwania binarnego elementu w tablicy. Zakładamy, że szukany element występuje w tablicy dokładnie raz. Przyjmij, że procedura jest wywołana z parametrami i gdzie liczba jest tak dobrana, że Search (A, l, r, x) 1 s (l+r) div 2 2 if A[s] = x 3 then return s 4 else if A[s] > x 5 then return Search(A, l, s-1, x) 6 else return Search(A, s+1, r, x) Zapisz równanie rekurencyjne dla powyższego algorytmu opisujące jego złożoność pesymistyczną ze względu na porównywanie kluczy w tablicy A. Następnie rozwiąż to równanie. Strona 2 z 12
Pytania praktyczne z egzaminu pisemnego z 25 czerwca 2014 (studia dzienne). 1. Rozwiąż poniższe równanie rekurencyjne: { 2. Poniżej zaprezentowano algorytm wyliczenia iloczynu dwóch liczb całkowitych takich, że oraz. Iloczyn (n, m) 1 P 0 2 N n 3 s m 4 while N > 0 5 do if odd(n) 6 then P P + s 7 N N div 2 8 s 2 * s 9 return P Przeanalizuj ten algorytm ze względu na operacje i występujące w 6 i 8 linijce kodu. Podaj złożoność optymistyczną i pesymistyczną dla zaprezentowanego algorytmu. Pytania praktyczne z egzaminu pisemnego z 15 oraz 27 lutego 2015 (studia zaoczne) 1. Rozwiąż poniższe równanie rekurencyjne: { 2. Algorytm mnożenia rosyjskich chłopów - to samo zadanie o mnożeniu liczb co na egzaminie z 25 czerwca 2014. Strona 3 z 12
1. Rozwiąż poniższe równanie rekurencyjne: { Rozwiązanie metodą iteracyjną Rozpiszmy wzory na poszczególne wyrazy ciągu : ( ) Będziemy teraz "rozwijali równanie" aż zobaczymy jakąś zależność. We wzorze będziemy teraz podstawiać za wyraz wzór na co raz "dalsze" wyrazy tego ciągu (wzory te zapisaliśmy powyżej, dla ułatwienia oznaczyłem kolorem kolejne podstawienia). ( ) ( ) Strona 4 z 12
Rekursja kończy się dla, stąd ( ) //, komentarz do zamiany sumy poniżej // rozwiązanie Komentarz do przekształcenia sumy Suma liczb jest równa, gdyż Szybkie sprawdzenie Prawidłowo powinno się to sprawdzić przez indukcję, natomiast można wstępnie się zorientować czy otrzymany wzór jest w porządku przez porównanie wyników ze wzoru pierwotnego i wzoru uzyskanego. Wyniki na postawie wzoru pierwotnego Wyniki na podstawie wzoru uzyskanego Na egzaminie możemy założyć, że prawidłowo rozwiązaliśmy równanie Także w trakcie ćwiczeń taki sposób sprawdzenia bardzo się przydaje. Strona 5 z 12
2. Rozwiąż poniższe równanie rekurencyjne: { Zadanie praktycznie takie samo jak poprzednie, różni się tylko stałą Rozwiązanie metodą iteracyjną Rozpiszmy wzory na poszczególne wyrazy ciągu : ( ) Będziemy teraz "rozwijali równanie" aż zobaczymy jakąś zależność. We wzorze będziemy teraz podstawiać za wyraz wzór na co raz "dalsze" wyrazy tego ciągu (wzory te zapisaliśmy powyżej, dla ułatwienia oznaczyłem kolorem kolejne podstawienia). ( ) ( ) Strona 6 z 12
Rekursja kończy się dla, stąd ( ) //, komentarz do zamiany sumy poniżej // rozwiązanie Komentarz do przekształcenia sumy Suma liczb jest równa, gdyż Szybkie sprawdzenie Prawidłowo powinno się to sprawdzić przez indukcję, natomiast można wstępnie się zorientować czy otrzymany wzór jest w porządku przez porównanie wyników ze wzoru pierwotnego i wzoru uzyskanego. Wyniki na postawie wzoru pierwotnego Wyniki na podstawie wzoru uzyskanego Na egzaminie możemy założyć, że prawidłowo rozwiązaliśmy równanie Także w trakcie ćwiczeń taki sposób sprawdzenia bardzo się przydaje. Strona 7 z 12
3. Rozwiąż poniższe równanie rekurencyjne: { Rozwiązanie Rozwijamy równanie podstawiając za wyraz : ( ) [ ( ) ] ( ) ( ) Wynika z tego, że: itd. ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) Otrzymujemy w ten sposób zapis dla stopnia rekurencji ( ) Chcemy teraz uzyskać w tym zapisie zależność od, dlatego podstawiamy za (ponieważ logarytmowanie jest odwrotnością potęgowania). wyraz ( ) // komentarz do tych przekształceń znajduje się poniżej // // rozwiązanie Strona 8 z 12
Komentarz - można sprawdzić indukcyjnie (albo na kalkulatorze ). - to również można sprawdzić na kalkulatorze. Rozwiązaniem jest więc: Szybkie sprawdzenie Wyniki na postawie wzoru pierwotnego Wyniki na podstawie wzoru uzyskanego ( ) ( ) ( ) ( ) Wygląda na to, że równanie to jest określone tylko dla wyrazów będących potęgą dwójki. To jest mój wniosek. Wiem, że to zadanie przeszło u Paszkowej i kolega na jego podstawie zaliczył kolokwium. Strona 9 z 12
4. Poniżej zaprezentowano algorytm wyliczenia iloczynu dwóch liczb całkowitych takich, że oraz. Iloczyn (n, m) 1 P 0 2 N n 3 s m 4 while N > 0 5 do if odd(n) 6 then P P + s 7 N N div 2 8 s 2 * s 9 return P Przeanalizuj ten algorytm ze względu na operacje i występujące w 6 i 8 linijce kodu. Podaj złożoność optymistyczną i pesymistyczną dla zaprezentowanego algorytmu. Nie wiem jak to rozwiązać, skopiowałem opis z http://ms.fhp.org.pl/?q=node/214 To nie jest rozwiązanie zadania! To ma tylko naprowadzić na to, o czym jest mowa. Należy mieć też na uwadze, że pisane było to przez dwie dziewczynki, stąd jest tu parę błędów i nieścisłości. Teoria Algorytm ten to "Algorytm mnożenia rosyjskich chłopów". Algorytm był znany już egipskim matematykom 1800 lat p.n.e. Nazwany jednak został jako mnożenie rosyjskich chłopów ze względu na powszechne zastosowanie go w Rosji w wieku XIX. W algorytmie wykorzystuje się przedstawienie jednej z liczb w systemie binarnym. Z tego wynika, iż pomysł takiego rozkładu liczby w obliczeniach miał miejsce na długo przed wykorzystaniem jej w arytmetyce komputerowej. Wykorzystane funkcje odd div - funkcja sprawdzająca, czy liczba jest parzysta czy nieparzysta - dzielenie całkowitoliczbowe Strona 10 z 12
Przykład wykorzystania Weźmy dwie liczby naturalne, które chcemy pomnożyć. Niech będą to np. 129 i 46. Na początku należy zapisać liczby w dwóch kolumnach: Następnie pierwszą liczbę (129) mnożymy przez 2, a drugą (46) dzielimy przez 2 (całkowicie). Wykonujemy działania do momentu, gdy w drugiej kolumnie pojawi się 1. Kolejnym krokiem jest wykreślenie wierszy, w których liczba z drugiej kolumny jest podzielna przez 2 oraz dodanie do siebie wszystkich niewykreślonych liczb z kolumny pierwszej. Takim sposobem otrzymujemy wynik działania:. Strona 11 z 12
Omówienie działania Algorytm mnożenia chłopów rosyjskich jest wersją mnożenia pisemnego, ale przy podstawie nie 10, lecz 2. W naszym przykładzie, w którym wykorzystaliśmy liczby 129 i 46, druga liczba (46) jest zamieniania na system binarny poprzez dzielenie całkowitoliczbowe przez 2. Mnożenie polega na tym, że mnożymy kolejne bity (czyli tam, gdzie bit wynosi 1) druga liczba zostałaby po prostu przepisana (czyli tak, jak w mnożeniu pisemnym). W przypadku, gdy bit wynosi 0, otrzymujemy liczbę 0. Następnie, sumujemy kolejne kolumny (znów tak, jak w mnożeniu pisemnym). Złożoność algorytmu 1. Złożoność obliczeniowa Złożoność obliczeniowa tego algorytmu jest logarytmiczna. Co to oznacza? Złożoność logarytmiczną mają na przykład algorytmy, których problem postawiony dla danych rozmiaru da się sprowadzić w pesymistycznym przypadku do problemu z rozmiarem danych o połowę mniejszym. Dlaczego? Z każdym obrotem pętli y zmniejsza się 2 razy. Zatem liczba obrotów pętli, to [ ]+1. Mamy tylko tyle przekształceń, ile wynosi log 2 z mniejszego z czynników. 2. Złożoność czasowa Po sprawdzeniu szybkości działania programu, okazało się, że dla różnych liczb z zakresu long long int (a nawet po wyeliminowaniu ujemnych [unsigned]) czas wykonywania algorytmu za każdym razem wynosił poniżej 1s. Z tego można wywnioskować, że pętla się bardzo szybko wykonuje, nawet dla bardzo dużych liczb. Strona 12 z 12