diff --git a/Graph/graph/traversing.py b/Graph/graph/traversing.py index 07f7da43764ad77441bf23aee5ff8ecd065c32b7..3d66df140b6c327c39660d0f01a2e9f8b26a7487 100644 --- a/Graph/graph/traversing.py +++ b/Graph/graph/traversing.py @@ -65,3 +65,46 @@ def BFS(graph: Graph, node: Node) -> Iterator[Tuple[Node, List[Edge]]]: :return: """ return _traversing(LIFO(), graph, node) + + +def Dikjstra(graph, start_node, target_node): + to_visit = LIFO() + to_visit.add(start_node) + visited = set() + parent = {} + ########################## + # graph traversing + ########################## + path = [] + rank = 0 + while to_visit: + rank += 1 + node = to_visit.pop() + # it is important to add node in visited right now + # and not a the end of the block + # otherwise node is not anymore in to_visit and not yet in visited + # so when we explore neighbors we add it again in to_visit + visited.add(node) + for edge in graph.edges(node): + if edge.target not in visited and edge.target not in to_visit: + edge['rank'] = rank + parent[edge.target] = edge + to_visit.add(edge.target) + + + ########################### + # find paths + ########################### + def find_parent(graph, node, rank, path): + path = [] + nbh = [e.target for e in graph.edges(node) if e.rank == rank] + path.append(nbh[0]) + if nbh[0] != start_node: + find_parent(graph, nbh[0], rank - 1, path) + return path + + rank = min([e.rank for e in graph.edges(target_node)]) + paths = find_parent(graph, target_node, rank, []) + return paths + +