Write a Python function to find the shortest path in a graph using Dijkstra's algorithm.
Posted by AliceWk
Last Updated: August 20, 2024
Finding the Shortest Path in a Graph Using Dijkstra's Algorithm
Dijkstra's algorithm is a popular method for finding the shortest path from a starting node to all other nodes in a weighted graph. It works on the principle of greedy optimization and operates on graphs where all edge weights are non-negative. Below is a Python function that implements Dijkstra's algorithm. The function uses a priority queue to efficiently fetch the next node with the smallest tentative distance.
Python Implementation
import heapq

def dijkstra(graph, start):
    # Initialize distances with infinity
    distances = {node: float('inf') for node in graph}
    distances[start] = 0  # Distance from start to itself is 0
    
    # Priority queue to maintain nodes to visit
    priority_queue = [(0, start)]  # (distance, node)
    
    while priority_queue:
        current_distance, current_node = heapq.heappop(priority_queue)
        
        # Nodes can only be added once; we skip processing if a longer distance is found
        if current_distance > distances[current_node]:
            continue
        
        # Explore neighbors
        for neighbor, weight in graph[current_node].items():
            distance = current_distance + weight
            
            # Only consider this new path if it's better
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(priority_queue, (distance, neighbor))
                
    return distances

# Example graph represented as an adjacency list
graph = {
    'A': {'B': 1, 'C': 4},
    'B': {'A': 1, 'C': 2, 'D': 5},
    'C': {'A': 4, 'B': 2, 'D': 1},
    'D': {'B': 5, 'C': 1}
}

# Compute shortest paths from node 'A'
shortest_paths = dijkstra(graph, 'A')
print(shortest_paths)
Explanation of the Code
1. Graph Representation: The graph is represented as a dictionary of dictionaries (adjacency list). Each key is a node, and its value is another dictionary, where keys are neighboring nodes and values are the weights of the edges connecting them. 2. Initialization: - distances: A dictionary that holds the shortest known distance from the start node to each node, initialized to infinity (float('inf')), except for the start node which is initialized to 0. - priority_queue: A min-heap (using heapq) that stores tuples of (distance, node) to efficiently retrieve the node with the smallest distance. 3. Processing Nodes: - The while loop continues until there are no more nodes in the priority queue. - Each iteration pops the smallest distance node. - If a node's current distance is greater than the recorded distance, it is skipped. - For each neighbor of the current node, the function calculates the potential new distance. If this distance is shorter than the recorded distance, it updates the dictionary and adds the neighbor to the priority queue. 4. Output: The function returns a dictionary containing the shortest distance from the start node to each other node in the graph.
Conclusion
Dijkstra's algorithm is highly efficient for finding the shortest paths in graphs with non-negative weights. This implementation provides a clear and systematic approach to solving this problem using Python, demonstrating the power of the heap data structure for optimizing search times.