2009-2010 BAHAR DÖNEMİ MC 689 ALGORİTMA TASARIMI ve ANALİZİ I. VİZE ÇÖZÜMLERİ 1. a) Böl ve yönet (divide & conquer) tarzındaki algoritmaların genel özelliklerini (çalışma mantıklarını) ve aşamalarını kısaca anlatınız. Böl ve Yönet yaklaşımı; büyük boyutlu bir problemin küçük boyuttaki parçalara bölünerek, her bir alt parçanın rekürsif olarak çözümlenmesi (yönetilmesi) ve gerektiğinde bu çözümlerin birleştirilerek esas çözüme ulaşılması ilkesine dayanır. Eğer N boyutlu bir problem N den daha ufak boyuttaki bir alt problem cinsinden ifade edilebiliyorsa, bu alt problemin çözümünde elde edilen sonuç üst problemin çözümlenmesinde kullanılabilir. Böl ve Yönet yaklaşımının 3 aşaması vardır : 1- Böl (divide) : N boyutlu problemin daha ufak boyutta en az bir parçaya ayrılması. 2- Yönet (conquer) : Her bir alt problemin rekürsif olarak çözümlenmesi. 3- Birleştir (combine) : Gerekiyorsa alt parçalardan gelen eldelerin birleştirilmesi. b) Aşağıda sözde-kod biçiminde verilmiş olan algoritma ne iş yapar? Bu algoritmanın rekürans bağıntısını oluşturunuz ve karmaşıklığını bulunuz. Bu algoritmanın yaptığı işi yapan en bilinen yöntem ile bir karşılaştırmasını yapınız. Hangi yöntem daha hızlıdır? F(A, N, K) // A dizi; N, K integer if N<0 then return K; if A[N]>K then K = A[N]; return F(A, N-1, K); Yanda verilen algoritma, son satırda tekrar kendini çağırdığı için rekürsif bir algoritmadır. Sözde-kod incelendiğinde bu algoritmanın parametre olarak verilen bir A dizisinde N ile 0. indis arasında kalan elemanların en büyüğünü bulduğu (ve her rekürsif dallanmada bu bilgiyi K değişkeni üzerinden ilettiği) görülebilir. Her iki if satırındaki işlemler sabit zamanlı Θ(1), son satırdaki rekürsif çağrı ise problemi N boyuttan N-1 boyuta indirerek tekrar çağırdığı için rekürans bağıntısı T(n) = T(n-1) + Θ(1) şeklindedir. Bu rekürans bağıntısının çözümü Θ(n) dir (Toplam n adet iç içe çağrı var; her çağrıda sabit zamanlı iş yapılıyor. n*c = cn) Bir dizinin en büyük elemanını bulma probleminin en bilinen yöntemi, 0-n indisleri arasında çalışan tek bir döngü üzerinde dizi elemanlarını incelemek ve en_büyük ten daha büyük olan dizi elemanını en_büyük içinde saklamaktır. Bu yöntemin karmaşıklığı da Θ(n) dir. Sonuç olarak her iki algoritma da Θ(n) karmaşıklığındadır. Rekürsif yaklaşımdaki her dallanmada adres ve yerel değişken bilgilerinin tutulduğu yığıt kullanımının getirdiği ek maliyet düşünüldüğünde iteratif yaklaşım tercih edilmelidir.
2. T(n) = T(n/2) + Θ (n 2 ) rekürans bağıntısını rekürsiyon ağacı (recursion tree) yöntemi ile çözünüz. Bu bağıntı master method teoreminin hangi durumuna uygundur? Bu yöntem ile de çözümü bularak ilk çözümün sağlamasını yapınız. Master Method : T(n) = at(n/b) + f(n) formundaki rekürans bağıntıları için; 1. Herhangi bir ε>0 için f(n) = Ο(n log b a-ε ) ise T(n)=Θ (n log b a ) 2. Herhangi bir k>=0 için f(n) = Θ (n log b a lg k n) ise T(n)= Θ (n log b a lg k+1 n) 3. Herhangi bir c<1 için a.f(n/b)<=c.f(n) sağlanıyorsa ve herhangi bir ε>0 için f(n)=ω( n log b a+ε ) ise T(n) = Θ (f(n)). T(n) cn 2 cn 2 cn 2 cn 2 \ \ \ \ T(n/2) c(n 2 /4) c(n 2 /4) c(n 2 /4) \ \ \ h= log 4 n 2 T(n\4) c(n 2 /16) c(n 2 /16) \... Θ(1) En sağda oluşan rekürans ağacının yüksekliği log 4 n 2 = 2log 4 n dir. Toplam maliyeti bulalım: 2log 4n -1 T(n) = cn 2 + c(n 2 /4) + c(n 2 /16) +...+1 = cn 2. (1/4) i = cn 2. (1-(1/4) 2log4n / (1-(1/4))) i=0 = cn 2. ((1 (1 / n 2 )) / (3/4)) = cn 2. (4(n 2 1)/3 n 2 ) = c(4n 2-4) / 3 = Θ(n 2 ) olarak bulunur. Master teorem kullanarak çözümü bulmaya çalışalım. a=1, b=2, f(n)= n 2 n log b a = n log 2 1 = n 0 = 1 f(n)= n 2 = Ω(1) olduğundan ve 1.(n/2) 2 <= c.n 2 ifadesi ¼<=c<1 için sağlandığından dolayı 3. durum içindeyiz. Buna göre çözüm T(n) = Θ (f(n)) = Θ (n 2 ) olarak bulunur.
3. Quicksort algoritması ile A={13,19,9,5,12,8,7,4,21,2,6,11} dizisi sıralanacaktır. Buna göre algoritmanın içindeki ilk PARTITION işleminin çalıştırılması esnasında dizinin alacağı durumu aşama aşama gösteriniz (her aşamada i ve j indislerinin yer değişimini gösteriniz). PARTITION(A, p, q) x A[p] i p for j p+ 1 to q do if A[j] x then i i+ 1 exchange A[i] A[j] exchange A[p] A[i] return i Quicksort algoritmasının çekirdeğini oluşturan PARTITION bölümünde pivot eleman dizinin diğer elemanları ile karşılaştırılmaktadır. Bu algoritmadak parametresi sırası ile karşılaştırılacak dizi elemanlarının indisini; i parametresi ise pivotun olası güncel konumunu belirlemektedir. Karşılaştırmalar esnasında bulunan her küçük eleman pivotun solunda kalacağı için pivotun konumu, yani i değeri 1 arttırılmakta ve karşılaştırılan eleman yeni konumdaki eleman ile değiştirilmektedir. Buna göre, soruda verilen A dizisi için seçilecek ilk pivot 13 elemanı olacak ve bu elemanı dizinin diğer elemanları ile karşılaştırılacaktır. Karşılaştırılan elemanlar koyu olarak belirtilmiştir. p q 13 19 9 5 12 8 7 4 21 2 6 11 13 19 9 5 12 8 7 4 21 2 6 11 13 9 19 5 12 8 7 4 21 2 6 11 13 9 19 5 12 8 7 4 21 2 6 11 13 9 5 19 12 8 7 4 21 2 6 11 13 9 5 19 12 8 7 4 21 2 6 11 13 9 5 12 19 8 7 4 21 2 6 11 13 9 5 12 19 8 7 4 21 2 6 11 13 9 5 12 8 19 7 4 21 2 6 11 13 9 5 12 8 19 7 4 21 2 6 11 13 9 5 12 8 7 19 4 21 2 6 11 13 9 5 12 8 7 19 4 21 2 6 11 13 9 5 12 8 7 4 2 21 19 6 11 13 9 5 12 8 7 4 2 21 19 6 11 13 9 5 12 8 7 4 2 6 19 21 11 13 9 5 12 8 7 4 2 6 19 21 11 13 9 5 12 8 7 4 2 6 11 21 19 11 9 5 12 8 7 4 2 6 13 21 19
4. n elemanlı bir A[1...n] dizisi şu şekilde sıralanabilir : Önce tüm dizinin en küçük elemanı bulunup bu eleman A[1] indisindeki eleman ile yer değiştirilir. Bunun ardından ilk eleman dışında kalan diğer elemanların en küçüğü bulunup bu eleman A[2] indisindeki eleman ile yer değiştirilir. Bu işlem A dizisinin ilk n-1 elemanı için tekrarlandığında dizi sıralanmış olur. Bu sıralama algoritması literatürde seçmeli sıralama (selection sort) algoritması olarak bilinmektedir. a) Bu algoritmaya ilişkin bir sözde kod (pseudo-code) yazınız. b) A={2,4,3,1} dizisinin bu algoritma ile sıralanması esnasında toplam kaç adet karşılaştırma (comparison) ve yer değiştirme (swap) işlemi yapılır? Hesaplayınız. c) Bu algoritmanın asimtotik analizini yapınız (analizde sadece karşılaştırma (comparison) sayılarını dikkate alınız). SELECTION_SORT (A,N) // A[1..N] dizisi for i 1 to N-1 do ek A[i] y i for j i+1 to N do if A[j]<ek then ek=a[j] y j if i!=y then swap (A[i],A[y]) A={2,4,3,1} Dizi Elemanı Karşılaştırma Yer Değiştirme (swap) Dizi Son Durumu 2 3 (2-4, 2-3, 2-1) 1 {1,4,3,2} 4 2 (4-3, 4-2) 1 {1,2,3,4} 3 1 (3-4) 0 {1,2,3,4} Dolayısıyla bu dizinin sıralanması esnasında toplam 3+2+1 = 6 karşılaştırma, 1+1=2 yer değiştirme yapılmaktadır. Algoritma iç içe iki döngü içermektedir. Dış döngü N-1 kere, iç döngü ise N-(i+1)+1 kere çalışmaktadır. Eleman karşılaştırma ifadesi bu iki döngünün de içinde yer aldığından, karşılaştırma işlemi sırasıyla N-1, N-2, N-3,... 1 kere yapılır. Yukarıdaki örnek için 4 elemanlı bir dizide sırayla 3,2,1 kere karşılaştırma yapılmıştır (1. eleman 3 kere, 2. eleman 2 kere, 3. eleman 1 kere karşılaştırma işlemi içinde yer almıştır). Sonuç olarak toplam karşılaştırma sayısı 1 den N-1 e kadar olan sayıların toplamıdır. Asimtotik olarak analiz edildiğinde algoritmanın karmaşıklığı N-1 i = ((N)*(N-1))/2 = Θ (n 2 ) olarak bulunur. i=1
5. U = {18,26,35,9,64,47,96,36,70} anahtarları slot sayısı m=13 olan boş bir hash tablosuna yerleştirilecektir. Bu yerleştirme işlemini; a) Doğrusal sınama (linear probing) ve b) h 1 (k)=k mod 13, h 2 (k)=1 + (k mod 12) hash fonksiyonlarını kullanan ikili sınama (double probing) yöntemlerini kullanarak ve her aşamada yapılan işlemleri belirterek gerçekleştiriniz. U = {18,26,35,9,64,47,96,36,70} Doğrusal sınama : h(k, i) = ((k mod 13) + i) mod 13 (18 mod 13)+0 = 5 (26 mod 13)+0 = 0 (35 mod 13)+0 = 9 (09 mod 13)+0 = 9 (çakışma) (09 mod 13)+1 = 10 (64 mod 13)+0 = 12 (47 mod 13)+0 = 8 (96 mod 13)+0 = 5 (çakışma) (96 mod 13)+1 = 6 (36 mod 13)+0 = 10 (çakışma) (36 mod 13)+1 = 11 (70 mod 13)+0 = 5 (çakışma) (70 mod 13)+1 = 6 (çakışma) (70 mod 13)+2 = 7 26 18 96 70 47 35 9 36 64 İkili sınama : h(k, i) = (k mod 13 + i.(1+(k mod 12))) mod 13 (18 mod 13)+0 = 5 (26 mod 13)+0 = 0 (35 mod 13)+0 = 9 (09 mod 13)+0 = 9 (çakışma) ((09 mod 13)+1.(1+ (09 mod 12))) mod 13 = 6 (64 mod 13)+0 = 12 (47 mod 13)+0 = 8 (96 mod 13)+0 = 5 (çakışma) ((96 mod 13)+1.(1+ (96 mod 12))) mod 13 = 6 (çakışma) ((96 mod 13)+2.(1+ (96 mod 12))) mod 13 = 7 (36 mod 13)+0 = 10 (70 mod 13)+0 = 5 (çakışma) ((70 mod 13)+1.(1+ (70 mod 12))) mod 13 = 3 26 70 18 9 96 47 35 36 64