|
1 | 1 | def longest_path(graph):
|
2 | | - # initialise a dictionary to keep track of distances of each node from a terminal node |
| 2 | + """ |
| 3 | + Calculate the longest path in a Directed Acyclic Graph (DAG) where the path length |
| 4 | + is defined as the number of edges from a node to a terminal node. |
| 5 | + |
| 6 | + Args: |
| 7 | + graph (dict): A dictionary representing the DAG where keys are node labels |
| 8 | + and values are lists of adjacent nodes. |
| 9 | + |
| 10 | + Returns: |
| 11 | + int: The length of the longest path in the graph. |
| 12 | + """ |
| 13 | + |
| 14 | + # Initialize a dictionary to keep track of distances of each node from a terminal node. |
3 | 15 | distance = {}
|
4 | | - |
| 16 | + |
| 17 | + # Iterate through each node in the graph. |
5 | 18 | for node in graph:
|
6 | | - if graph[node] == []:# this indicates a terminal node due to absence of neighbors |
7 | | - distance[node] = 0 # distance from a terminal node to a terminal node is 0 |
| 19 | + # Check if the node is a terminal node (i.e., has no neighbors). |
| 20 | + if graph[node] == []: |
| 21 | + # Distance from a terminal node to itself is 0. |
| 22 | + distance[node] = 0 |
8 | 23 |
|
9 | | - # start traversal of graph from each node |
| 24 | + # Start traversal of the graph from each node. |
10 | 25 | for node in graph:
|
11 | | - # pass to helper function that mutates the distance dictionary |
| 26 | + # Call the helper function that mutates the distance dictionary. |
12 | 27 | traverse_distance(graph, node, distance)
|
13 | 28 |
|
14 | | - # finally return the max value of the distance dictionary values |
| 29 | + # Finally, return the maximum value of the distances recorded. |
15 | 30 | return max(distance.values())
|
16 | 31 |
|
| 32 | + |
17 | 33 | def traverse_distance(graph, node, distance):
|
| 34 | + """ |
| 35 | + Helper function to recursively calculate the distance of each node from a terminal node. |
| 36 | + |
| 37 | + Args: |
| 38 | + graph (dict): The DAG represented as an adjacency list. |
| 39 | + node (any): The current node being processed. |
| 40 | + distance (dict): Dictionary storing the distances of nodes from terminal nodes. |
| 41 | + |
| 42 | + Returns: |
| 43 | + int: The distance of the current node from a terminal node. |
| 44 | + """ |
| 45 | + |
| 46 | + # If the node's distance has already been calculated, return it. |
18 | 47 | if node in distance:
|
19 | | - return distance[node] # return the distance of the node from the terminal node if already precalculated |
20 | | - |
| 48 | + return distance[node] |
| 49 | + |
| 50 | + # Initialize the largest distance found among neighbors to 0. |
21 | 51 | largest = 0
|
22 | 52 |
|
| 53 | + # Iterate through each neighbor of the current node. |
23 | 54 | for neighbor in graph[node]:
|
24 | | - temp = traverse_distance(graph, neighbor, distance) # note here that the recursive call returns a number ie. distance from neighbor to terminal node |
| 55 | + # Recursively calculate the distance for the neighbor. |
| 56 | + temp = traverse_distance(graph, neighbor, distance) |
| 57 | + # Update the largest distance if the current neighbor's distance is greater. |
25 | 58 | if temp > largest:
|
26 | 59 | largest = temp
|
27 | | - |
28 | | - distance[node] = 1+largest # store the distance of the current node from terminal node so that it does not have to be recalculated |
29 | | - |
| 60 | + |
| 61 | + # Store the distance of the current node (1 + largest distance among neighbors). |
| 62 | + distance[node] = 1 + largest |
| 63 | + |
| 64 | + # Return the calculated distance for the current node. |
30 | 65 | return distance[node]
|
31 | 66 |
|
| 67 | + |
32 | 68 | """
|
33 | 69 | e = # edges
|
34 | 70 | n = # nodes
|
|
0 commit comments