Analiza Algorytmów - Moduł 2- Ćwiczenia Aleksandra Orpel 1 Niezmienniki pętli Ćwiczenie 1. Wykaż, że podany warunek "k 4 > 2m 6 " jest niezmiennikiem pętli 1while 1 mdo 2 3 m := 2m; 4 k := 3k; 5 end: Rozwiazanie: Załóżmy, że zdanie k 4 > 2m 6 jest prawdziwe oraz 1 m: Pokażemy, że pozostaje ono prawdziwe po wykonaniu poleceń zwierszy3i4, tj. zachodzi nierówność (3k) 4 > 2(2m) 6 : Istotnie: 2(2m) 6 =2 7 m 6 < 2 6 k 4 =64k 4 < 3 4 k 4 : Zatem zdanie (p) jest niezmiennikiem rozważanej pętli. Ćwiczenie 2. Rozważmy pętlę 1 while j kdo 2 3 i := i +2; 4 j := j +1; 5 end: gdzie i; j sa liczbami całkowitymi. Sprawdzić, czy warunek ((p)) (a) (b) "i <j 2 " (1) jest niezmiennikiem powyższej pętli, jeśli k =1? "i j 2 " (2) jest niezmiennikiem powyższej pętli, jeśli k =0? Rozwiazanie: Niech i; j będa dowolnymi liczbami całkowitymi. (a) Załóżmy, że i < j 2 oraz j 1: Aby pokazać, że (1) jest niezmiennikiem pętli, należy dowieść nierówności i +2< (j +1) 2 : Korzystajaczzałożenia (i <j 2 i j 1) mamy co było dookazania. (j +1) 2 = j 2 +2j +1 i +2j +1 i +2; 1
(b) Przypuśćmy, że prawdziwe sa zdania(2) i" j 0": Sprawdzimy, czy po wykonaniu poleceń pętli (wiersze 3 i 4), (2) pozostaje prawdziwe. Postępujac jak w poprzednim przypadku mamy (j +1) 2 = j 2 +2j +1 i +2j +1: Zauważamy, że dla dowolnej liczby całkowitej j nie możemy oszacowaćzdołuwyrażenia 2j+1 przez 2, gdyż naprzykład dla j =0przyjmuje ono wartość 1. Kładac i = j =0; stwierdzamy, że warunek (2) jest spełniony przed wykonaniem poleceń pętli oraz j =0 0: Jednocześnie po wykonaniu wierszy 3i4i =2zaś j =1i wówczas zdanie (2) jest fałszywe. Oznacza to, że (2) nie jest niezmiennikiem pętli. Ćwiczenie 3. Rozważmy ciag instrukcji s:=2; i:=1; while 1 i do wypisz s; s:=s+2i+1; i:=i+1; end. Zbadać, czy warunek "s = i 2 +1" (p) jest niezmiennikiem powyższej pętli while: Podać 123 liczbę wypisana przez ten algorytm? Rozwiazanie: Aby orzec, czy zdanie p jest niezmiennikiem powyższej pętli, należy zbadać prawdziwość następujacej implikacji h s 8 i;s2n = i 2 +1 ^ i 1 i ) s +2i +1=(i +1) 2 +1 : Załóżmy więc, że poprzednik implikacji jest prawdziwy. Wówczas (i +1) 2 +1=i 2 +2i +1+1=s +2i +1; przy czym ostatnia równość wynikazzałożenia s = i 2 +1: Zatem p jest niezmiennikiem rozważanej pętli. Łatwo widać, że 123 liczba wypisana przez ten algorytm jest wartościazmiennejs po 122 iteracji pętli, a wówczas i = 123: Jeśli zatem będziemy mogli stwierdzić, że p jest prawdziwe niezależnie od numeru iteracji, to będzie można wykorzystać zwiazek między wartościami zmiennych s oraz i do uzyskania żadanej odpowiedzi. Należy zatem posłużyć się twierdzeniem o niezmiennikach pętli. Ponieważ wykazaliśmy już, że p jest niezmiennikiem pętli, wystarczy jeszcze zauważyć, że warunek p jest prawdziwy przed wejściem wpętlę, tj. dla poczatkowych wartości przypisanych zmiennym i oraz s (i =1i s =2): Zatem wszystkie założenia twierdzenia 3 sa spełnione. Na mocy pierwszej części jego tezy stwierdzamy, że zdanie p pozostaje prawdziwe po każdej iteracji pętli, w szczególności po 122: przebiegu. Stad 123: liczba wypisana przez ten algorytm jest równa 123 2 +1: 2 Badanie poprawności algorytmów Następne ćwiczenia pokaża wykorzystanie twierdzenia o niezmiennikach pętli do dowodów poprawności algorytmów Ćwiczenie 4. Wykaż, że algorytm Bin(n) t := n; k := 0; while t 1 do k := k +1; b[k] :=t mod 2; t := tdiv2; end; 2
end. zwraca tablicę b zawierajaca reprezentację binarnaliczbyn poczynajac od najmniej znaczacych bitów. Zakładamy, że na poczatku tablica b została wyzerowana. Rozwiazanie: Pokażemy, że zdanie p: "Jeżeli tablica b jest reprezentacjabinarn aliczbynaturalnej m (rozpoczynajac od najmniej znaczacych bitów); to n = t 2 k + m:" jest niezmiennikiem pętli "while": Załóżmy więc, że p jest prawdziwe przed wykonaniem poleceń pętli w powyższym algorytmie oraz t>0. (Wtedy dla pewnego k 2 N mamy b[l] =0; dla każdego l>koraz m = b[1] 2 0 +b[2] 2 1 +:::+b[k] 2 k 1 ): Po wykonaniu poleceń pętli mamy b[l] =0; dla każdego l>k+1: Ponieważ k +1: element tablicy b jest 0 lub 1 wzależności od parzystości zmiennej t; rozważymy dwa przypadki. Przypuśćmy najpierw, że t jest liczbaparzyst a. Wówczas b[k +1]=0i liczba m nie ulega zmianie w czasie wykonywania poleceń pętli, zatem W drugim przypadku b[k +1]=1i mamy t 2 2k+1 + m = n: t 1 2 k+1 + m +2 k = t 2 k 2 k + m +2 k = t 2 k + m = n; 2 gdzie ostatnia równość wynikazzałożenia. Podsumawujac, w obu przypadkach zdanie p pozostaje prawdziwe po jednokrotnym wykonaniu poleceń pętli, a stad jest ono jej niezmiennikiem. Łatwo zauważyć, że p jest prawdziwe dla poczatkowych wartości zmiennych, apętla wykonuje skończona liczbę iteracji (co pozostawiamy do samodzielnego udowodnienia - patrz zadanie 3 -Moduł 1.). Korzytajac teraz z twierdzenia o niezmiennikach pętli orzekamy, iż zdanie p pozostaje prawdziwe również pozakończeniu pętli oraz t =0(warunek dozoru jest wtedy fałszywy). Zapisujac p dla wartości jakie zmienne maja powyściu z pętli uzyskujemy prawdziwość następujacego stwierdzenia: "Jeżeli tablica b jest reprezentacjabinarn aliczbynaturalnej m (rozpoczynajac od najmniej znaczacych bitów); to n =0 2 k + m:" co oznacza poprawność badanego algorytmu. Ćwiczenie 5. Zadaniem poniższego algorytmu jest wyznaczenie częsci całkowitej q i reszty r dzielenia liczby całkowitej m 0 przez liczbę naturalna n : Dzielenie(m; n) q := 0; r := m; while r ndo q := q +1; r := r n; end; end: Zbadać poprawność tego algorytmu. Rozwiazanie: Zauważmy najpierw, że kolejne wartości zmiennej r tworzaci ag malejacy liczb naturalnych, zatem po skończonej liczbie iteracji otrzymamy r<nipętla zakończy działanie. Ponieważ zadaniem algorytmu jest wyznaczenie liczb q = m n oraz r = m nq; więc m = n q + r i 0 r<n: Gdyby udało się pokazać, że powyższa koniunkcja zdań jest prawdziwa po zakończeniu działania pętli, to wówczas będziemy mogli stwierdzić, że algorytm jest poprawny. Nie możemy użyć każdego zdania z osobna, gdyż wówczas uzyskamy zbyt mało informacjiodanychwyjściowych. Chcemy zastosować znów twierdzenie o niezmiennikach pętli, zatem najpierw szukamy niezmiennika pętli "while". Oczywiście (p) 3
możemy zaczać odrozważenia całej koniunkcji p, ale zakładajac prawdziwość zdania p przed wykonaniem treści pętliiprawdziwość warunku dozoru otrzymamy sprzeczność. Daje to natychmiastowy wniosek, iż p jest niezmiennikiem trywialnym, który nie jest przydatny w praktyce. (Zauważmy też, że nie jesteśmy w stanie orzec, czy zdanie to jest prawdziwe przed wejściem w pętlę, gdyż nie wiemy, która z liczb n i m jest większa.) "Niewygodna" częścia zdania p jest "r <n": Nie możemy więc użyć tej nierówności jako części niezmiennika, ale po zakończeniu działania pętli otrzymamy jajakooczywist a konsekwencję zaprzeczenia warunku dozoru pętli. Wobec powyższego pomijamy nierówność "r <n" i sprawdzamy, czy zdanie m = n q + r i 0 r (p1) jest niezmiennikiem pętli występujacej w algorytmie. Załóżmy, że koniunkcja (p1) jest prawdziwa oraz, że r n: Należy teraz pokazać, iż m = n (q +1)+(r n) i r n 0: Proste rachunki i założenie r n pozwalajastwierdzićprawdziwośćpowyższego zdania, co oznacza, że (p1) jest niezmiennikiem rozważanej pętli. Zauważmy jednocześnie, że (p1) jest prawdziwe przed wykonaniem poleceń pętli. Na mocy twierdzenia 3 uzyskujemy prawdziwość zdania (p1) ifałszywość warunku dozoru. Stad algorytm jest poprawny, gdyż wyznaczone przez niego liczby q i r spełniaja warunek p: Ćwiczenie 6. Niech dana będzie procedura Partition (X, Left, Right); Dane wejściowe: tablicaxoróżnych elementach, X[Left..Right]; Dane wyjściowe: tablicaxorazindeksmidddletaki,że dla każdego i Middle : X[i] X[Middle] oraz X[j] >X[Middle] dlawszystkichj>middle; 1 2 pivot:=x[left]; 3 L:=Left; R:=Rihgt; 4 while L<R do 5 while (X[L] pivot and L Right) do L:=L+1; 6 while (X[R] >pivotand R Left) do R:=R-1; 7 if L<R then 8 zamień X[L]zX[R]; 9 Middle:=R; 10 zamień X[Left] z X[Middle] 11end. Dokonać podziału ci agu 6; 2; 8; 5; 10; 9; 12; 1; 15; 7; 3; 13; 4; 11; 16; 14 na dwie podtablice za pomoca powyższej procedury. Stwierdzić, czy może ona zostać wykorzystana jako procedura dzielaca w algorytmie Quicksort? Rozwiazanie: Poniższa tabelka podaje kolejne przekształcenia tablicy wejściowej 6 2 8 5 10 9 12 1 15 7 3 13 4 11 16 14 6 2 4 5 10 9 12 1 15 7 3 13 8 11 16 14 6 2 4 5 3 9 12 1 15 7 10 13 8 11 16 14 6 2 4 5 3 1 12 9 15 7 10 13 8 11 16 14 1 2 4 5 3 6 12 9 15 7 10 13 8 11 16 14 Uzyskujemy następujace podtablice X[1::5] =< 1; 2; 4; 5; 3 >; X[7::16] =< 12; 9; 15; 7; 10; 13; 8; 11; 16; 14 >: 4
Naszym zadaniem jest wykazanie poprawności semantycznej powyższego algorytmu, tzn. musimy sprawdzić, czy zwraca on pewna permutaję tablicy wejściowej oraz indeks Middle, ożadanych własnościach. Wykorzystajmy wyniki przedstawione w tabelce. Zauważmy, że po każdym przejściu pętli zachodzi następujacy warunek: "dla dowolnego i < L zachodzi pivot X[i] oraz dla każdego j > R mamy pivot <X[j]": W chwili zakończenia działania stwierdzamy L 1 = R (dlaczego?). Ponadto Middle = R i X[Middle]=pivot: Jeśli więc uda nam się pokazać, że po wyjściu z pętli zdanie to pozostaje prawdzie, to zapisujac je dla wyjściowych wartości zmiennych uzyskamy dla dowolnego i Middle zachodzi X[Middle] X[i] (3) oraz dla każdego j > Middle mamy X[Middle] <X[j]: Pamiętamy, żejednymzpodstawowychnarzędzi, którym posługujemy się w tego typu zadaniach jest (obok indukcji matematycznej) twierdzenie o niezmiennikach. Rozpoczniemy od pokazania, że zdanie p :=(p 1 ^ p 2 ); gdzie p 1 : "dla dowolnego i<lzachodzi pivot X[i]"; (p) p 2 : "dla dowolnego j>rzachodzi pivot < X[j]" jest niezmiennikiem zewnętrznej pętli "while". Rozpoczniemy od pokzania, że p 1 i p 2 sa niezmiennikmi odpowiednio pierwszej i drugiej wewnętrznej pętli while w tym algorytmie. (a) Załóżmy więc, że p 1 jest prawdziwe przed wejściem w pierwsza wewnętrzna pętlę while (-wiersz 5) i, że (X[L] pivot and L Right). Niech L 1 oznacza wartość zmiennejl po wykonaniu podstawienia wtreści tej pętli. Wówczas L 1 := L +1.Zzałożenia, że prawdziwy jest warunek dozoru pętli oraz, że p 1 jest prawdziwe przed wykonaniem podstwienia zawartego w treści pętli, mamy X[L] pivot idladowolnegoi<lzachodzi pivot X[i]; tj. dla dowolnego i<l 1 zachodzi pivot X[i] co oznacza, że p 1 pozostaje prawdziwe również po wykonaniu treści pierwszej wewnętrznej pętli while; zatem jest jej niezmiennikiem. (b) Analogicznie postępujemy wykazujac, że p 2 jest niezmiennikiem drugiej wewnętrznej pętli whilewiersz 6. Możemy teraz przystapić do wykazania, że koniunkcja p := (p 1 ^ p 2 ) jest niezmiennikiem zewnętrznej pętli while: Załóżmy więc, że p jest prawdziwe przed wejściem w pętlę i,że L<R:Przyjmijmy, że L s ;R s oraz L n ;R n oznaczaja wartości L i R,odpowiednio, przed wejściem w wewnętrzne pętle while ipowyjsciuzwewnętrznych pętli. Rozważmy cztery przypadki 1. X[L s ] pivot i X[R s ]>pivot 2. X[L s ]>pivoti X[R s ] pivot 3. X[L s ] pivot i X[R s ] pivot 4. X[L s ]>pivoti X[R s ]>pivot: (Dla uproszczenie rozważań pomijamy rozważnia dotyczace przekrocznia zakresu, zakładajac, że w każdym zprzypadkówniezostał on przekroczony.) Ad. 1. Wpierwszymprzypadku, możemy na mocy założenia stwierdzić, że (p 1 prawdziwe dla L s i X [L s ] pivot) : Ponieważ dodakowo wiemy z punktu (a), że p 1 jest niezmiennikiem pierwszej wewnętrznej pętli while, na mocy twierdzenia o niezmiennikach orzekamy, że pozostaje ono również prawdziwe po wyjściu z pętli zaś warunek dozoru pętli fałszywy, tj. 8 i<ln pivot X[i] i X[L n ] >pivot: (4) 5
Analogicznie, korzystajac z punktu (b) stwierdzamy, że p 2 pozostaje prawdziwe po wyjściu z drugiej wewnętrznej pętli while zaś warunek dozoru pętli fałszywy, tj. 8 j>rn pivot < X[i] i X[R n ] pivot (5) Po przejściu obu pętli wewnętrznych sprawdzany jest warunek L n < R n : Jeśli jest on spełniony, to następuje zamiana elementów X[L n ] i X[R n ],cospowoduje,że X[L n ] pivot i X[R n ]>pivot:oczywiście niematowpływu na wartość logicznazdań p 1 i p 2 ; ponieważ nierówności występujace w obu zdaniach dotyczatylkowartości elementów tablicy A o indeksach mniejszych od L n zdanie p 1 lub większych od R n zdanie p 2 : Wobectegopowykonaniupoleceńzewnętrznej pętli while zdania p 1 i p 2 pozostaja prawdziwe. Należy teraz zwrócić uwagęnafakt, iż w przypadku powyższej zamiany elementów, w kolejnym przebiegu pętli, który na pewno zostanie wykonany z uwagi na nierówność L n <R n ; wykonane zostanaobiepętle wewnętrzne (jedno- lub wielokrotnie), co zapewnia, że "zbliżanie się" wartości zmiennych L i R; aw konsekwencji zakończenie działania pętli zewnętrznej. Ad. 2. Rozważmy teraz przypadek 2. Wówczas żadna z pętli wewnętrznych nie zostaje wykonana (wartości L i R nie zmieniajasię), a co za tym idzie wartości zmiennych występujacych w zdaniu p nie zmieniajasię, stad p także w tym przypadku pozostaje prawdziwe. Dyskusje pozostałych przypadków pozostawiamy jako ćwiczenia. Podsumowujac: we wszystkich przypadkach wykazaliśmy, zakładajac prawdziwość zdania p oraz nierówności "L < R" przed wykonaniem poleceń zewnętrznej pętli "while", prawdziwość zdania p po jednokrotnym wykonaniu poleceń pętli zewnetrznej. Stad p jest niezmiennikiem zewnętrznej pętli "while". Zauważmy jednocześnie, że dla poczatkowych wartości L i R warunki zawarte w zdaniu p sa spełnione w sposób trywialny, gdyż zmiennel i R przekraczaja dopuszczalne wartości i w konsekwencji zdanie zawierajace kwantyfikator ogólny z ograniczonym zakresem jest prawdziwe. Jednocześnie w obu rozważanych przypadkach zmienna L rośnie lub/i R maleje, co spowoduje zakończenie pętli zewnętrznej "while". Na mocy twierdzenia o niezmiennikach pętli wnosimy, że p jest prawdziwe po zakończeniu działania pętli. Zatem z uwagi na podstawienia w wersach 9 i 10 otrzymujemy (3). 6