Zaawansowane algorytmy i struktury danych

advertisement
{2015-02-26, 2015-03-03} by Admirał
Zaawansowane algorytmy i struktury danych
u dr Barbary Marszał-Paszek
Opracowanie pytań praktycznych z egzaminów.
Strona 1 z 12
{2015-02-26, 2015-03-03} by Admirał
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
{2015-02-26, 2015-03-03} by Admirał
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
{2015-02-26, 2015-03-03} by Admirał
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
{2015-02-26, 2015-03-03} by Admirał
Rekursja kończy się dla
, stąd
(
( )
(
( )
( )
( )
(
)
))
∑
∑
(
)
// ( )
, komentarz do zamiany sumy poniżej
( )
( )
// rozwiązanie
Komentarz do przekształcenia sumy
jest równa (
Suma liczb
), 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
{2015-02-26, 2015-03-03} by Admirał
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
{2015-02-26, 2015-03-03} by Admirał
Rekursja kończy się dla
, stąd
(
( )
(
(
( )
( )
( )
)
))
∑
∑
(
)
// ( )
, komentarz do zamiany sumy poniżej
( )
( )
// rozwiązanie
Komentarz do przekształcenia sumy
jest równa (
Suma liczb
), 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
{2015-02-26, 2015-03-03} by Admirał
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
{2015-02-26, 2015-03-03} by Admirał
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
{2015-02-26, 2015-03-03} by Admirał
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
- funkcja sprawdzająca, czy liczba jest parzysta czy nieparzysta
div
- dzielenie całkowitoliczbowe
Strona 10 z 12
{2015-02-26, 2015-03-03} by Admirał
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
{2015-02-26, 2015-03-03} by Admirał
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 log2 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
Download