Kesirli Sırt Çantası
Bölünebilen eşyalarla çantayı birim ağırlık başına değere göre dolduran ve en iyi sonucu veren açgözlü algoritma.
Önce bunlara göz at
#Nasıl çalışır?
Kesirli sırt çantası, 0/1 sırt çantasının eşyaların bölünebildiği hâlidir: bir eşyanın tamamını değil, istediğimiz kadarını alabiliriz (toz altın, baharat, kumaş gibi).
Bu durumda açgözlü yaklaşım en iyi çözümü verir: eşyaları birim ağırlık başına değere (v / w) göre sırala, en değerliden başlayarak tamamını al; sığmayan ilk eşyadan kalan yer kadar kes ve dur.
Aynı eşyalarla 0/1 sırt çantasında kapasite 7 için en iyi değer 9'dur; kesirli hâlde 9,67'ye çıkar. 0/1 hâlinde aynı açgözlü kural yanılabilir, çünkü eşya bölünemediği için boşta kalan yer değerlendirilemez. Bu yüzden 0/1 sırt çantası DP ister.
#Kendin dene
| w | v | v/w | × | + | |
|---|---|---|---|---|---|
| 4 | 5 | 7 | 1.4 | ||
| 2 | 3 | 4 | 1.33 | ||
| 3 | 4 | 5 | 1.25 | ||
| 1 | 1 | 1 | 1 |
Kalan kapasite
7 / 7Eşyalar bölünebiliyor (toz, sıvı, kumaş gibi). Açgözlü kural: birim ağırlık başına değeri en yüksek olandan başla.
#Adım adım
- 01Her eşya için v / w oranını hesapla.
- 02Eşyaları bu orana göre büyükten küçüğe sırala.
- 03Sığan eşyaların tamamını al.
- 04Sığmayan ilk eşyadan kalan kapasite kadar kesir al ve dur.
#Örnek kod
Aynı algoritma 8 dilde. Her program derlenip çalıştırılarak test edildi ve hepsi aynı çıktıyı veriyor.
# (weight, value) of each item; any fraction of an item may be taken.
ITEMS = [(1, 1), (3, 4), (4, 5), (5, 7)]
def fractional_knapsack(items: list, capacity: float) -> float:
total = 0.0
for w, v in sorted(items, key=lambda it: it[1] / it[0], reverse=True): # best value per weight first
if capacity <= 0:
break
take = min(w, capacity) # the whole item, or the part that still fits
total += v * take / w
capacity -= take
return total
print(f"{fractional_knapsack(ITEMS, 7):.2f}") # 0/1 knapsack only reaches 9#Karmaşıklık
| İşlem | Süre |
|---|---|
| Sıralama | O(n log n) |
| Doldurma | O(n) |
| Toplam | O(n log n) |
| 0/1 sürümü (DP) | O(n · W) |
Sıralama baskındır. Seçim (selection) algoritmasıyla kesilecek eşyayı bulmak O(n)'e de indirilebilir. Sonuç her zaman en iyidir: daha düşük oranlı bir eşyadan bir birim almak, daha yüksek oranlı bir eşyadan bir birim almaktan asla iyi olamaz.
#Ne zaman kullanılır?
Bölünebilir kaynakların paylaştırılması: bütçe dağıtımı, yük ve yakıt planlaması, yatırım miktarlarının kesirli seçimi. Ayrıca 0/1 sırt çantası için dal-sınır (branch and bound) yöntemlerinde üst sınır hesaplamak için kullanılır.
#Alıştırma
Soruları cevaplamak ve ilerlemeni kaydetmek için giriş yap.
Kolay
Kesirli sırt çantasında eşyalar hangi sıraya göre alınır?
- 1Birim ağırlık başına değere (v / w) göre, en yüksekten
- 2Ağırlığa göre, en hafiften
- 3Değere göre, en yüksekten
- 4Rastgele
0/1 ve kesirli sırt çantası arasındaki fark nedir?
- 1Kesirli olanda eşyaların bir kısmı alınabilir
- 2Kesirli olanda kapasite sınırı yoktur
- 30/1'de eşyalar bölünebilir
- 4Fark yoktur
Kesirli sırt çantasının zaman karmaşıklığı nedir?
- 1O(n log n)
- 2O(n · W)
- 3O(2ⁿ)
- 4O(W)
Orta
Kapasite 5; eşyalar (ağırlık, değer): (4, 8), (2, 3). En yüksek değer kaçtır?
- 19,5
- 28
- 311
- 410
Zor
Aynı açgözlü kural 0/1 sırt çantasında neden yanılabilir?
- 1Eşyalar bölünemediği için kalan boş yer değerlendirilemeyebilir
- 2Oranlar negatif olabildiği için
- 3Sıralama yanlış sonuç verdiği için
- 4Yanılmaz, her zaman doğrudur