Greedy Algorithms
Açgözlü(Greedy) yaklaşım Dinamik programlama tekniği gibi optimizasyon sorularına uygulanır Uygulanması çok daha kolay bir yaklaşımdır Problem optimallık prensibini sağlamalıdır (DP gibi). Problemin aynı zamanda greedy-seçim özelliği olmalıdır. Her adımda o adımda en iyi görünen elemanı seçiyoruz (yerel optimal seçim) yerel optimal seçim yaparak global optimal çözümü bulacağımızı umut ediyoruz
Açgözlü yaklaşım Bir problemin ardışık kararlar dizisi sonucu çözülebileceğini varsayalım. Açgözlü yaklaşım şudur: her adımdaki karar o adım için en iyi karardır(yerel optimaldir). Bu yerel optimal çözümler sonuçta global optimal çözümü(asıl problemin çözümünü) oluşturuyorlar. Çok az sayıda optimizasyon problemine açgözlü yaklaşım uygulanabilir.
Basit bir örnek Problem: n sayı arasından toplamları en çok olan k sayı bulunuz. Algorithm: for i = 1 to k dizideki en büyük sayıyı al aldığın sayıyı diziden sil.
Özel bir çizgede en kısa yol problemi Problem: Aşağıdaki çizgede v0 dan v3 e olan en kısa yolu bulunuz greedy yöntem bu problemi çözer. En kısa yol: 1 + 2 + 4 = 7.
Çok kademeli bir çizgede en kısa yol Problem: Aşağıdaki çok kademeli çizgede v0 dan v3 e olan en kısa yolu bulunuz Greedy method: v0v1,2v2,1v3 = 23 Optimal: v0v1,1v2,2v3 = 7 The greedy method does not work.
Problemin çözümü dmin(i,j): i ve j arasındaki en kısa uzaklık olsun. Problem dinamik programlama yöntemiyle çözülebilir.
Etkinlik seçimi problemi Problem: n etkinlik var, S = {1, 2, …, n}, her i etkinliğinin başlangıç zamanı si ve bitiş zamanı fi, si fi var. i etkinliği [si, fi] zaman aralığında yapılıyor. i ve j etkinlikleri için si fj veya sj fi ise bu etkinlikler uyumludur denir. Eleman sayısı maksimum ve tüm elemanları ikişerli uyumlu olan etkinlikler kümesi aranıyor.
Örnek: Çözüm kümesi = {1, 4, 8, 11} Algorithm: Başlangıçta çözüm kümesi boş küme olsun Adım 1: Bitiş zamanları fi dizisini küçükten büyüğe doğru sırala, sıralama sonrası f1 f2 f3 … fn. Adım 2: Çözüm kümesinde bulunan tüm etkinliklerle uyumlu olan sıradaki i etkinliğini çözüm kümesine ekle . Adım 3: Bakılmamış etkinlik kalmadıysa dur. Aksi durumda, Adım 2 ye git. İşlem zamanı: O(nlogn) i 1 2 3 4 5 6 7 8 9 10 11 si 12 fi 13 14
Copyright © The McGraw-Hill Companies, Inc Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display.
Örneğin adım adım çözümü: Solution = {1, 4, 8, 11} i si fi Kabul 1 4 Evet 2 3 5 Hayır 6 7 8 10 11 9 12 13 14
Son teslim tarihleri bulunan işler Problem: n iş var, S={1, 2, …, n}, her i işinin son teslim tarihi di 0 ve getirisi pi 0 veriliyor. Her işi bir birimlik zaman diliminde yapabiliyoruz ve bir işi teslim etmeden başka işi yapamıyoruz. i işini son teslim tarihinden önce teslim etmeden pi getirisini kazanamıyoruz. Amac en çok para kazanmaktır. Optimal çözüm= {1, 2, 4}. Toplam kazanç= 20 + 15 + 5 = 40. i 1 2 3 4 5 pi 20 15 10 di
Algorithm: Başlangıçta çözüm kümesi boştur Adım 1: Getiriler pi dizisini artmayan biçimde sırala. Sıralama sonrası p1 p2 p3 … pn. Adım 2: Son teslim tarihi geçmemiş sıradaki i işini al ve [r-1, r] zaman aralığında yapmayı planla. Burada r sayısı 1 r di koşulunu sağlayan ve [r-1, r] zaman aralığının boş olduğu en büyük r tam sayısıdır. (Tabii eğer bu koşula uyan r sayısı varsa) Adım 3: Tüm işlere bakılmışsa dur. Aksi durumda 2. adıma geç. İşlem zamanı: O(n2)
Çözüm kümesi = {1, 2, 4} Toplam kazanç = 20 + 15 + 5 = 40 Örnek. i pi di 1 20 2 [1, 2] aralığını seç 15 [0, 1] aralığını seç 3 10 reddet 4 5 [2, 3] aralığını seç
Sırt Çantası( Knapsack) Problemi Ünlü sırt çantası problemi: Hırsız bir muzeye giriyor. Her tarafta resimler, heykeller ve mücevherler var. Hırsızın çok iyi gözleri vardır, bakar bakmaz bu nesnelerin ne kadar para edeceklerini görüyor. Ayrıca ağırlıklarını da hesaplayabiliyor. Hırsızın belirli bir kapasitesi olan sadece bir çantası vardır. Bu hırsızın çok para kazanabilmesi için hangi nesneleri seçmesi gerekir?
Sırt çantası problemi n nesne var, ağırlıkları wi > 0 fiyatları pi > 0 çanta kapasitesi: M maksimize et 0 xi 1, 1 i n
Sırt çantası problemi algoritma: Açgözlü algotitma: Adım 1: pi/wi sayılarını artmayacak biçimde sırala Adım 2: Sıralı dizye göre çantanın alabileceği sıradaki nesneyi (veya sonuncu ise çantaya yerleşebilecek parçasını) çantaya koy. n = 3, M = 20, (p1, p2, p3) = (25, 24, 15) (w1, w2, w3) = (18, 15, 10) Sol: p1/w1 = 25/18 = 1.32 p2/w2 = 24/15 = 1.6 p3/w3 = 15/10 = 1.5 Optimal çözüm: x1 = 0, x2 = 1, x3 = 1/2 toplam kazanç = 24 + 7.5 = 31.5
0-1 sırt çantası problemi Sırt çantasının kapasitesi W ve S kümesi veriliyor (bu kümede n nesne vardır) Her i nesnesinin ağırlığı wi ve kazancı bi ( wi , bi ve W pozitif tam sayılardır) Problem: Hangi nesneleri seçelim ki kazanç en fazla olsun? Diğer problemden farkı: Nesneleri bölemiyoruz
0-1 Sırt çantası problemi: Ağırlık Değer wi bi Items 2 3 Çanta Max ağırlık: W = 20 3 4 4 5 W = 20 5 8 9 10
Sırt çantası problemi 0-1 sırt çantası problemi: Hırsız n tane nesne arasından bazılarını seçmelidir, burada i. nesnenin değeri bi ve ağırlığı wi Çanta kapasitesi W Not: bi, wi, ve W tam sayılardır “0-1” anlamı: bir nesneyi ya bütün olarak alacak, ya da hiç alamayacak kesirli sırt çantası problemi: Hırsız nesnelerin bir parçasını da alabilir
0-1 Sırt çantası problemi
0-1 Sırt çantası problemi: brute-force yaklaşım Aklımıza gelen ilk algoritmayla çözersek: n nesne var, 2n durum Her durum için değerleri hesapla, koşulu sağlayanlar arasından toplam değeri en büyük olanı bul İşlem zamanı O(2n)
Sırt çantası problemi Kesirli problem açgözlü yaklaşımla yapılır Nasıl? 0-1 problemi ise açgözlü yaklaşımla yapılamaz Açgözlü: değer/ağırlık en fazla olanı al Örnek: 3 nesnenin ağırlıkları 10, 20, ve 30 kg, çanta kapasitesi 50 kg olsun Nesne değerleri 60, 100, 120 lira olsun. Açgözlü algoritmaya göre önce 1. sonra da 2. nesne alınacak, yani 160 lira kazanç olur. Oysa 2. ve 3. nesneleri alırsa 220 lira kazanır
Copyright © The McGraw-Hill Companies, Inc Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display.
0-1 problemi Açgözlü yaklaşım çalışmadı. Brute Force kötü. Daha iyisi var mı? Var, dinamik programlama yöntemi Sadece altproblemi dikkatli tanımlamak gerekir Altproblemi tanımlamaya çalışalım: Nesne numaraları 1..n olsun. Altproblem: Sk = {1, 2, .. k} numaralı nesneler arasından optimal olanları seç
Altproblemin tanımı Nesne numaraları 1..n olsun. Altproblem: Sk = {1, 2, .. k} numaralı nesneler arasından optimal olanları seç Bu altproblem tanımı doğru gibi ama. Soru şu: Asıl problem olan (Sn ) in çözümünü (Sk) cinsinden yazabilir miyiz? Ne yazık ki, hayır….
? Altproblem tanımı wi bi Ağırlık Değer wi bi Nesne # ? 1 2 3 Max ağırlık: W = 20 S4 için: Toplam ağırlık: 14; Toplam kazanç: 20 S4 2 3 4 S5 3 4 5 4 5 8 5 9 10 w1 =2 b1 =3 w3 =4 b3 =5 w4 =5 b4 =8 w5 =9 b5 =10 S4 için çözüm S5 için çözümün altparçası değil!!! S5 için: Toplam ağırlık: 20 Toplam kazanç: 26
Altproblem tanımı (devamı) Görüldüğü gibi S4 için olan çözüm S5 için olan çözümün altparçası değil Bunun anlamı şudur: altproblemi iyi tanımlamadık ve başka bir tanıma gereksinim vardır! Yeni bir parametre dahil edelim: w<=W parametresi çantanın değişken kapasitesini göstermektedir. Bu parametreyi 0 dan W ya kadar artırarak B[k,w] yi hesaplayacağız.
Altproblem için özyinelemeli formül Anlamı şudur: ilk k tane nesneden oluşan Sk kümesinin kapasitesi w olan çanta için en iyi altkümesi 2 sinden biri olur: 1) Ya Sk-1 kümesinin kapasitesi w olan çanta için en iyi altkümesidir, 2) Ya da Sk-1 kümesinin kapasitesi w-wk olan çanta için en iyi altkümesine k nesnesinin eklenmişidir
Özyinelemeli formül Sk kümesinin kapasitesi w olan çanta için en iyi altkümesi, k. nesneyi içerebilir veya içermez 1. durum: wk>w ise k. nesne çözümün içinde olamaz, bu nesne kapasitesi w olan çantaya giremez. 2. durum: wk <=w ise k. nesne çözümde ola da bilir, olamaya da bilir, büyük olanı alırız
0-1 Sırt Çantası Algoritması for w = 0 to W B[0,w] = 0 for i = 0 to n B[i,0] = 0 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
brute-force algoritması İşlem zamanı for w = 0 to W B[0,w] = 0 for i = 0 to n B[i,0] = 0 O(W) n defa tekrar ediyor O(W) İşlem zamanı? O(n*W) brute-force algoritması O(2n)
Örnek n = 4 (nesne sayısı) W = 5 (maksimum kapasite) Elemanlar (ağırlık, değer): (2,3), (3,4), (4,5), (5,6)
Örnek i 1 2 3 4 W 1 2 3 4 5 for w = 0 to W B[0,w] = 0
Örnek i 1 2 3 4 W 1 2 3 4 5 for i = 0 to n B[i,0] = 0
Örnek Nesneler: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=1 bi=3 wi=2 w=1 1 2 3 4 W i=1 bi=3 wi=2 w=1 w-wi =-1 1 2 3 4 5 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Items: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=1 bi=3 wi=2 w=2 1 2 3 4 W i=1 bi=3 wi=2 w=2 w-wi =0 1 2 3 3 4 5 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Items: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=1 bi=3 wi=2 w=3 1 2 3 4 W i=1 bi=3 wi=2 w=3 w-wi=1 1 2 3 3 3 4 5 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Items: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=1 bi=3 wi=2 w=4 1 2 3 4 W i=1 bi=3 wi=2 w=4 w-wi=2 1 2 3 3 3 4 3 5 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Items: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=1 bi=3 wi=2 w=5 1 2 3 4 W i=1 bi=3 wi=2 w=5 w-wi=2 1 2 3 3 3 4 3 5 3 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Nesneler: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=2 bi=4 wi=3 w=1 1 2 3 4 W i=2 bi=4 wi=3 w=1 w-wi=-2 1 2 3 3 3 4 3 5 3 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Nesneler: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=2 bi=4 wi=3 w=2 1 2 3 4 W i=2 bi=4 wi=3 w=2 w-wi=-1 1 2 3 3 3 3 4 3 5 3 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Nesneler: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=2 bi=4 wi=3 w=3 1 2 3 4 W i=2 bi=4 wi=3 w=3 w-wi=0 1 2 3 3 3 3 4 4 3 5 3 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Nesneler 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=2 bi=4 wi=3 w=4 1 2 3 4 W i=2 bi=4 wi=3 w=4 w-wi=1 1 2 3 3 3 3 4 4 3 4 5 3 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Nesneler 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=2 bi=4 wi=3 w=5 1 2 3 4 W i=2 bi=4 wi=3 w=5 w-wi=2 1 2 3 3 3 3 4 4 3 4 5 3 7 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Nesneler: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=3 bi=5 wi=4 1 2 3 4 W i=3 bi=5 wi=4 w=1..3 1 2 3 3 3 3 3 4 4 4 3 4 5 3 7 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Nesneler: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=3 bi=5 wi=4 w=4 1 2 3 4 W i=3 bi=5 wi=4 w=4 w- wi=0 1 2 3 3 3 3 3 4 4 4 3 4 5 5 3 7 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Nesneler: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=3 bi=5 wi=4 w=5 1 2 3 4 W i=3 bi=5 wi=4 w=5 w- wi=1 1 2 3 3 3 3 3 4 4 4 3 4 5 5 3 7 7 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Nesneler: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=3 bi=5 wi=4 1 2 3 4 W i=3 bi=5 wi=4 w=1..4 1 2 3 3 3 3 3 3 4 4 4 4 3 4 5 5 5 3 7 7 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w
Örnek Nesneler: 1: (2,3) 2: (3,4) 3: (4,5) 4: (5,6) i=3 bi=5 wi=4 w=5 1 2 3 4 W i=3 bi=5 wi=4 w=5 1 2 3 3 3 3 3 3 4 4 4 4 3 4 5 5 5 3 7 7 7 if wi <= w // item i can be part of the solution if bi + B[i-1,w-wi] > B[i-1,w] B[i,w] = bi + B[i-1,w- wi] else B[i,w] = B[i-1,w] else B[i,w] = B[i-1,w] // wi > w