def read_from_file(filename): """Read from a file located at `filename` and return the corresponding graph object.""" file = open(filename, "r") lines = file.readlines() file.close() # Check if it is a graph or digraph graph_or_digraph_str = lines[0].strip() if len(lines) > 0 else None if graph_or_digraph_str != "G" and graph_or_digraph_str != "D": raise Exception("File must start with G or D.") is_directed = graph_or_digraph_str == "D" g = Graph(is_directed) # Add all vertices for vertex_key in lines[1].strip("() \n").split(","): g.add_vertex(vertex_key) # Add all edges for line in lines[2:]: # Split components of edge new_edge = line.strip("() \n").split(",") if len(new_edge) < 2 or len(new_edge) > 3: raise Exception("Lines adding edges must include 2 or 3 values") # Get vertices vertex1, vertex2 = new_edge[:2] # Get weight if it exists weight = int(new_edge[2]) if len(new_edge) == 3 else None # Add edge(s) g.add_edge(vertex1, vertex2, weight) return g
def test_add_vertex(self): graph = Graph(True) graph.add_vertex("apple") graph.add_vertex("banana") self.assertEqual(2, graph.get_num_vertices()) self.assertIsInstance(graph.get_vertex("apple"), Vertex)
def getAllSocialPaths(self, userID): """ Takes a user's userID as an argument Returns a dictionary containing every user in that user's extended network with the shortest friendship path between them. The key is the friend's ID and the value is the path. """ visited = {} # Note that this is a dictionary, not a set # !!!! IMPLEMENT ME newGraph = Graph() for user in self.users: newGraph.add_vertex(user) for user in self.friendships: for friend in self.friendships[user]: newGraph.add_edge(user, friend) for friend in self.users: socialPath = newGraph.bfs(userID, friend) if socialPath is not False: visited[friend] = socialPath return visited
def test_add_edge(self): graph = Graph() graph.add_vertex("A") graph.add_vertex("B") graph.add_edge("A", "B", 40) self.assertDictEqual(graph.vertices["A"].neighbours, {"B": {'weight': 40, 'pheromone': 1.0}}) self.assertDictEqual(graph.vertices["B"].neighbours, {"A": {'weight': 40, 'pheromone': 1.0}}) self.assertRaises(ValueError, graph.add_edge, "A", "B", -40)
def test_returns_array_of_vertices_for_graph_without_edges(self): g = Graph() g.add_vertex(1) g.add_vertex(2) g.add_vertex(3) has_cycle, vertices = topological_sort(g) self.assertEqual(False, has_cycle) self.assertEqual([1, 2, 3], vertices)
def getAllSocialPaths(self, userID): """ Takes a user's userID as an argument Returns a dictionary containing every user in that user's extended network with the shortest friendship path between them. The key is the friend's ID and the value is the path. """ visited = {} # Note that this is a dictionary, not a set # !!!! IMPLEMENT ME # With the Graph class # runtime: 1.9708278179168701 seconds 100 users, 20 average # runtime: 24.768869876861572 seconds 200 users, 20 average # runtime: 24.120848417282104 seconds # runtime: 24.88981318473816 seconds g = Graph() for user in self.users: g.add_vertex(user) for user in self.friendships: for friend in self.friendships[user]: g.add_edge(user, friend) for friend in self.users: path = g.bfs(userID, friend) if path is not False: visited[friend] = path # Without the Graph class but have Queue # runtime: 1.8722269535064697 seconds # runtime: 27.13098406791687 seconds # runtime: 26.577613592147827 seconds # runtime: 26.608980178833008 seconds # for friend in self.users: # q = Queue() # visit = set() # path = [] # q.enqueue([userID]) # while len(q.storage) > 0: # node = q.dequeue() # path = node # vnode = node[-1] # if vnode == friend: # visited[friend] = path # pass # visit.add(vnode) # for child in self.friendships[vnode]: # if child not in visit: # dup_node = node[:] # dup_node.append(child) # q.enqueue(dup_node) return visited
def test_get_edge_as_tuple(self): graph = Graph(True) v1 = graph.add_vertex("apple") v2 = graph.add_vertex("banana") v3 = graph.add_vertex("coconut") graph.add_edge("apple", "banana") graph.add_edge("apple", "coconut", 3) self.assertEqual(("apple", "banana"), graph.get_edge_as_tuple(v1, v2)) self.assertEqual(("apple", "coconut", 3), graph.get_edge_as_tuple(v1, v3))
def test_incident_invariant_is_preserved_throughout_graph_operations(self): g = Graph(directed = True) g.add_vertex(1) self.assertEqual(g.incident(1), [], 'should have instantiated an empty set of ingress vertices') g.add_edge((2,1)) g.add_edge((2,1)) self.assertEqual(g.incident(1), [2], 'set of incident vertices is preserved') self.assertEqual(g.incident(2), [], 'no vertices incident in 2') g.remove_edge((2,1)) self.assertEqual(g.incident(1), [], '2 was removed from the list of incident vertices for 3')
def test_incident_invariant_is_preserved_throughout_graph_operations(self): g = Graph(directed=True) g.add_vertex(1) self.assertEqual( g.incident(1), [], 'should have instantiated an empty set of ingress vertices') g.add_edge((2, 1)) g.add_edge((2, 1)) self.assertEqual(g.incident(1), [2], 'set of incident vertices is preserved') self.assertEqual(g.incident(2), [], 'no vertices incident in 2') g.remove_edge((2, 1)) self.assertEqual( g.incident(1), [], '2 was removed from the list of incident vertices for 3')
def test_add_edge(self): graph = Graph(True) graph.add_vertex("apple") graph.add_vertex("banana") graph.add_vertex("coconut") graph.add_edge("apple", "banana") graph.add_edge("apple", "coconut", 3) self.assertEqual(3, graph.get_num_vertices()) self.assertEqual(2, graph.get_num_edges()) graph.add_edge("pineapple", "strawberry") self.assertEqual(5, graph.get_num_vertices()) self.assertEqual(3, graph.get_num_edges()) self.assertCountEqual( ["apple", "banana", "coconut", "pineapple", "strawberry"], graph.get_vertices())
def test_add_vertex(self): g = Graph() g.add_vertex(1) self.assertIn(1, g.table, 'should have stored a key in the hash') self.assertEqual(g.table[1], {}, 'should have stored an empty hash')
def test_remove_vertex_removes_value_as_well(self): g = Graph(False) g.add_vertex(1) g.set_vertex_value(1, 100) g.remove_vertex(1) self.assertIsNone(g.get_vertex_value(1), '1 is no longer in the graph')
def test_returns_single_vertex_for_graph_with_single_vertex(self): g = Graph() g.add_vertex(1) has_cycle, vertices = topological_sort(g) self.assertEqual(False, has_cycle) self.assertEqual([1], vertices)