• Nie Znaleziono Wyników

Ćwiczenia z ASD. Micha l Knapik. Ostatnio kompilowane: 19 marca 2021

N/A
N/A
Protected

Academic year: 2022

Share "Ćwiczenia z ASD. Micha l Knapik. Ostatnio kompilowane: 19 marca 2021"

Copied!
9
0
0

Pełen tekst

(1)

Cwiczenia z ASD ´

Micha l Knapik

Ostatnio kompilowane: 19 marca 2021

(2)

Cwiczenia 1 ´

Poprawno´ s´ c cz

e´ , sciowa i pe lna algorytm´ ow

1.1 Rozgrzewka

Zadanie 1.1.1. Rozwa˙zmy nastepuj, ace funkcje:, FUN1(n):

1. k = 1

2. while (k < n):

3. k := 2*k

4. return k

FUN2(n):

1. k = 1

2. while (k*k < n):

3. k := k + 1

4. return k

Operacje dominujace w FUN1 i FUN2 to dzia lania arytmetyczne. Oblicz dok ladn, a, z lo˙zono´s´c obliczeniowa obu funkcji.,

Zadanie 1.1.2. Uszereguj niemalejaco wzgl, edem rz, edu nast, epuj, ace funkcje:, 1. n!

2. 0.001n5+ n3 3. log(n!) 4. n1000− n999 5. 10000n4+ 999n3, 6. (1.000001)n 7. log(log(n)) 8. n log(n) 9. nn

Zadanie 1.1.3. W dalszej cze´,sci zaje´,c bedziemy zajmowali sie m.in. sortowaniem., Dobre algorytmy sortowania pozwalaja na posortowanie tablicy o rozmiarze n wy-, konujac oko lo nlogn operacji elementarnych. S labsze algorytmy mog, a wymaga´, c n2 operacji elementarnych.

Skr´ot MIPS oznacza liczbe milion´, ow operacji na sekunde. Procesor Zilog Z80, (opracowany w 1976) mo˙ze wykona´c 0.5 MIPS. Procesor AMD Ryzen Threadrip- per 3990X (2020) mo˙ze wykona´c 2300000 MIPS. Przyjrzymy sie, jak brutalna si la, obliczeniowa ma sie do dobrego wyboru algorytm´, ow.

(3)

1. Dobry programista opracowa l algorytm sortujacy w czasie nlogn i uruchomi l go, na maszynie z procesorem Z80. S labszy programista napisa l program sortujacy, w czasie n2i uruchomi l go na maszynie z procesorem AMD Ryzen Threadripper 3990X. Znajd´z wielko´s´c tablicy kt´ora Z80 posortuje szybciej ni˙z AMD Ryzen., 2. Z poprzedniego punktu wynika, i˙z tablica taka bedzie bardzo du˙za. Czy rze-, czywi´scie jest to sukces? Ile czasu potrwa sortowanie tej tablicy przy pomocy maszyny AMD? A ile czasu potrwa loby, gdyby zastosowano na tej maszynie algorytm sortujacy o z lo˙zono´, sci ok. nlogn?

Przyk ladowe rozwiazanie:,

def compare_exec_time(mips1, mips2, n):

"""True iff the worse algorithm is faster or data of size n."""

return n**2/mips1 < n*math.log(n)/mips2 n = 10

while compare_exec_time(2300000, 0.5, n):

n += 100

print(f’Z80 starts winning at n={n}’)

print(f’It would take AMD {(n**2/2300000)/(60*60*24*365)}’

’years using slower algorithm...’)

print(f’and {(n*math.log(n,2)/2300000)/(60)} minutes with faster?!’) Zadanie 1.1.4. Por´ownaj nastepuj, ace funkcje:,

FUN3(n):

1. m = 1

2. for i = 1 to 3

3. m := m*m

4. for j = 1 to n

5. m := m+j

4. return m

FUN4(n):

1. m = 1

2. for i = 1 to n

3. m := m*m

4. for j = 1 to 3

5. m := m+j

4. return m

Kt´ora ma wieksz, a z lo˙zono´, s´c obliczeniowa? Oblicz szybko oszacowanie dolne na, warto´s´c (nie z lo˙zono´s´c) F U N 3(n) i F U N 4(n), u˙zywajac notacji Ω. Jakiego ro-, dzaju gwarancje daje to oszacowanie? Przetestuj eksperymentalnie implementacje w, Pythonie.

1.2 Podstawowe definicje

Algorytm ma w lasno´s´c pe lnej poprawno´sci, gdy dla wszystkich danych wej´sciowych:

1. je´sli dane wej´sciowe sa poprawne (zgodne ze specyfikacj, a wej´, scia), to algorytm po zatrzymaniu sie zwr´, oci poprawny wynik (zgodny ze specyfikacja),,

2. je´sli dane wej´sciowe sa poprawne, to algorytm w ko´, ncu zatrzyma sie.,

Algorytm jest cze´,sciowo poprawny, gdy spe lniony jest pierwszy z powy˙zszych warunk´ow. Drugi warunek jest zazwyczaj nazywany warunkiem stopu i jest, swoja, droga, nierozstrzygalny - tzn. nie istnieje algorytm U, kt´, ory biorac pseudokod do-, wolnego algorytmu A i dowolne dane wej´sciowe x powie nam, czy A zatrzyma sie, po wykonaniu na danych x.

(4)

Zadanie 1.2.1. Napisa´c jednolinijkowy algorytm, trywialnie cze´,sciowo poprawny dla dowolnych danych.

Przyk ladowe rozwiazanie:, Alg(x):

while (true) PASS

Powy˙zszy algorytm jest cze´,sciowo poprawny, niezale˙znie od specyfikacji - bowiem nigdy sie nie zatrzyma.,

Specyfikacja danych wej´sciowych sk lada sie zazwyczaj z opisu typu, wraz z ew., dodatkowym jego zawe˙zeniem. Poprawne dane to dane zgodne z t, a specyfikacj, a,, czesto wyra˙zon, a jako formu la pewnej logiki. Poprawno´, s´c zwracanego wyniku wery- fikowana jest w podobny spos´ob - powinna by´c zgodna z pewna specyfikacj, a. Istniej, a, jezyki takie jak Ada-Spark, w kt´, orych mo˙zna formu lowa´c w/w warunki poprawno´sci explicite i pr´obowa´c statycznie weryfikowa´c programy. Jezyki te s, a u˙zywane do´, s´c sporadycznie, g l´ownie w tzw. zastosowaniach krytycznych.

1.3 Metoda niezmiennik´ ow

Metoda niezmiennik´ow s lu˙zy do dowodzenia poprawno´sci program´ow. Niezmiennik petli to warunek (specyfikowany formalnie lub w j, ezyku bardziej naturalnym), kt´, ory jest:

ˆ prawdziwy przed pierwsza iteracj, a p, etli (inicjalizowanie);,

ˆ oraz je´sli by l prawdziwy przed dana iteracj, a p, etli, to b, edzie prawdziwy i po, niej (utrzymanie).

Je´sli wiec udowodnimy, ˙ze dana w lasno´, s´c jest niezmiennikiem petli oraz p, etla za-, trzyma sie po sko´, nczonej liczbie iteracji, to wyka˙zemy, ˙ze niezmiennik bedzie praw-, dziwy po zako´nczeniu petli. Oczywi´, scie musi by´c on zbudowany tak zrecznie, by, wynika lo z tego, ˙ze badany program jest poprawny.

Zadanie 1.3.1 (Schemat Hornera). Celem jest efektywne obliczenie warto´sci wielo- mianu f (x) = Pn

i=0aixi. Jako dane wej´sciowe podana jest tablica wsp´o lczynnik´ow wielomianu A[0, . . . , n]. Algorytm powinien realizowa´c obliczenia zgodnie ze wzor- cem:

f (x) = a0+ x(a1+ x(a2+ . . . x(an−1+ xan))).

Zapisz pseudokod algorytmu i zbadaj pe lna poprawno´, s´c algorytmu.

Przyk ladowe rozwiazanie:, HORNER(A,x):

1. res := 0

2. i := len(A) - 1 3.

4. while (i >= 0):

5. res += A[i] + x*res

6. i--

7.

8. return res

Warunek stopu jest spe lniony w oczywisty spos´ob - petla while musi si, e zatrzy-, ma´c dla poprawnych danych wej´sciowych (a wiec domy´, slnie dla i = n, gdzie n ∈ N), i to w n + 1 krokach.

Niezmiennik petli. Zacznijmy od przyk ladu, kt´, ory pozwoli na zbudowanie pew- nej intuicji. Za l´o˙zmy, ˙ze f (x) = 9x3− 3x2 + 7x − 4 i przyjrzyjmy sie zawarto´, sci zmiennej res podczas kolejnych iteracji:

ˆ Gdy i = 0 to res = 0 przed wykonaniem iteracji i res = 9 po wykonaniu.

(5)

ˆ Gdy i = 1 to res = 9 przed i res = 9x − 3 po wykonaniu iteracji.

ˆ Gdy i = 2 to res = 9x − 3 przed i res = 9x2− 3x + 7 po.

ˆ Gdy i = 3 to res = 9x2− 3x + 7 przed i res = 9x3− 3x2+ 7x − 4 po.

Mo˙zemy wiec sformu lowa´, c niezmiennik petli w nast, epuj, acy spos´, ob:

ˆ Gdy i = n, to res = 0.

ˆ W przeciwnym przypadku res = Pnj=i+1A[j]xj−(i+1).

Prawdziwo´s´c tego warunku dla i = n jest oczywista. Dla porzadku zauwa˙zmy, ˙ze, po pierwszej iteracji petli mamy i = n − 1 i res = A[n] =, Pn

j=n−1+1A[j]xj−((n−1)+1). Zajmijmy sie utrzymaniem warunku. Je´, sli przed rozpoczeciem i–tej iteracji (tzn., znajdujac si, e w linijce 4) mamy:,

res =

n

X

j=i+1

A[j]xj−(i+1),

to wykonanie linijki 5 zmodyfikuje nam zawarto´s´c zmiennej res nastepuj, aco:,

res = A[i] + x ∗ (

n

X

j=i+1

A[j]xj−(i+1)),

a po dalszych transformacjach otrzymamy warto´s´c zmiennej res po i–tej iteracji:

res = A[i] +

n

X

j=i+1

A[j]xj−i=

n

X

j=i

A[j]xj−i.

W kolejnej linijce warto´s´c zmiennej i jest zmniejszona o jeden, wiec powy˙zsza za-, le˙zno´s´c zapisana przy u˙zyciu nowej warto´sci tej zmiennej przyjmie posta´c:

res =

n

X

j=i+1

A[j]xj−(i+1).

Ko´nczymy, przygladaj, ac si, e zawarto´, sci zmiennej res po wykonaniu ostatniego kroku petli. Krok ten zaczyna si, e z i = 0 a ko´, nczy z i = −1.

res =

n

X

j=−1+1

A[j]xj−(−1+1)=

n

X

j=0

A[j]xj.

A to jest dok ladnie to o co chodzi lo, czyli warto´s´c f (x).

1.4 W stron e analizy z lo˙zono´

,

sci

Schemat Hornera pozwala na obliczenie warto´sci wielomianu w czasie liniowym. Na- iwne podej´scie do tego problemu daje algorytm dzia lajacy w czasie kwadratowym., Zr´´ od lem z lo˙zono´sci jest tu potegowanie, realizowane przez szereg mno˙ze´, n. Spr´obu- jemy teraz zaprojektowa´c algorytm pozwalajacy na szybkie pot, egowanie.,

Zadanie 1.4.1. Wykorzystaj przedstawienie wyk ladnika w postaci binarnej do za- implementowania efektywnego potegowania i oszacuj z lo˙zono´, s´c algorytmu. Zapisz pseudokod funkcji FASTPOW(n, k) = nk. Podpowied´z: zauwa˙z, ˙ze n11dec = n1011bin = n1·23+0·22+1·21+1·20 = n23 · n21 · n20. Zaobserwuj zgodnie z jaka regu l, a jest tworzony, nastepuj, acy ci, ag: n, 1, (n2)2= n22, ((n2)2)2= n23, . . .

Przyk ladowe rozwiazanie (z przeliczaniem decymalne-binarne w locie):,

(6)

FASTPOW(n,k):

1. if k == 0 return 1

2. if (k mod 2 == 1) res := n 3. else res := 1

4. k = k/2 8. mult = n*n 5. while (k > 0)

6. if (k mod 2 == 1) res *= mult

7. k = k/2

8. mult = mult*mult

9. return res

Zadanie 1.4.2. Wykorzystaj zale˙zno´s´c:

nk= (

n(nk−12 )2 dla k nieparzystych, (nk2)2 dla k parzystych

do zaprojektowania algorytmu efektywnego potegowania. U˙zyj rekursji (metoda dziel, i rzad´, z). Przygotuj r´ownanie rekurencyjne na pesymistyczna z lo˙zono´, s´c czasowa roz-, wiazania i oszacuj j, a.,

Przyk ladowe rozwiazanie:, RPOW(n,k):

1. if (k == 0) return 1

2. if (k mod 2 == 1) return n * (rpow(n, (k-1)/2)* rpow(n, (k-1)/2)) 3. else return (rpow(n, k/2)* rpow(n, k/2))

R´ownanie rekurencyjne dla z lo˙zono´sci pesymistycznej:

T (k) =

 1 + T (k−12 ) dla k nieparzystych, 1 + T (k2) dla k parzystych

(7)

Cwiczenia 2 ´

Wyszukiwanie i sortowanie - pocz atki ,

2.1 Algorytm wyszukiwania binarnego

Idea algorytmu binarnego wyszukiwania elementu e w ciagu uporz, adkowanym arr:, 1. Inicjalizacja l := 0, p := len(arr) − 1.

2. Element e, o ile jest obecny w ciagu, znajduje si, e w przedziale indeksowanym, [l, p]. Je´sli p < l, zwr´o´c -1 (e nie wystepuje w arr).,

3. Obejrzyj warto´s´c mediany: med = arr[bl+p2 c]. Je´sli med = e, zwr´o´c bl+p2 c.

4. Je˙zeli med < e, niech l = bl+p2 c + 1 i wr´o´c do 2.

5. Je˙zeli med > e, niech p = bl+p2 c − 1 i wr´o´c do 2.

Zadanie 2.1.1. Wypisz elementy z kt´orym zostanie por´ownany klucz e przy wyszuki- waniu go w ciagu arr:,

ˆ e = 251, arr = [0, 1, 3, 7, 11, 210, 113, 251, 325, 412, 1213, 2351].

ˆ e = 2, arr = [0, 1, 3, 7, 11, 210, 113, 251, 325, 412, 1213, 2351].

Zadanie 2.1.2. Implementacja z wyk ladu wyszukiwania binarnego nie korzysta z re- kurencji. Zaprojektuj rekurencyjna wersj, e wyszukiwania binarnego. Jakie s, a zalety, a jakie wady rekurencji?

Przyk ladowe rozwiazanie:, Rec-BinSearch(s,l,p,e):

if l > p return -1 m = floor((l+p)/2) if s[m] = e return e

if s[m] < e return Rec-BinSearch(s, m+1, p) if s[m] > e return Rec-BinSearch(s, l, m-1)

Zadanie 2.1.3. UVA: 10611 - The Playboy Chimp. Podpowied´z: zastosuj algorytm wyszukiwania binarnego zwracajacy ostatnio sprawdzany indeks zamiast -1 i obejrzyj, elementy sasiaduj, ace ze zwr´, oconym indeksem.

Zadanie 2.1.4. Metoda bisekcji s lu˙zy do znajdowania pierwiastk´ow r´ownania f (x) = 0. Zak ladamy, ˙ze f jest funkcja rzeczywist, a, ci, ag l, a, okre´, slona na przedziale [a, b], i taka, ˙ze f (a) · f (b) < 1 (dlaczego to wystarczy, by istnia l pierwiastek w w/w, przedziale?). Zaprojektowa´c algorytm, kt´ory dla zadanego  > 0 znajduje przedzia l [c, d] ⊆ [a, b] zawierajacy pierwiastek f i taki, ˙ze (d − c) ≤ .,

(8)

2.2 Algorytm turniejowy

Cel algorytmu turniejowego: znale´z´c drugi najmniejszy element e w ciagu nieupo-, rzadkowanym arr zawieraj, acym elementy bez powt´, orze´n. Idea dzia lania:

1. Zbuduj najni˙zsze pietro drzewa binarnego, z lo˙zone z element´, ow arr. Bedziemy, budowali drzewko od tej podstawy, ku zwie´nczeniu.

2. Budujemy nowe pietro. Iteruj (np. od lewej) po parach s, asiednich w, ez l´, ow po- przedniego pietra (˙zadne dwie pary nie maj, a wsp´, olnych element´ow). Z ka˙zdej takiej pary (node(arr[i]), node(arr[i + 1])) wybierz mniejszy element i umie´s´c go w nowym we´,zle. Lewa i prawa ga la´,z nowego wez la powinny prowadzi´, c do, odpowiednio, wez l´, ow zawierajacych arr[i] i arr[i + 1]. Je´, sli poprzednie pietro, mia lo nieparzysta liczb, e element´, ow, przepisz element, kt´ory nie wzia l udzia lu, w por´ownaniach do nowego pietra.,

3. Je˙zeli najnowsze pietro ma wi, ecej ni˙z jeden element, wr´, o´c do punktu2.

4. Je´sli ma tylko jeden element, jest to element najmniejszy mine. Zejd´z od korzenia w d´o l drzewa po wez lach zawieraj, acych mine, ogl, adaj, ac elementy, por´ownywane z mine. Wybieramy najmniejszy z tych element´ow.

Zadanie 2.2.1. Narysuj drzewko por´ownywa´n w algorytmie turniejowym dla ciagu, arr = [7, 4, 9, 1, 8, 15].

Zadanie 2.2.2. Dlaczego element znaleziony w czasie schodzenia w d´o l drzewka jest drugim najmniejszym w ciagu?,

2.3 Statystyki pozycyjne

Niech arr bedzie ci, agiem (dla uproszczenia - r´, o˙znych) nieuporzadkowanych liczb., i–ta statystyk, a pozycyjn, a nazwiemy i–ty najmniejszy element arr, gdzie 0 ≤ i <,

|arr| (tradycyjnie, liczymy od 0). Na wyk ladzie przedstawiono zarys algorytmu wykorzystujacego podzia ly Hoare’a, obliczaj, acego statystyki pozycyjne w ´, srednim czasie liniowym (przy za lo˙zeniu zrandomizowanego wyboru elementu dzielacego w, podziale Hoare’a). Za l´o˙zmy, ˙ze mamy procedure Hoare-Partition(arr, p, r),, kt´ora:

1. zwraca indeks q taki, ˙ze p ≤ q ≤ r, oraz

2. permutuje tablice arr[p . . . r] w taki spos´, ob, ˙ze elementy arr[p . . . (q − 1)] sa, mniejsze od element´ow arr[(q + 1) . . . r], za´s element arr[q] jest na w la´sciwym miejscu (tzn. tam, gdzie znalaz lby sie po posortowaniu arr).,

Ilustracja: je´sli arr = [5, 1, 4, 9, 3, 8], to przyk ladowe wykonanie procedury Hoare- Partition(arr, 0, 6) mo ˙ze zwr´oci´c q = 3 i zmodyfikowa´c tablice arr = [3, 1, 4, 5, 9, 8]., Pomimo, i˙z nie jest posortowana, to warto´s´c 5 znalaz la sie na swoim miejscu.,

Procedura Select(arr, p, r, i) wykorzystuje podzia ly Hoare’a w celu reku- rencyjnego wyszukania i–tej statystyki tablicy arr [p. . . r].

Select(arr, p, r, i):

if p = r then return arr[p]

q = Hoare-Partition(arr, p, r) k = q - p + 1

if i = k then return arr[q]

if i < k then return Select(arr, p, q-1, i) else return Select(arr, q+1, r, i-k)

Szczeg´o ly procedury Hoare-Partition(arr, p, r) zostana przedstawione przy, okazji algorytmu QuickSort.

Zadanie 2.3.1. Znale´z´c najgorszy przypadek dla procedury Select i okre´sli´c jego z lo-

˙zono´s´c.

(9)

2.4 Sortowanie - pocz atki

,

Algorytm sortowania przez wstawianie (InsertionSort) polega na wstawianiu w ju˙z posortowana pocz, atkow, a cz,,s´c tablicy kolejnego elementu e. Polega to na przesu- waniu element´ow w prawo, dop´oty, dop´oki nie znajdziemy w la´sciwego miejsca do wstawienia e. Algorytm ma do´s´c elegancka i prost, a implementacj, e (patrz wyk lad),, ale jego ´srednia z lo˙zono´s´c jest kwadratowa.

Zadanie 2.4.1. Zasymuluj dzia lanie InsertionSort na tablicy arr = [4, 1, 5, 1, 6, 9, 10].

Okre´sl pesymistyczny (najwieksza liczba por´, owna´n) i optymistyczny (najmniejsza) przypadek dla tego algorytmu.

Zadanie 2.4.2. InsertionSort ma swoja nieco bardziej praktyczn, a wersj, e - sortowanie, Shella (ShellSort). Zapoznaj sie z opisem tego algorytmu i przetestuj kilka wybranych, sekwencji wyboru kroku.

Algorytm sortowania jest stabilny, je´sli posortowana tablica zachowuje pierwotna, kolejno´s´c element´ow o tych samych kluczach. Rozwa˙zmy tablice arr = [3, 1, 4,, 3, 5].

Zak ladamy tutaj, ˙ze elementy tablicy posiadaja jak,,s strukture wewn, etrzn, a, odr´, o˙z- niajace czerwon, a tr´, ojke od niebieskiej. Stabilny algorytm sortowania zastosowany do, arr zwr´oci [1,3,3, 4, 5]. Niestabilny mo˙ze zwr´oci´c [1,3,3, 4, 5]. Stabilno´s´c jest war- to´sciowa cech, a - rozwa˙zmy sytuacj, e, gdy sortujemy ksi, a˙zk, e telefoniczn, a, najpierw, po imionach, potem po nazwiskach.

Zadanie 2.4.3. Rozwa˙zmy dwie wersje algorytmu InsertionSort (tym razem zapisane w pseudoJavie):

insertionSortA(arr, len){

for(next = 1; next < len; next++){

curr = next;

temp = arr[next];

while((curr > 0) && (temp < arr[curr - 1])){

arr[curr] = arr[curr - 1];

curr--;

}

arr[curr] = temp;

} }

insertionSortB(arr, len){

for(next = 1; next < len; next++){

curr = next;

temp = arr[next];

while((curr > 0) && (temp <= arr[curr - 1])){

arr[curr] = arr[curr - 1];

curr--;

}

arr[curr] = temp;

} }

Kt´ory z nich jest stabilny i dlaczego?

Cytaty

Powiązane dokumenty

W walec jest wpisana kula i sto˙zek (podstawa walca jest taka sama jak podstawa sto˙zka, a wierzchołek sto˙zka le˙zy na drugiej

Na ile sposob´ow mo˙zna podzieli´c 5 kanapek na 3 nierozr´o˙znialne talerze przy czy na ka˙zdym talerzu mo˙ze by´c dowolna liczba kanapek (w l¸acznie z zerem) oraz a) kanapki

Na ile sposob´ow mo˙zna podzieli´c 5 kanapek na 3 nierozr´o˙znialne talerze przy czy na ka˙zdym talerzu mo˙ze by´c dowolna liczba kanapek (w l¸acznie z zerem) oraz a) kanapki

Oblicz warto´s˙c oczekiwan¸a i odchylenie standardowe wygranej w t-tym rzucie monet¸a.. Wyniki zinterpetuj

[r]

Czy prawd¸a jest, ˙ze ka˙zdy graf, kt´ory posiada dobre 3-pokolorowanie nie zawiera K 4 jako minora?.

[r]

Zatem mamy jedną klatkę wielkości 1, i jedną wielkości ­ 2, czyli musi mieć wielkość 3.. Zatem mamy jedną klatkę wielkości 1, i jedną wielkości ­ 2, czyli musi mieć