Dijkstra dan Bellman-Ford adalah dua algoritma fundamental untuk shortest path. Di episode ini kalian memahami Dijkstra dengan greedy dan priority queue untuk graph tanpa edge negatif, Bellman-Ford dengan dynamic programming untuk graph dengan edge negatif, serta mempraktikkan keduanya pada road network.

Setelah di episode 17 kita memahami topological sort dan cycle detection, pada episode ini kita mempelajari shortest path — dua algoritma yang menjawab pertanyaan: "Jalur mana dari A ke B yang total bobotnya paling kecil?" Dijkstra dan Bellman-Ford adalah dua solusi fundamental untuk masalah ini, masing-masing dengan trade-off yang berbeda.
Dijkstra lebih cepat tetapi tidak bisa menangani edge negatif. Bellman-Ford lebih lambat tetapi bisa menangani edge negatif dan mendeteksi negative cycle. Pemilihan antara keduanya tergantung pada sifat graph yang kalian hadapi.
Dijkstra menggunakan pendekatan greedy: dari semua node yang belum dikunjungi, pilih yang memiliki jarak terpendek dari source. Menggunakan priority queue (binary heap) untuk efisiensi.
import heapq
def dijkstra(graph, start):
distances = {node: float('inf') for node in graph}
distances[start] = 0
pq = [(0, start)]
previous = {node: None for node in graph}
while pq:
current_dist, current_node = heapq.heappop(pq)
if current_dist > distances[current_node]:
continue
for neighbor, weight in graph[current_node]:
distance = current_dist + weight
if distance < distances[neighbor]:
distances[neighbor] = distance
previous[neighbor] = current_node
heapq.heappush(pq, (distance, neighbor))
return distances, previousBellman-Ford menggunakan dynamic programming: relaksasi semua edge sebanyak V-1 kali. Jika setelah V-1 kali masih ada yang berkurang, berarti ada negative cycle.
def bellman_ford(edges, num_nodes, start):
distances = [float('inf')] * num_nodes
distances[start] = 0
for _ in range(num_nodes - 1):
for u, v, weight in edges:
if distances[u] + weight < distances[v]:
distances[v] = distances[u] + weight
for u, v, weight in edges:
if distances[u] + weight < distances[v]:
return None # Negative cycle terdeteksi
return distancesEdge negatif: bobot < 0. Negative cycle: cycle dengan total bobot negatif → bisa loop tanpa hingga untuk mengurangi jarak. Bellman-Ford mendeteksinya karena jarak masih berkurang setelah V-1 kali relaksasi.
| Aspek | Dijkstra | Bellman-Ford |
|---|---|---|
| Kompleksitas | O((V+E) log V) | O(VE) |
| Edge negatif | Tidak boleh | Boleh |
| Negative cycle | Tidak bisa deteksi | Bisa deteksi |
| Data structure | Priority queue | Tidak perlu |
| Kasus | Road network, routing | Currency arbitrage |
graph = {
'A': [('B', 4), ('C', 2)],
'B': [('A', 4), ('C', 1), ('D', 5)],
'C': [('A', 2), ('B', 1), ('D', 8)],
'D': [('B', 5), ('C', 8)]
}
distances, previous = dijkstra(graph, 'A')
print("Distances from A:", distances)edges = [
(0, 1, 4), (0, 2, 2), (1, 2, -1),
(1, 3, 5), (2, 3, 8)
]
distances = bellman_ford(edges, 4, 0)
print("Bellman-Ford distances:", distances)Note
Dijkstra menggunakan priority queue (binary heap) yang kita pelajari di episode 8. Jika kalian belum familiar dengan binary heap, kembali ke episode 8 sebelum meneruskan episode ini.
Inti yang harus dibawa pulang:
Di episode 19 selanjutnya kita akan membahas Minimum Spanning Tree (Kruskal & Prim) — dua algoritma untuk menemukan subset edge dengan total bobot minimum yang menghubungkan semua node. Kruskal menggunakan Union-Find (yang akan kita pelajari mendalam di episode 20), Prim menggunakan priority queue. Pastikan kalian sudah paham edge weighting karena MST beroperasi pada weighted undirected graph!