|
1 |
| -#!/usr/bin/python |
2 |
| - |
3 |
| -""" Author: OMKAR PATHAK """ |
4 |
| - |
5 |
| - |
6 |
| -class Graph: |
7 |
| - def __init__(self): |
8 |
| - self.vertex = {} |
9 |
| - |
10 |
| - # for printing the Graph vertices |
11 |
| - def printGraph(self): |
12 |
| - print(self.vertex) |
13 |
| - for i in self.vertex.keys(): |
14 |
| - print(i, " -> ", " -> ".join([str(j) for j in self.vertex[i]])) |
15 |
| - |
16 |
| - # for adding the edge between two vertices |
17 |
| - def addEdge(self, fromVertex, toVertex): |
18 |
| - # check if vertex is already present, |
19 |
| - if fromVertex in self.vertex.keys(): |
20 |
| - self.vertex[fromVertex].append(toVertex) |
21 |
| - else: |
22 |
| - # else make a new vertex |
23 |
| - self.vertex[fromVertex] = [toVertex] |
24 |
| - |
25 |
| - def DFS(self): |
26 |
| - # visited array for storing already visited nodes |
27 |
| - visited = [False] * len(self.vertex) |
28 |
| - |
29 |
| - # call the recursive helper function |
30 |
| - for i in range(len(self.vertex)): |
31 |
| - if visited[i] == False: |
32 |
| - self.DFSRec(i, visited) |
33 |
| - |
34 |
| - def DFSRec(self, startVertex, visited): |
35 |
| - # mark start vertex as visited |
36 |
| - visited[startVertex] = True |
37 |
| - |
38 |
| - print(startVertex, end=" ") |
39 |
| - |
40 |
| - # Recur for all the vertices that are adjacent to this node |
41 |
| - for i in self.vertex.keys(): |
42 |
| - if visited[i] == False: |
43 |
| - self.DFSRec(i, visited) |
44 |
| - |
| 1 | +"""The DFS function simply calls itself recursively for every unvisited child of |
| 2 | +its argument. We can emulate that behaviour precisely using a stack of iterators. |
| 3 | +Instead of recursively calling with a node, we'll push an iterator to the node's |
| 4 | +children onto the iterator stack. When the iterator at the top of the stack |
| 5 | +terminates, we'll pop it off the stack. |
| 6 | +
|
| 7 | +Pseudocode: |
| 8 | + all nodes initially unexplored |
| 9 | + mark s as explored |
| 10 | + for every edge (s, v): |
| 11 | + if v unexplored: |
| 12 | + DFS(G, v) |
| 13 | +""" |
| 14 | + |
| 15 | +from typing import Set, Dict |
| 16 | + |
| 17 | + |
| 18 | +def depth_first_search(graph: Dict, start: str) -> Set[int]: |
| 19 | + """Depth First Search on Graph |
| 20 | +
|
| 21 | + :param graph: directed graph in dictionary format |
| 22 | + :param vertex: starting vectex as a string |
| 23 | + :returns: the trace of the search |
| 24 | + >>> G = { "A": ["B", "C", "D"], "B": ["A", "D", "E"], |
| 25 | + ... "C": ["A", "F"], "D": ["B", "D"], "E": ["B", "F"], |
| 26 | + ... "F": ["C", "E", "G"], "G": ["F"] } |
| 27 | + >>> start = "A" |
| 28 | + >>> output_G = list({'A', 'B', 'C', 'D', 'E', 'F', 'G'}) |
| 29 | + >>> all(x in output_G for x in list(depth_first_search(G, "A"))) |
| 30 | + True |
| 31 | + >>> all(x in output_G for x in list(depth_first_search(G, "G"))) |
| 32 | + True |
| 33 | + """ |
| 34 | + explored, stack = set(start), [start] |
| 35 | + while stack: |
| 36 | + v = stack.pop() |
| 37 | + # one difference from BFS is to pop last element here instead of first one |
| 38 | + for w in graph[v]: |
| 39 | + if w not in explored: |
| 40 | + explored.add(w) |
| 41 | + stack.append(w) |
| 42 | + return explored |
| 43 | + |
| 44 | + |
| 45 | +G = { |
| 46 | + "A": ["B", "C", "D"], |
| 47 | + "B": ["A", "D", "E"], |
| 48 | + "C": ["A", "F"], |
| 49 | + "D": ["B", "D"], |
| 50 | + "E": ["B", "F"], |
| 51 | + "F": ["C", "E", "G"], |
| 52 | + "G": ["F"], |
| 53 | +} |
45 | 54 |
|
46 | 55 | if __name__ == "__main__":
|
47 |
| - g = Graph() |
48 |
| - g.addEdge(0, 1) |
49 |
| - g.addEdge(0, 2) |
50 |
| - g.addEdge(1, 2) |
51 |
| - g.addEdge(2, 0) |
52 |
| - g.addEdge(2, 3) |
53 |
| - g.addEdge(3, 3) |
54 |
| - |
55 |
| - g.printGraph() |
56 |
| - print("DFS:") |
57 |
| - g.DFS() |
| 56 | + import doctest |
58 | 57 |
|
59 |
| - # OUTPUT: |
60 |
| - # 0 -> 1 -> 2 |
61 |
| - # 1 -> 2 |
62 |
| - # 2 -> 0 -> 3 |
63 |
| - # 3 -> 3 |
64 |
| - # DFS: |
65 |
| - # 0 1 2 3 |
| 58 | + doctest.testmod() |
| 59 | + print(depth_first_search(G, "A")) |
0 commit comments