def main(): g = Graph(6) print(g) g.add_edge(0, 5) g.add_edge(2, 4) g.add_edge(2, 3) g.add_edge(1, 2) g.add_edge(0, 1) g.add_edge(3, 4) g.add_edge(3, 5) g.add_edge(0, 2) print(g) s = 0 dfs = DepthFirstPaths(g, s) print(dfs) for v in range(g.get_V()): if dfs.has_path_to(v): print(f'{s} to {v}') for x in reversed(dfs.path_to(v)): if x == s: print(x, end="") else: print(f' - {x}', end="") print() else: print(f'{s} to {v}: not connected\n')
def test_initialization(self): graph = Graph(directed=True) assert graph.directed assert not graph.weighted assert graph.adj == {} assert len(graph) == 0 assert len(graph.nodes) == 0 assert len(graph.edges) == 0
def test_cyclic_graph_large(): graph = Graph() nodes = [["a", "b"], ["b", "c"], ["c", "d"], ["d", "e"], ["d", "a"], ["a", "d"], ["e", "z"], ["z", "a"]] graph.make_unweighted_from_list(nodes) expected_path = ["a", "d", "e", "z"] actual_path = graph.breadth_first_search(start=Node("a"), target=Node("z")) assert actual_path == expected_path
def test_straight_line_graph(): # a straight line graph is one that has only one path at each node graph = Graph() nodes = [["a","b",1],["b","c",1]] graph.make_weighted_from_list(nodes) expected_path = ["a","b","c"] actual_path = graph.dijkstras_with_target(Node("a"),Node("c")) assert actual_path == expected_path
def component(graph: Graph[T], node: T) -> Graph[T]: """Returns the connected component that contains the given vertex, as a new Graph object. A vertex with no incident edges is itself a component. A graph that is itself connected has exactly one component, consisting of the whole graph. """ res: Graph = Graph() _component(graph, node, res, visited=set()) return res
def __init__(self): """ Initializes an empty dictionary to contain Edge instances. Keys will be Edge labels as strings. Key values will be Edge instances. """ self.edges = {} self.graph = Graph()
def test_add_node(): graph = Graph() graph.add_node(Node(1)) assert len(graph.nodes) == 1 graph.add_node(Node(2)) assert len(graph.nodes) == 2 graph.add_node(Node(2)) assert len(graph.nodes) == 2
def test_add_node(): graph = Graph() expected = 'spam' # a vertex's value that comes back actual = graph.add_node('spam').value assert actual == expected
def test_size_empty(): graph = Graph() expected = 0 actual = graph.size() assert actual == expected
def test_add_edge(self): graph = Graph(directed=True, weighted=False) graph.add_node(1) graph.add_edge(1, 2) assert len(graph) == 2 assert len(graph.nodes) == 2 assert len(graph.edges) == 1 assert graph.contains_edge((1, 2)) assert graph.adj == {1: {2}, 2: set()}
def graph(): g = Graph(5) g.add_edge(0, 1) g.add_edge(0, 2) g.add_edge(0, 3) g.add_edge(1, 2) g.add_edge(4, 4) return g
def test_add_node(self): graph = Graph(directed=True) graph.add_node(1) graph.add_node(2) assert graph.contains_node(1) assert graph.contains_node(2) assert len(graph) == 2 assert len(graph.nodes) == 2 assert graph.adj == {1: set(), 2: set()}
def test_unweighted_directed(): graph = Graph() nodes = [["a","b"],["b","c"],["a","c"]] graph.make_unweighted_from_list(nodes) test_graph = { Node("a"):[Edge("a","b"),Edge("a","c")], Node("b"):[Edge("b","c")], Node("c"):[] } assert compare_graphs(test_graph, graph.graph) == True
def test_unweighted_list_of_int(): graph = Graph() nodes = [[1, 2], [2, 3], [3, 5], [5, 1], [2,5]] graph.make_unweighted_from_list(nodes) test_graph = { Node(1):[Edge(1,2)], Node(2):[Edge(2,3), Edge(2,5)], Node(3):[Edge(3,5)], Node(5):[Edge(5,1)]} assert compare_graphs(test_graph, graph.graph) == True
def test_weighted_list_of_int(): graph = Graph() nodes = [[1, 2, 99], [2, 3, 26], [3, 5, 130], [5, 1, 2], [2, 5, 0]] graph.make_unweighted_from_list(nodes) test_graph = { Node(1):[Edge(1,2,99)], Node(2):[Edge(2,3,26), Edge(2,5,0)], Node(3):[Edge(3,5,130)], Node(5):[Edge(5,1,2)]} assert compare_graphs(test_graph, graph.graph) == True
def test_does_contain_cycle(self): graph = Graph(is_directed=True) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_edge('A', 'B') graph.add_edge('B', 'C') graph.add_edge('C', 'A') self.assertTrue(graph.contains_cycle())
def test_add_edge_interloper_end(): graph = Graph() end = Vertex('end') start = graph.add_node('start') with pytest.raises(KeyError): graph.add_edge(start, end)
def test_weighted_undirected(): graph = Graph() nodes = [["a","b",1],["b","c",2],["a","c",3]] graph.make_weighted_from_list(nodes, directed=False) test_graph = { Node("a"):[Edge("a", "b",1), Edge("a","c",3)], Node("b"):[Edge("b","a",1), Edge("b","c",2)], Node("c"):[Edge("c","b",2), Edge("c","a",3)] } assert compare_graphs(test_graph, graph.graph) == True
def test_unweighted_edges_set(): test_graph = { Node("a"):[Edge("a","b"),Edge("a","c")], Node("b"):[Edge("b","c")], Node("c"):[] } graph = Graph() nodes = [["a","b"],["b","c"],["a","c"]] graph.make_unweighted_from_list(nodes) for node in graph.graph: assert graph.graph[node] == test_graph[node.name]
def test_does_not_contain_cycle_dag(self): """Test that a DAG does not contain a cycle.""" graph = Graph(is_directed=True) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_edge('A', 'B') graph.add_edge('B', 'C') graph.add_edge('A', 'C') self.assertFalse(graph.contains_cycle())
def test_size(): graph = Graph() graph.add_node('spam') expected = 1 actual = graph.size() assert actual == expected
def courseOrder(numCourses, prerequisites): """Return a course schedule according to the prerequisites provided.""" graph = Graph(is_directed=True) for i in range(numCourses): graph.add_vertex(i) for elm in prerequisites: graph.add_edge(elm[1], elm[0]) return graph.topological_sort()
def test_size(): g = Graph() vertex_apple = g.add('apple') vertex_banana = g.add('banana') vertex_cake = g.add('cake') expected = g.size() assert expected == 3 vertex_banana = g.add('dog') vertex_cake = g.add('egg') expected = g.size() assert expected == 5
def test_remove_edge(self): graph = Graph(directed=False, weighted=False) graph.add_multiple_edges(((1, 2), (2, 3), (3, 4))) assert len(graph) == 4 assert len(graph.edges) == 3 assert graph.adj == {1: {2}, 2: {1, 3}, 3: {2, 4}, 4: {3}} graph.remove_edge((1, 2)) assert len(graph) == 4 assert len(graph.edges) == 2 assert graph.adj == {1: set(), 2: {3}, 3: {2, 4}, 4: {3}}
def test_not_bipartite(self): """Test that a cycle on 3 vertices is NOT bipartite.""" graph = Graph(is_directed=False) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_edge('A', 'B') graph.add_edge('A', 'C') graph.add_edge('B', 'C') self.assertFalse(graph.is_bipartite())
def test_contains_cycle_undirected(self): graph = Graph(is_directed=False) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_edge('A','B') graph.add_edge('B','C') graph.add_edge('C','A') # This would be true if graph were directed self.assertTrue(graph.contains_cycle())
def test_find_path_dfs(self): graph = Graph(is_directed=True) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_edge('A', 'B') graph.add_edge('B', 'C') graph.add_edge('C', 'A') path = graph.find_path_dfs_iter('A', 'C') self.assertEqual(path, ['A', 'B', 'C'])
def test_does_not_contain_cycle_tree(self): """Test that a tree on 4 vertices does not contain a cycle.""" graph = Graph(is_directed=True) vertex_a = graph.add_vertex('A') vertex_b = graph.add_vertex('B') vertex_c = graph.add_vertex('C') vertex_d = graph.add_vertex('D') graph.add_edge('A', 'B') graph.add_edge('A', 'C') graph.add_edge('A', 'D') self.assertFalse(graph.contains_cycle())
def test_is_bipartite_tree(self): """Test that a tree on 4 vertices is bipartite.""" graph = Graph(is_directed=False) vertex_a = graph.add_vertex('A') vertex_b = graph.add_vertex('B') vertex_c = graph.add_vertex('C') vertex_d = graph.add_vertex('D') graph.add_edge('A', 'B') graph.add_edge('A', 'C') graph.add_edge('A', 'D') self.assertTrue(graph.is_bipartite())
def test_weighted_modify_weight(): graph = Graph() nodes = [["a","b",1],["b","c",2],["a","c",3]] graph.make_weighted_from_list(nodes) graph.modify_weight(["a","b",1], 78) test_graph = { Node("a"):[Edge("a", "b",78), Edge("a","c",3)], Node("b"):[Edge("b","c",2)], Node("c"):[] } assert compare_graphs(test_graph, graph.graph) == True