Dalam bidang ilmu komputer, khususnya pada permasalahan pencarian jalur terpendek, algoritma Dijkstra dan A* seringkali menjadi pilihan utama. Keduanya memiliki tujuan yang sama, yaitu menemukan jalur terpendek dari satu titik ke titik lainnya pada sebuah graf. Namun, terdapat perbedaan mendasar dalam cara keduanya bekerja yang akan kita bahas secara detail.
Algoritma Dijkstra merupakan algoritma pencarian jalur terpendek yang sangat populer. Algoritma ini bekerja dengan prinsip greedy, yaitu selalu memilih jalur dengan biaya terkecil pada setiap langkah. Dijkstra menjamin bahwa jalur yang ditemukan adalah jalur terpendek menuju semua simpul, namun membutuhkan waktu komputasi yang cukup lama terutama pada graf yang besar.
import heapq
def dijkstra(graph, start):
distances = {node: float('inf') for node in graph}
distances[start] = 0
priority_queue = [(0, start)]
while priority_queue:
current_distance, current_node = heapq.heappop(priority_queue)
if current_distance > distances[current_node]:
continue
for neighbor, weight in graph[current_node].items():
distance = current_distance + weight
if distance < distances[neighbor]:
distances[neighbor] = distance
heapq.heappush(priority_queue, (distance, neighbor))
return distances
Algoritma A* merupakan pengembangan dari algoritma Dijkstra. Perbedaan utama A* adalah adanya heuristik, yaitu perkiraan biaya dari simpul saat ini ke simpul tujuan. Heuristik ini digunakan untuk memandu pencarian agar lebih efisien. Kombinasi antara biaya yang sudah dilalui dan heuristic ini menghasilkan fungsi f(n) yang digunakan untuk menentukan node mana yang akan dikunjungi selanjutnya.
Algoritma A* menjamin bahwa jalur yang ditemukan adalah jalur terpendek jika heuristik yang digunakan adalah admissible (tidak pernah overestimate) dan consistent (selalu underestimate).
import heapq
class Node:
def __init__(self, x, y, g, h, parent=None):
self.x = x
self.y = y
self.g = g # Biaya aktual
self.h = h # Heuristic
self.f = g + h
self.parent = parent
def __lt__(self, other):
return self.f < other.f
def astar(start, goal, grid):
open_set = []
closed_set = set()
# Tambahkan node awal ke open_set
start_node = Node(start[0], start[1], 0, heuristic(start, goal))
heapq.heappush(open_set, start_node)
while open_set:
current = heapq.heappop(open_set)
closed_set.add(current)
if current.x == goal[0] and current.y == goal[1]:
path = []
while current is not None:
path.append((current.x, current.y))
current = current.parent
return path[::-1]
# Generate neighbors
neighbors = [(current.x-1, current.y), (current.x+1, current.y),
(current.x, current.y-1), (current.x, current.y+1)]
for neighbor in neighbors:
if 0 <= neighbor[0] < len(grid) and 0 <= neighbor[1] < len(grid[0]) and grid[neighbor[0]][neighbor[1]] == 0: # Pastikan dalam batas grid dan bisa dilewati
neighbor_node = Node(neighbor[0], neighbor[1], current.g + 1, heuristic(neighbor, goal), current)
if neighbor_node not in closed_set:
if neighbor_node not in open_set or neighbor_node.f < open_set[open_set.index(neighbor_node)].f:
heapq.heappush(open_set, neighbor_node)
return None # Jika tidak ditemukan jalur
def heuristic(a, b):
# Euclidean distance
return ((a[0] - b[0])**2 + (a[1] - b[1])**2)**0.5
# Contoh penggunaan
grid = [[0, 0, 0],
[0, 1, 0],
[0, 0, 0]] # 1 adalah dinding, 0 adalah jalan
start = (0, 0)
goal = (2, 2)
path = astar(start, goal, grid)
print(path)
Peningkatan:
Fitur | Algoritma Dijkstra | Algoritma A* |
---|---|---|
Heuristik | Tidak ada | Ada |
Efisiensi | Kurang efisien | Lebih efisien |
Kelengkapan | Menemukan jalur terpendek ke semua simpul | Menemukan jalur terpendek ke tujuan |
Kompleksitas | O(V^2) | Tergantung heuristik |
Fitur | Dijkstra | A* |
---|---|---|
Waktu (tanpa PQ) | O(V^2) | O(V^2) |
Waktu (dengan PQ) | O(E log V) | O(E log V) |
Ruang | O(V) | O(V) |
Faktor yang Mempengaruhi Kinerja:
Penting untuk diingat: Kompleksitas waktu dan ruang di atas adalah batas atas. Dalam praktiknya, kinerja algoritma dapat bervariasi tergantung pada struktur graf dan input yang diberikan.
Algoritma Dijkstra dan A* banyak digunakan dalam berbagai aplikasi, seperti:
Algoritma Dijkstra dan A* adalah dua algoritma pencarian jalur terpendek yang sangat berguna. Pilihan algoritma yang tepat tergantung pada permasalahan yang ingin dipecahkan dan informasi yang tersedia. Algoritma A* umumnya lebih efisien dibandingkan Dijkstra, terutama pada graf yang besar, namun membutuhkan desain heuristik yang baik.
Referensi:
Catatan:
Artikel ini dibuat untuk tujuan pembelajaran dan pemahaman dasar mengenai algoritma Dijkstra dan A*. Implementasi sebenarnya dalam aplikasi nyata mungkin memerlukan pertimbangan dan optimasi yang lebih kompleks.