Merhaba arkadaşlar,
Mobilhanem.com üzerinden anlattığımız/yayınladığımız Algoritma Eğitimleri serimize devam ediyoruz. Bu dersimizde ise Sırt Çantası(Knapsack) algoritmasını anlatmaya çalışacağız.
Knapsack (Sırt Çantası) Algoritması nedir ?
Knapsack algoritması mevcut verilerden en optimum verimi alma üzerine kurulu bir algoritmadır.
Şöyle basitçe bir örnek vermek gerekirse bir hırsız düşünün sırt çantasına (knapsack) belirli bir ağırlığa kadar eşya koyabiliyor. Evde ise eşyaların ağırlıkları ve değerleri vardır, hırsız en optimum şekilde kar ile evden ayrılmalı ve çantasını ona göre doldurmalıdır.
Örnek Senaryo
Eşya | Ağırlık | Fiyat |
1 | 4 Kg | 2 ₺ |
2 | 2 Kg | 3 ₺ |
3 | 3 Kg | 6 ₺ |
4 | 2 Kg | 2 ₺ |
Yukarıda ki tablo da evde bulunan eşyaların ağırlıkları ve beraberinde değerleri bulunmaktadır. Hırsızın sırt çantası ise en fazla 6 Kg‘lık eşya kapasitesi olsun.
Öncelikle her bir eşyanın birim fiyatını hesaplamamız gerekir çünkü eşyaları çantaya birim fiyatı büyük olandan küçük olana doğru bir sırayla koyacağız ki en verimli şekilde işlem tamamlansın.
Fiyatları ağırlıklara bölerek birim fiyatları bulacağız. Birim fiyatlar aşağıdaki gibidir.
Eşya | Ağırlık | Değer | Birim Fiyat |
1 | 4 Kg | 2 ₺ | 0,5 ₺ |
2 | 2 Kg | 3 ₺ | 1,5 ₺ |
3 | 3 Kg | 6 ₺ | 2,0 ₺ |
4 | 2 Kg | 2 ₺ | 1,0 ₺ |
Senaryo İşlemleri
Sırt çantamız 6 Kg lık eşya sığdırabileceğimizi söylemiştik ve birim fiyatı büyük olandan başlayıp küçük olana doğru çantaya koyacağımızdan da bahsetmiştik bu örneğimizde sırasıyla 3 > 2 > 4 > 1 eşyaları sırasıyla çantaya koyulacaktır.
3.eşyayı çantaya attığımızı düşünelim. 3 Kg fiyatı 6 ₺ sonrasında 2.eşyayı attığımızda ise toplam ağırlık 5 Kg fiyat ise 9 ₺ oldu. Şimdi bizim çantamızın toplam alacağı ağırlık 6 Kg şuan da çantamızda 1 Kg’lık yer kaldı. Ama ağırlığı 1 Kg olan bir eşya bulunmamakta ve buna ek olarak 4.eşya dan 1 Kg lık alacağımızı düşünerek en optimum performansı yakalamış olacağız çünkü sıra bu şekilde gidiyordu. (3 > 2 > 4 > 1)
Sonuç olarak çantamız 6 Kg ve 10 TL lik eşya almış olduk.
Java Kodu
private static double knapsack(List
double value = 0.0;
List
for (Goods goods : goodsList) {
list.add(goods.getValue() / goods.getWeight());
}
double tempWeight = 0.0;
while (tempWeight < weight){
double subWeight = weight - tempWeight;
double maxValue = Collections.max(list);
int maxIndex = list.indexOf(maxValue);
if (goodsList.get(maxIndex).getWeight() <= subWeight){
tempWeight += goodsList.get(maxIndex).getWeight();
value += goodsList.get(maxIndex).getValue();
}else{
double WEIGHT = goodsList.get(maxIndex).getWeight(); // 2
if (WEIGHT % subWeight == 0){
double div = WEIGHT / subWeight;
value += goodsList.get(maxIndex).getWeight() / div;
tempWeight += subWeight;
}
}
goodsList.remove(maxIndex);
list.remove(maxIndex);
if (tempWeight == weight){
break;
}
}
return value;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
private static double knapsack(List
double value = 0.0; List
for (Goods goods : goodsList) { list.add(goods.getValue() / goods.getWeight()); }
double tempWeight = 0.0; while (tempWeight < weight){
double subWeight = weight – tempWeight;
double maxValue = Collections.max(list); int maxIndex = list.indexOf(maxValue);
if (goodsList.get(maxIndex).getWeight() <= subWeight){ tempWeight += goodsList.get(maxIndex).getWeight(); value += goodsList.get(maxIndex).getValue(); }else{ double WEIGHT = goodsList.get(maxIndex).getWeight(); // 2 if (WEIGHT % subWeight == 0){ double div = WEIGHT / subWeight; value += goodsList.get(maxIndex).getWeight() / div; tempWeight += subWeight; } }
goodsList.remove(maxIndex); list.remove(maxIndex);
if (tempWeight == weight){ break; } } return value; } |
C++ Kodu
int knapSack(int W, int wt[], int val[], int n){
int i, w;
int K[n + 1][W + 1];
for (i = 0; i <= n; i++){ for (w = 0; w <= W; w++){ if (i == 0 || w == 0) K[i][w] = 0; else if (wt[i - 1] <= w) K[i][w] = max(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w]); else K[i][w] = K[i - 1][w]; } } return K[n][W]; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
int knapSack(int W, int wt[], int val[], int n){ int i, w; int K[n + 1][W + 1]; for (i = 0; i <= n; i++){ for (w = 0; w <= W; w++){ if (i == 0 || w == 0) K[i][w] = 0; else if (wt[i – 1] <= w) K[i][w] = max(val[i – 1] + K[i – 1][w – wt[i – 1]], K[i – 1][w]); else K[i][w] = K[i – 1][w]; } } return K[n][W]; } |
Python Kodu
def KnapsackFrac(v, w, W):
order = bubblesortByRatio(v, w)
weight = 0.0
value = 0.0
knapsack = []
n = len(v)
index = 0
while (weight < W) and (index < n):
if weight + w[order[index]] <= W:
knapsack.append((order[index], 1.0))
weight = weight + w[order[index]]
value = value + v[order[index]]
else:
fraction = (W - weight) / w[order[index]]
knapsack.append((order[index], fraction))
weight = W
value = value + v[order[index]] * fraction
index = index + 1
return (knapsack, value)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
def KnapsackFrac(v, w, W): order = bubblesortByRatio(v, w) weight = 0.0 value = 0.0 knapsack = [] n = len(v) index = 0 while (weight < W) and (index < n): if weight + w[order[index]] <= W: knapsack.append((order[index], 1.0)) weight = weight + w[order[index]] value = value + v[order[index]] else: fraction = (W – weight) / w[order[index]] knapsack.append((order[index], fraction)) weight = W value = value + v[order[index]] * fraction index = index + 1 return (knapsack, value) |
Proje Kodu : Github
Umarım faydalı olmuştur aklınıza takılan bir yer ya da sormak istediğiniz bir ksıım olursa sormaktan çekinmeyin.
Hoşçakalın.
18