From c3310fc81f393bb648952abbec93e6a7f64afc58 Mon Sep 17 00:00:00 2001 From: aland1013 Date: Tue, 10 Nov 2020 23:43:29 -0500 Subject: [PATCH 1/8] implemented Graph class --- projects/graph/README.md | 4 ---- projects/graph/graph.py | 10 +++++++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/projects/graph/README.md b/projects/graph/README.md index e7c8489e7..1a8da8f98 100644 --- a/projects/graph/README.md +++ b/projects/graph/README.md @@ -2,7 +2,6 @@ This is a multi-stage project to implement a basic graph class and traversals. - ## Part 1: Graph Class In the file `graph.py`, implement a `Graph` class that supports the API in the example below. In particular, this means there should be a field `vertices` that @@ -65,9 +64,6 @@ Write a function within your Graph class that takes takes a starting node and a Write a function within your Graph class that takes takes a starting node and a destination node as an argument, then performs DFS. Your function should return a valid path (not necessarily the shortest) from the start node to the destination node. Note that there are multiple valid paths. - ## Part 7: Implement Depth-First Search using Recursion Write a function within your Graph class that takes takes a starting node and a destination node as an argument, then performs DFS using recursion. Your function should return a valid path (not necessarily the shortest) from the start node to the destination node. Note that there are multiple valid paths. - - diff --git a/projects/graph/graph.py b/projects/graph/graph.py index 59fecae4b..c1b00c61d 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -13,19 +13,23 @@ def add_vertex(self, vertex_id): """ Add a vertex to the graph. """ - pass # TODO + self.vertices[vertex_id] = set() def add_edge(self, v1, v2): """ Add a directed edge to the graph. """ - pass # TODO + if v1 not in self.vertices or v2 not in self.vertices: + print('Error - invalid vertex') + return + + self.vertices[v1].add(v2) def get_neighbors(self, vertex_id): """ Get all neighbors (edges) of a vertex. """ - pass # TODO + return self.vertices[vertex_id] def bft(self, starting_vertex): """ From 60899708ba66c5643d4169762e5efa7befed5dda Mon Sep 17 00:00:00 2001 From: aland1013 Date: Wed, 11 Nov 2020 07:27:40 -0500 Subject: [PATCH 2/8] implemented bft --- projects/graph/graph.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/projects/graph/graph.py b/projects/graph/graph.py index c1b00c61d..413b61e2a 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -36,7 +36,21 @@ def bft(self, starting_vertex): Print each vertex in breadth-first order beginning from starting_vertex. """ - pass # TODO + queue = Queue() + visited = set() + + queue.enqueue(starting_vertex) + + while queue.size() > 0: + current_vert = queue.dequeue() + + if current_vert not in visited: + visited.add(current_vert) + + print(current_vert) + + for vert in self.vertices[current_vert]: + queue.enqueue(vert) def dft(self, starting_vertex): """ From 7c85aec61f52cb14874b46e33280c132f2e5e0d8 Mon Sep 17 00:00:00 2001 From: aland1013 Date: Wed, 11 Nov 2020 08:01:02 -0500 Subject: [PATCH 3/8] implemented interative dft --- projects/graph/graph.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/projects/graph/graph.py b/projects/graph/graph.py index 413b61e2a..71bdd2c1f 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -57,7 +57,21 @@ def dft(self, starting_vertex): Print each vertex in depth-first order beginning from starting_vertex. """ - pass # TODO + stack = Stack() + visited = set() + + stack.push(starting_vertex) + + while stack.size() > 0: + current_vert = stack.pop() + + if current_vert not in visited: + visited.add(current_vert) + + print(current_vert) + + for v in self.vertices[current_vert]: + stack.push(v) def dft_recursive(self, starting_vertex): """ From 356608a16c2879aebcb890792d65f5b0d9eff70e Mon Sep 17 00:00:00 2001 From: aland1013 Date: Wed, 11 Nov 2020 08:48:50 -0500 Subject: [PATCH 4/8] implemented recursive dft --- projects/graph/graph.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/projects/graph/graph.py b/projects/graph/graph.py index 71bdd2c1f..bba75ed75 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -80,7 +80,17 @@ def dft_recursive(self, starting_vertex): This should be done using recursion. """ - pass # TODO + visited = set() + self.dft_helper(starting_vertex, visited) + + + def dft_helper(self, v, visited): + visited.add(v) + print(v) + + for n in self.get_neighbors(v): + if n not in visited: + self.dft_helper(n, visited) def bfs(self, starting_vertex, destination_vertex): """ From 743bf346ba8b3cd4f3bf378cac935a8a9276ef7f Mon Sep 17 00:00:00 2001 From: aland1013 Date: Wed, 11 Nov 2020 09:00:02 -0500 Subject: [PATCH 5/8] implemented bfs --- projects/graph/graph.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/projects/graph/graph.py b/projects/graph/graph.py index bba75ed75..305e7e8b4 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -98,7 +98,26 @@ def bfs(self, starting_vertex, destination_vertex): starting_vertex to destination_vertex in breath-first order. """ - pass # TODO + queue = Queue() + visited = set() + + queue.enqueue([starting_vertex]) + + while queue.size() > 0: + current_path = queue.dequeue() + current_vert = current_path[-1] + + if current_vert == destination_vertex: + return current_path + + if current_vert not in visited: + visited.add(current_vert) + + for vert in self.vertices[current_vert]: + new_path = list(current_path) + new_path.append(vert) + queue.enqueue(new_path) + def dfs(self, starting_vertex, destination_vertex): """ From a207263903d9095b2b5c7703d36464bab43ab660 Mon Sep 17 00:00:00 2001 From: aland1013 Date: Wed, 11 Nov 2020 09:03:59 -0500 Subject: [PATCH 6/8] implemented dfs --- projects/graph/graph.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/projects/graph/graph.py b/projects/graph/graph.py index 305e7e8b4..3645b6552 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -125,7 +125,25 @@ def dfs(self, starting_vertex, destination_vertex): starting_vertex to destination_vertex in depth-first order. """ - pass # TODO + stack = Stack() + visited = set() + + stack.push([starting_vertex]) + + while stack.size() > 0: + current_path = stack.pop() + current_vert = current_path[-1] + + if current_vert == destination_vertex: + return current_path + + if current_vert not in visited: + visited.add(current_vert) + + for v in self.vertices[current_vert]: + new_path = list(current_path) + new_path.append(v) + stack.push(new_path) def dfs_recursive(self, starting_vertex, destination_vertex): """ From be6606742529a97e66bb066d4fbd3a1a8ef34e0d Mon Sep 17 00:00:00 2001 From: aland1013 Date: Wed, 11 Nov 2020 16:10:39 -0500 Subject: [PATCH 7/8] implemented recursive dfs --- projects/graph/graph.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/projects/graph/graph.py b/projects/graph/graph.py index 3645b6552..bc337f2f5 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -73,24 +73,19 @@ def dft(self, starting_vertex): for v in self.vertices[current_vert]: stack.push(v) - def dft_recursive(self, starting_vertex): + def dft_recursive(self, starting_vertex, visited=set()): """ Print each vertex in depth-first order beginning from starting_vertex. This should be done using recursion. """ - visited = set() - self.dft_helper(starting_vertex, visited) - - - def dft_helper(self, v, visited): - visited.add(v) - print(v) + visited.add(starting_vertex) + print(starting_vertex) - for n in self.get_neighbors(v): + for n in self.get_neighbors(starting_vertex): if n not in visited: - self.dft_helper(n, visited) + self.dft_recursive(n, visited) def bfs(self, starting_vertex, destination_vertex): """ @@ -145,7 +140,7 @@ def dfs(self, starting_vertex, destination_vertex): new_path.append(v) stack.push(new_path) - def dfs_recursive(self, starting_vertex, destination_vertex): + def dfs_recursive(self, starting_vertex, destination_vertex, path=[], visited=set()): """ Return a list containing a path from starting_vertex to destination_vertex in @@ -153,7 +148,19 @@ def dfs_recursive(self, starting_vertex, destination_vertex): This should be done using recursion. """ - pass # TODO + path.append(starting_vertex) + visited.add(starting_vertex) + + if starting_vertex == destination_vertex: + return path + + for v in self.get_neighbors(starting_vertex): + if v not in visited: + new_path = self.dfs_recursive(v, destination_vertex, path, visited) + if new_path is not None: + return new_path + else: + path.pop() if __name__ == '__main__': graph = Graph() # Instantiate your graph From 4a29c5f3f23864bb4dc67a92ce6d27bd6db92005 Mon Sep 17 00:00:00 2001 From: aland1013 Date: Wed, 11 Nov 2020 17:19:44 -0500 Subject: [PATCH 8/8] fixed bug related to default parameter values --- projects/graph/graph.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/projects/graph/graph.py b/projects/graph/graph.py index bc337f2f5..53dad51f7 100644 --- a/projects/graph/graph.py +++ b/projects/graph/graph.py @@ -73,13 +73,16 @@ def dft(self, starting_vertex): for v in self.vertices[current_vert]: stack.push(v) - def dft_recursive(self, starting_vertex, visited=set()): + def dft_recursive(self, starting_vertex, visited=None): """ Print each vertex in depth-first order beginning from starting_vertex. This should be done using recursion. """ + if visited == None: + visited = set() + visited.add(starting_vertex) print(starting_vertex) @@ -140,7 +143,7 @@ def dfs(self, starting_vertex, destination_vertex): new_path.append(v) stack.push(new_path) - def dfs_recursive(self, starting_vertex, destination_vertex, path=[], visited=set()): + def dfs_recursive(self, starting_vertex, destination_vertex, path=None, visited=None): """ Return a list containing a path from starting_vertex to destination_vertex in @@ -148,6 +151,11 @@ def dfs_recursive(self, starting_vertex, destination_vertex, path=[], visited=se This should be done using recursion. """ + if path == None: + path = [] + if visited == None: + visited = set() + path.append(starting_vertex) visited.add(starting_vertex) @@ -161,6 +169,7 @@ def dfs_recursive(self, starting_vertex, destination_vertex, path=[], visited=se return new_path else: path.pop() + if __name__ == '__main__': graph = Graph() # Instantiate your graph @@ -228,4 +237,4 @@ def dfs_recursive(self, starting_vertex, destination_vertex, path=[], visited=se [1, 2, 4, 7, 6] ''' print(graph.dfs(1, 6)) - print(graph.dfs_recursive(1, 6)) + print(graph.dfs_recursive(1, 6)) \ No newline at end of file