def test_get_vertices_for_directed_graph(self): g = Graph(True) g.add_edge((1, 2)) actual = g.get_vertices() expected = [1, 2] self.assertEqual(actual, expected, 'should return all vertices')
def read_graph_from_file(file_name: str): try: with open(file_name) as graph_file: graph_temp = Graph() for line in graph_file.readlines(): lst = line.split() if len(lst) == 2: if graph_temp.is_vertex(lst[0]): graph_temp.start = lst[0] if graph_temp.is_vertex(lst[1]): graph_temp.end = lst[1] elif len(lst) == 3: vertex_1 = lst[0] vertex_2 = lst[1] edge_weight = int(lst[2]) if edge_weight > 0: graph_temp.add_edge(vertex_1.strip(), vertex_2.strip(), edge_weight) else: print("ERROR: Wrong file format.") return Graph() if graph_temp.start is None: graph_temp.start = graph_temp.vertices[list( graph_temp.vertices.keys())[0]] if graph_temp.end is None: graph_temp.end = graph_temp.vertices[list( graph_temp.vertices.keys())[-1]] return graph_temp except FileNotFoundError: print("ERROR: File ", file_name, " not found.") print("Current folder: " + str(Path.cwd())) return None
def test_set_edge_value_if_edge_exists(self): g = Graph(True) g.add_edge((1,2,10)) g.set_edge_value((1,2), 20) self.assertEqual(g.table[1][2], 20, 'should have updated the edge value')
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 update_MST_4(G: Graph, T: Graph, e: Tuple[str, str], weight: int): """ Sig: Graph G(V, E), Graph T(V, E), edge e, int -> Pre: Post: Ex: TestCase 4 below """ (u, v) = e assert (e in G and e in T and weight > G.weight(u, v)) G.set_weight(u, v, weight) T.remove_edge(u, v) a_nodes = set() dfs(T, u, a_nodes) all_edges = G.edges min_edge = e for (l, m) in all_edges: # Variant: len(all_edges) - all_edges.index((l, m)) if (l in a_nodes and m not in a_nodes) or (m in a_nodes and l not in a_nodes): (u, v) = min_edge if G.weight(l, m) < G.weight(u, v): min_edge = (l, m) (u, v) = min_edge T.add_edge(u, v, G.weight(u, v))
def test_adjacent_in_directed_graphs(self): g = Graph(True) g.add_edge((1, 2)) self.assertTrue(g.adjacent(1, 2), 'should find them adjacent') self.assertFalse(g.adjacent(2, 1), 'the edge is pointing the other way')
class ReverseDelete(object): name = 'reversedelete' def __init__(self, save_all_edges=False): self.queue = PriorityQueue() self.graph = Graph() self.logging = False self.save_all_edges = save_all_edges self.all_edges = [] def set_logging(self, level): if level == 'debug': self.logging = True def add_edge(self, node1, node2, weight, n, n_nodes, n_edges): self.queue.put((-weight, (node1, node2))) if self.save_all_edges: self.all_edges.append((node1, node2, weight)) def init_from_file(self, f): self.graph.import_data(f, self.add_edge) def solve(self): res = [] while not self.queue.empty(): (weight, edge) = self.queue.get() self.graph.remove_edge(edge[0], edge[1]) if not self.graph.is_connected(): self.graph.add_edge(edge[0], edge[1], -weight) res.append((edge[0], edge[1], -weight)) continue return (self.graph.n_nodes, len(res), res)
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_set_edge_value_if_edge_exists(self): g = Graph(True) g.add_edge((1, 2, 10)) g.set_edge_value((1, 2), 20) self.assertEqual(g.table[1][2], 20, 'should have updated the edge value')
def test_add_edge_node_does_node_exist(): graph = Graph() graph.add_edge(1, 2) expected = {} output = graph.graph assert output == expected
def test_breadth_first_search_complex(capsys): graph = Graph() graph.graph['A'] = set() graph.graph['B'] = set() graph.graph['C'] = set() graph.graph['D'] = set() graph.graph['E'] = set() graph.graph['F'] = set() graph.graph['G'] = set() graph.graph['H'] = set() graph.add_edge('A', 'B') graph.add_edge('A', 'C') graph.add_edge('A', 'D') graph.add_edge('B', 'E') graph.add_edge('C', 'F') graph.add_edge('C', 'G') graph.add_edge('D', 'G') graph.add_edge('E', 'H') graph.add_edge('F', 'H') graph.add_edge('G', 'H') graph.breadth_first_search('A') expected = "A B C D E F G H " output = capsys.readouterr().out assert output == expected
def test_get_vertices_for_directed_graph(self): g = Graph(True) g.add_edge((1,2)) actual = g.get_vertices() expected = [1,2] self.assertEqual(actual, expected, 'should return all vertices')
def test_set_edge_value_works_for_undirected_graphs(self): g = Graph(False) g.add_edge((1, 2, 10)) g.set_edge_value((1, 2), 30) self.assertEqual(g.table[1][2], 30, 'has updated the edge') self.assertEqual(g.table[2][1], 30, 'reverse edge was updated too')
def test_returns_array_of_vertices_for_graph_as_list(self): g = Graph() g.add_edge(1, 2, 1) g.add_edge(2, 3, 1) has_cycle, vertices = topological_sort(g) self.assertEqual(False, has_cycle) self.assertEqual([3, 2, 1], vertices)
def test_set_edge_value_works_for_undirected_graphs(self): g = Graph(False) g.add_edge((1,2,10)) g.set_edge_value((1,2), 30) self.assertEqual(g.table[1][2], 30, 'has updated the edge') self.assertEqual(g.table[2][1], 30, 'reverse edge was updated too')
def test_get_edge_value_in_directed_graph(self): g = Graph(True) g.add_edge((1,2,3)) self.assertEqual(g.get_edge_value((1,2)), 3, 'should have stored value') self.assertIsNone(g.get_edge_value((2,1)), 'should have no value for reverse edge')
def test_set_edge_value_if_graph_is_directed_and_inverse_edge_exists(self): g = Graph(True) g.add_edge((1, 2, 10)) g.add_edge((2, 1, 20)) g.set_edge_value((1, 2), 30) self.assertEqual(g.table[1][2], 30, 'has updated the edge') self.assertEqual(g.table[2][1], 20, 'reverse edge remained the same')
def test_returns_array_of_vertices_for_graph_with_dependent_vertices(self): g = Graph() g.add_edge(1, 2, 1) g.add_edge(4, 1, 1) g.add_edge(3, 1, 1) has_cycle, vertices = topological_sort(g) self.assertEqual(False, has_cycle) self.assertEqual(any_of([2, 1, 4, 3], [2, 1, 3, 4]), vertices)
def test_get_edge_value_in_directed_graph(self): g = Graph(True) g.add_edge((1, 2, 3)) self.assertEqual(g.get_edge_value((1, 2)), 3, 'should have stored value') self.assertIsNone(g.get_edge_value((2, 1)), 'should have no value for reverse edge')
def test_incident_in_directed_graph(self): g = Graph(directed=True) g.add_edge((2, 1)) g.add_edge((3, 1)) actual = g.incident(1) expected = [2, 3] self.assertEqual(actual, expected, '1 has two incident vertexes')
def test_add_edge_node_to_itself(): graph = Graph() graph.graph["node_1"] = set() graph.add_edge("node_1", "node_1") expected = {"node_1": {"node_1"}} output = graph.graph assert output == expected
def test_set_edge_value_if_graph_is_directed_and_inverse_edge_exists(self): g = Graph(True) g.add_edge((1,2,10)) g.add_edge((2,1,20)) g.set_edge_value((1,2), 30) self.assertEqual(g.table[1][2], 30, 'has updated the edge') self.assertEqual(g.table[2][1], 20, 'reverse edge remained the same')
def dfs_residual(G: Graph, R: Graph, node: str, nodes: Set[str]): nodes.add(node) for neighbor in G.neighbors(node): capacity = G.capacity(node, neighbor) flow = G.flow(node, neighbor) R.add_edge(neighbor, node, capacity=flow, flow=0) if neighbor not in nodes: dfs_residual(G, R, neighbor, nodes)
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_incident_in_directed_graph(self): g = Graph(directed = True) g.add_edge((2,1)) g.add_edge((3,1)) actual = g.incident(1) expected = [2, 3] self.assertEqual(actual, expected, '1 has two incident vertexes')
def test_egress(self): g = Graph(False) g.add_edge((1, 2, 10)) g.add_edge((1, 3, 11)) g.add_edge((2, 3, 12)) actual = g.egress(1) expected = [(1, 2, 10), (1, 3, 11)] self.assertEqual(actual, expected, 'should return ingress edges')
def test_add_edge_multiple_times_nothing_happens(self): g = Graph(True) g.add_edge((1, 2, 3)) g.add_edge((1, 2, 3)) g.add_edge((1, 2, 3)) g.add_edge((1, 2, 3)) self.assertIn(1, g.table, 'should have stored the tail in table') self.assertIn(2, g.table[1], 'should have stored the head in table')
def test_get_weight(self): """ Test getting the weight of an edge between two nodes. """ g = Graph() g.add_node("A") g.add_node("B") g.add_edge("A", "B", 123.45) self.assertEqual(g.get_weight("A", "B"), 123.45)
def test_returns_none_for_graph_with_cycle(self): g = Graph() g.add_edge(1, 2, 1) g.add_edge(4, 1, 1) g.add_edge(3, 1, 1) g.add_edge(2, 3, 1) has_cycle, vertices = topological_sort(g) self.assertEqual(True, has_cycle) self.assertIsNone(vertices)
def union(graph1: Graph, graph2: Graph): caminoUnionG1G2 = Graph(multi_graph=True) for i in graph1.get_edges(): caminoUnionG1G2.add_edge(i[0], i[1]) for e in graph2.get_edges(): caminoUnionG1G2.add_edge(e[0], e[1]) return caminoUnionG1G2
def test_add_edge_multiple_times_nothing_happens(self): g = Graph(True) g.add_edge((1,2,3)) g.add_edge((1,2,3)) g.add_edge((1,2,3)) g.add_edge((1,2,3)) self.assertIn(1, g.table, 'should have stored the tail in table') self.assertIn(2, g.table[1], 'should have stored the head in table')
def test_egress(self): g = Graph(False) g.add_edge((1, 2, 10)) g.add_edge((1, 3, 11)) g.add_edge((2, 3, 12)) actual = g.egress(1) expected = [(1, 2, 10), (1, 3, 11)] self.assertEqual(actual, expected, 'should return ingress edges')
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_remove_edge_in_directed_graph(self): g = Graph(True) g.add_edge((1,2,10)) g.add_edge((2,3,11)) g.add_edge((3,1,12)) g.remove_edge((2,3)) self.assertEqual(g.table[1][2], 10, 'should have kept the edge') self.assertEqual(g.table[3][1], 12, 'should have kept the edge') self.assertEqual(g.table[2], {}, 'should have removed the edge')
def test_get_vertices_for_undirected_graph(self): g = Graph(False) g.add_edge((1, 2)) g.add_edge((2, 3)) g.add_edge((3, 1)) actual = g.get_edges() expected = [(1, 2, True), (1, 3, True), (2, 3, True)] self.assertEqual(actual, expected, 'should return only one way edges')
def test_add_edge_default(self): """ Test adding an edge to the graph. """ correct = "{'A': {'B': 0.0}, 'B': {}}" g = Graph() g.add_node("A") g.add_node("B") g.add_edge("A", "B") self.assertEqual(str(g), correct)
def test_add_edge_with_value(self): """ Test adding an edge to the graph. """ correct = "{'A': {'B': 22.22}, 'B': {}}" g = Graph() g.add_node("A") g.add_node("B") g.add_edge("A", "B", 22.22) self.assertEqual(str(g), correct)
def test_add_edge_invalid_end(self): """ Test adding an edge where the end node does not exist. """ g = Graph() g.add_node("A") g.add_node("B") with self.assertRaises(ValueError) as context: g.add_edge("A", "C") self.assertIn("end", str(context.exception))
def test_add_edge_for_directed_graph(self): g = Graph(True) g.add_edge((1,2,3)) self.assertIn(1, g.table, 'should have stored a key for tail vertex') self.assertIn(2, g.table[1], 'should have stored the edge') self.assertEqual(g.table[1][2], 3, 'should have stored the edge value') self.assertIn(2, g.table, 'should not have stored the node') self.assertNotIn(1, g.table[2], 'should not have stored the reverse edge')
def test_remove_edge_in_directed_graph(self): g = Graph(True) g.add_edge((1, 2, 10)) g.add_edge((2, 3, 11)) g.add_edge((3, 1, 12)) g.remove_edge((2, 3)) self.assertEqual(g.table[1][2], 10, 'should have kept the edge') self.assertEqual(g.table[3][1], 12, 'should have kept the edge') self.assertEqual(g.table[2], {}, 'should have removed the edge')
def constructor(M, sigma, kind='log'): g = Graph() for i in range(len(M)): for j in range(len(M[i])): for p in range(len(M)): for q in range(len(M[i])): if p != i or q != j: g.add_edge(get_name(i, j), get_name(p, q), weight(M, [i, j], [p, q], kind, sigma)) g.normalize() return g
def test_get_vertices_for_undirected_graph(self): g = Graph(False) g.add_edge((1,2)) g.add_edge((2,3)) g.add_edge((3,1)) actual = g.get_edges() expected = [(1,2,True), (1,3,True), (2,3,True)] self.assertEqual(actual, expected, 'should return only one way edges')
def union_graphs(graph1: Graph, graph2: Graph): multi_graph = Graph(multi_graph=True) for e in graph1.get_edges(): multi_graph.add_edge(e[0], e[1]) for e in graph2.get_edges(): multi_graph.add_edge(e[0], e[1]) return multi_graph
def test_add_edge_for_undirected_graph(self): g = Graph(False) g.add_edge((1,2,3)) self.assertIn(1, g.table, 'should have stored a key for tail vertex') self.assertIn(2, g.table[1], 'should have stored the edge') self.assertEqual(g.table[1][2], 3, 'should have stored the edge value') self.assertIn(2, g.table, 'should have stored a key for head vertex') self.assertIn(1, g.table[2], 'should have stored the reversed edge') self.assertEqual(g.table[2][1], 3, 'should have stored the edge value')
def test_remove_vertex(self): g = Graph(False) g.add_edge((1,2)) g.add_edge((2,3)) g.add_edge((3,1)) g.remove_vertex(3) self.assertTrue(g.table[1][2], 'should keep edges not involving 3') self.assertTrue(g.table[2][1], 'should keep edges not involving 3') self.assertNotIn(3, g.table, 'vertex 3 disappeared') self.assertNotIn(3, g.table[1], 'edge from 3 to 1 dissappeared')
def test_neighbours_in_directed_graph(self): g = Graph(True) g.add_edge((1,2)) g.add_edge((1,3)) expected = [2, 3] actual = g.neighbours(1) self.assertEqual(actual, expected, 'should find neighbours of 1') expected = [] actual = g.neighbours(2) self.assertEqual(actual, expected, '2 has no neighbours')
def test_remove_edge_in_undirected_graph(self): g = Graph(False) g.add_edge((1,2,10)) g.add_edge((2,3,11)) g.add_edge((3,1,12)) g.remove_edge((2,3)) self.assertEqual(g.table[1][2], 10, 'no removals') self.assertEqual(g.table[1][3], 12, 'no removals') self.assertEqual(g.table[2][1], 10, 'removed the edge from tail') self.assertEqual(g.table[3][1], 12, 'removed the edge from head')
def test_rename_vertex(self): g = Graph(True) g.add_edge((1,2)) g.add_edge((2,3)) g.add_edge((3,4)) g.add_edge((4,1)) g.rename_vertex(3,3.5) self.assertNotIn(3, g.table, 'removed vertex 3') self.assertNotIn(3, g.table[2], 'removed vertex (2,3)') self.assertIn(3.5, g.table, 'add vertex 3.5') self.assertIn(4, g.table[3.5], '3.5 tails to 4')
def test_incident_in_undirected_graph(self): g = Graph(directed = False) g.add_edge((2,1)) g.add_edge((3,1)) actual = g.incident(1) expected = [2, 3] self.assertEqual(actual, expected, '1 has two incident vertexes') incident = g.incident(1) neighbours = g.neighbours(1) self.assertEqual(incident, neighbours, 'should be the same for undirected graphs')
def test_clone(self): g1 = Graph(False) g1.add_edge((1,2,10)) g1.add_edge((2,3,20)) g1.add_edge((3,1,30)) g2 = g1.clone() g2.set_edge_value((1,2), 100) self.assertEqual(g1.get_edge_value((1,2)), 10, 'should not have modified the value of the edge in g1') g2.add_vertex((3,4,40)) self.assertFalse(g1.adjacent(3,4), 'g1 should not have vertex 4')
def test_rename_vertex_should_remove_self_edges(self): g = Graph(True) g.add_edge((1,2)) g.add_edge((2,3)) g.add_edge((3,4)) g.add_edge((4,1)) g.rename_vertex(2,1) self.assertTrue(g.table[1][3]) self.assertTrue(g.table[3][4]) self.assertTrue(g.table[4][1]) self.assertNotIn(2, g.table[1]) self.assertNotIn(2, g.table)
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_vertices_are_correctly_maintained_after_remove_vertex(self): g = Graph(directed=True) g.add_edge((1,2)) g.add_edge((2,3)) g.add_edge((3,1)) # table: {1: {2: True}, 2: {3: True}, 3: {1: True}} # incident: {1: set([3]), 2: set([1]), 3: set([2])} g.remove_vertex(1) self.assertEqual(g.table, {2: {3: True}, 3: {}}) self.assertEqual(g.incident_vertices, {2: set(), 3: set([2])}) g = Graph(directed=False) g.add_edge((1,2)) g.add_edge((2,3)) g.add_edge((3,1)) # table: {1: {2: True, 3: True}, 2: {1: True, 3: True}, 3: {1: True, 2: True}} # incident: {1: set([2, 3]), 2: set([1, 3]), 3: set([1, 2])} g.remove_vertex(1) self.assertEqual(g.table, {2: {3: True}, 3: {2: True}}) self.assertEqual(g.incident_vertices, {2: set([3]), 3: set([2])})
def test_adjacent_in_directed_graphs(self): g = Graph(True) g.add_edge((1,2)) self.assertTrue(g.adjacent(1,2), 'should find them adjacent') self.assertFalse(g.adjacent(2,1), 'the edge is pointing the other way')
def test_adjacent_in_undirected_graphs(self): g = Graph(False) g.add_edge((1,2)) self.assertTrue(g.adjacent(1,2), 'should find them adjacent') self.assertTrue(g.adjacent(2,1), 'un-directed graph')
def test_add_edge_does_not_add_self_edges(self): g = Graph(True) g.add_edge((1,2)) g.add_edge((1,1)) self.assertNotIn(1, g.table[1], 'should not have added a self edge')