Penyelesaian Knapsack dengan BFS
Soal diatas dengan tas berkapasitas 10 kg. 5 barang (berat, nilai):
- Barang 1: (6 kg, 30)
- Barang 2: (3 kg, 14)
- Barang 3: (4 kg, 16)
- Barang 4: (2 kg, 9)
- Barang 5: (5 kg, 20)
Tujuan: pilih kombinasi barang (masing-masing diambil atau tidak — 0/1 knapsack) sehingga total berat ≤ 10 kg dan total nilai maksimal.
1. Pendekatan dengan BFS
Representasi node:
Transisi dari node pada level = i:
Varian yang disarankan: BFS dengan pruning berat — saat membuat anak include, hanya enqueu jika weight + w[i] ≤ capacity. Dengan pruning ini kita mengurangi jumlah node yang harus diperiksa (tetap eksponensial tapi lebih kecil).
BFS memastikan kita menjelajah level demi level. Kita memeriksa semua kombinasi (daun) yang mungkin, dan menyimpan solusi terbaik yang feasible.
Pseudocode
FUNCTION BFS_KNAPSACK(items, capacity):
# items: list of (weight, value), 0-based index
n = length(items)
best_value = 0
best_set = []
queue = empty queue
enqueue (level = 0, chosen = [], weight = 0, value = 0)
WHILE queue not empty:
(level, chosen, weight, value) = dequeue(queue)
IF level == n:
# leaf: semua keputusan sudah dibuat
IF weight <= capacity AND value > best_value:
best_value = value
best_set = chosen.copy()
CONTINUE
# 1) child: exclude current item
enqueue(queue, (level+1, chosen.copy(), weight, value))
# 2) child: include current item (prune jika berat melebihi kapasitas)
w2 = weight + items[level].weight
v2 = value + items[level].value
IF w2 <= capacity:
enqueue(queue, (level+1, chosen + [level+1], w2, v2))
RETURN best_value, best_set
END FUNCTION
Catatan: jika tidak memakai pruning, tetap enqueu anak include walau w2 > capacity, tetapi hanya menerima solusi di daun yang weight ≤ capacity. Pruning menghemat memori dan waktu.
3. Simulasi
Saya tampilkan semua daun (semua kombinasi 5-bit) dalam urutan BFS (level-order). Format: (nomor daun) decisions(0/1) → [daftar item], berat, nilai — feasible?
- 00000 → [] , berat=0 , nilai=0 — feasible
- 00001 → [5], berat=5 , nilai=20 — feasible
- 00010 → [4], berat=2 , nilai=9 — feasible
- 00011 → [4,5], berat=7 , nilai=29 — feasible
- 00100 → [3], berat=4 , nilai=16 — feasible
- 00101 → [3,5], berat=9 , nilai=36 — feasible
- 00110 → [3,4], berat=6 , nilai=25 — feasible
- 00111 → [3,4,5], berat=11 , nilai=45 — infeasible (berat>10)
- 01000 → [2], berat=3 , nilai=14 — feasible
- 01001 → [2,5], berat=8 , nilai=34 — feasible
- 01010 → [2,4], berat=5 , nilai=23 — feasible
- 01011 → [2,4,5], berat=10 , nilai=43 — feasible
- 01100 → [2,3], berat=7 , nilai=30 — feasible
- 01101 → [2,3,5], berat=12 , nilai=50 — infeasible
- 01110 → [2,3,4], berat=9 , nilai=39 — feasible
- 01111 → [2,3,4,5], berat=14 , nilai=59 — infeasible
- 10000 → [1], berat=6 , nilai=30 — feasible
- 10001 → [1,5], berat=11 , nilai=50 — infeasible
- 10010 → [1,4], berat=8 , nilai=39 — feasible
- 10011 → [1,4,5], berat=13 , nilai=59 — infeasible
- 10100 → [1,3], berat=10 , nilai=46 — feasible ← nilai tertinggi sampai titik ini
- 10101 → [1,3,5], berat=15 , nilai=66 — infeasible
- 10110 → [1,3,4], berat=12 , nilai=55 — infeasible
- 10111 → [1,3,4,5], berat=17 , nilai=75 — infeasible
- 11000 → [1,2], berat=9 , nilai=44 — feasible
- 11001 → [1,2,5], berat=14 , nilai=64 — infeasible
- 11010 → [1,2,4], berat=11 , nilai=53 — infeasible
- 11011 → [1,2,4,5], berat=16 , nilai=73 — infeasible
- 11100 → [1,2,3], berat=13 , nilai=60 — infeasible
- 11101 → [1,2,3,5], berat=18 , nilai=80 — infeasible
- 11110 → [1,2,3,4], berat=15 , nilai=69 — infeasible
- 11111 → [1,2,3,4,5], berat=20 , nilai=89 — infeasible
Komentar pada trace: dari daun-daun feasible, nilai terbaik yang ditemukan oleh BFS (dengan pruning) adalah pada daun nomor 21 (10100) → memilih item 1 dan 3.
4. Hasil akhir
- Berat total = 6 + 4 = 10 kg. (langkah aritmetika: 6 + 4 = 10)
- Nilai total = 30 + 16 = 46. (langkah aritmetika: 30 + 16 = 46)
Hasil komputasi lengkap menunjukkan kombinasi lain yang feasible tidak mencapai nilai 46 (mis. [2,4,5] memberi nilai 43; [1,2] memberi 44; dst).
Kompleksitas & Catatan
Implementasi Java
from collections import deque
items = [(6,30),(3,14),(4,16),(2,9),(5,20)] # (berat, nilai)
capacity = 10
def bfs_knapsack(items, capacity):
n = len(items)
best_value = -1
best_set = []
q = deque()
q.append((0, [], 0, 0)) # level, chosen(list of 1-based indices), weight, value
nodes_expanded = 0
while q:
level, chosen, w, v = q.popleft()
nodes_expanded += 1
if level == n:
if w <= capacity and v > best_value:
best_value = v
best_set = chosen.copy()
continue
# exclude next item
q.append((level+1, chosen.copy(), w, v))
# include next item (prune bila berat melebihi kapasitas)
w2 = w + items[level][0]
v2 = v + items[level][1]
if w2 <= capacity:
q.append((level+1, chosen + [level+1], w2, v2))
return best_value, best_set, nodes_expanded
best_value, best_set, nodes_expanded = bfs_knapsack(items, capacity)
print("Best value:", best_value)
print("Best set (item indices):", best_set)
print("Nodes expanded:", nodes_expanded)
Perkiraan output:
Best value: 46 Best set (item indices): [1, 3] Nodes expanded: (nilai tergantung implementasi; pada contoh ini ~43)

Posting Komentar