def test_dijkstra_edge_attr_weights(self) -> None: WEIGHT = "weight_key" g = DiGraph( [ ("s", "t"), ("s", "y"), ("t", "y"), ("t", "x"), ("x", "z"), ("y", "t"), ("y", "x"), ("y", "z"), ("z", "s"), ("z", "x"), ] ) g.get_edge("s", "t")[WEIGHT] = 10 g.get_edge("s", "y")[WEIGHT] = 5 g.get_edge("t", "y")[WEIGHT] = 2 g.get_edge("t", "x")[WEIGHT] = 1 g.get_edge("x", "z")[WEIGHT] = 4 g.get_edge("y", "t")[WEIGHT] = 3 g.get_edge("y", "x")[WEIGHT] = 9 g.get_edge("y", "z")[WEIGHT] = 2 g.get_edge("z", "s")[WEIGHT] = 7 g.get_edge("z", "x")[WEIGHT] = 6 path_dict: VertexDict[ShortestPath[DiVertex]] = dijkstra(g, "s", weight=WEIGHT) assert len(path_dict) == 5, "Shortest path_dict dictionary should have length equal to |V|." assert path_dict["s"].length == 0, "Length of s path should be 0." assert path_dict["t"].length == 8, "Length of path s ~> t should be 8." assert path_dict["x"].length == 9, "Length of path s ~> x should be 9." assert path_dict["y"].length == 5, "Length of path s ~> y should be 5." assert path_dict["z"].length == 7, "Length of path s ~> z should be 7."
def test_edges_and_edge_count(self) -> None: g = DiGraph([(1, 2), (2, 1), (2, 3)]) assert set(g.edges()) == { g.get_edge(1, 2), g.get_edge(2, 1), g.get_edge(2, 3), }, "edges should be (1, 2), (2, 1), (2, 3)" assert g.edge_count == 3, "graph should have 3 edges"
def test_dijkstra_edge_weight_filter_function(self) -> None: COLOR = "color_key" g = DiGraph( [ ("s", "t", 10), ("s", "y", 5), ("t", "y", 2), ("t", "x", 1), ("x", "z", 4), ("y", "t", 3), ("y", "x", 9), ("y", "z", 2), ("z", "s", 7), ("z", "x", 6), ] ) g.get_edge("s", "t")[COLOR] = "RED" g.get_edge("s", "y")[COLOR] = "BLUE" g.get_edge("t", "y")[COLOR] = "RED" g.get_edge("t", "x")[COLOR] = "RED" g.get_edge("x", "z")[COLOR] = "RED" g.get_edge("y", "t")[COLOR] = "BLUE" g.get_edge("y", "x")[COLOR] = "RED" g.get_edge("y", "z")[COLOR] = "BLUE" g.get_edge("z", "s")[COLOR] = "BLUE" g.get_edge("z", "x")[COLOR] = "BLUE" # Exclude blue edges. def get_weight(v1: V, v2: V, reverse_graph: bool) -> Optional[float]: graph = v1._parent_graph if reverse_graph: edge = graph.get_edge(v2, v1) edge_str = f"({v2.label}, {v1.label})" else: edge = graph.get_edge(v1, v2) edge_str = f"({v1.label}, {v2.label})" if edge is None: raise ValueError(f"graph does not have edge {edge_str}") if graph.is_multigraph(): assert isinstance(edge, MultiEdgeBase) has_color = any(c.attr.get(COLOR, "no color") == "BLUE" for c in edge.connections()) if has_color: return None return min(c.weight for c in edge.connections()) if cast(Attributes, edge).attr.get(COLOR, "no color attribute") == "BLUE": return None return edge.weight path_dict: VertexDict[ShortestPath[DiVertex]] = dijkstra(g, "s", weight=get_weight) assert path_dict["s"].length == 0, "Length of s path should be 0." assert path_dict["t"].length == 10, "Length of path s ~> t should be 10." assert path_dict["x"].length == 11, "Length of path s ~> x should be 11." assert path_dict["y"].length == 12, "Length of path s ~> y should be 12." assert path_dict["z"].length == 15, "Length of path s ~> z should be 15."
def test_get_random_edge(self) -> None: g = DiGraph([(1, 2), (2, 1), (5, 6)]) cnt: Counter[DiEdge] = collections.Counter() for _ in range(1000): rand_edge = g.get_random_edge() if rand_edge is None: raise Exception("rand_edge returned None") cnt[rand_edge] += 1 assert cnt[g.get_edge( 1, 2)] > 270, r"~33% of random samples should be edge (1, 2)" assert cnt[g.get_edge( 2, 1)] > 270, r"~33% of random samples should be edge (2, 1)" assert cnt[g.get_edge( 5, 6)] > 270, r"~33% of random samples should be edge (5, 6)"
def test__init__from_graph(self) -> None: g = Graph([(2, 1, 5.0, {"color": "red"}), (4, 3)]) assert g.weight == 6.0, "graph should have weight 6.0" dg = DiGraph(g) assert dg.has_edge( 2, 1), "digraph should have edge (2, 1) copied from graph" assert (dg.get_edge(2, 1)["color"] == "red" ), "edge (2, 1) should have 'color' attribute set to red" assert dg.get_edge( 2, 1).weight == 5.0, "edge (2, 1) should have weight 5.0" assert dg.has_edge( 4, 3), "graph should have edge (4, 3) copied from graph" assert dg.edge_count == 2, "graph should have two edges" assert dg.weight == 6.0, "graph should have weight 6.0" assert dg.get_edge(2, 1) is not g.get_edge( # type: ignore 2, 1), "digraph should have deep copies of edges and vertices"
def test_add_edges_from(self) -> None: g = DiGraph() g.add_edges_from([ (1, 2, 4.5, { "color": "blue", "mass": 42 }), (4, 3, 9.5), (5, 6, { "color": "red", "mass": 99 }), (8, 7), (7, 8), ]) assert g.edge_count == 5, "digraph should have 5 edges" assert g.get_edge( 1, 2).weight == 4.5, "edge (1, 2) should have weight 4.5" assert g.get_edge( 1, 2 )["color"] == "blue", "edge (1, 2) should have 'color' set to 'blue'" assert g.get_edge( 1, 2)["mass"] == 42, "edge (1, 2) should have 'mass' set to 42" assert not g.get_edge(4, 3).has_attributes_dict( ), "edge (3, 4) should not have attributes dict" assert (g.get_edge(5, 6).weight == edge_module.DEFAULT_WEIGHT ), "edge should have default weight" assert g.get_edge(7, 8) != g.get_edge( 8, 7), "order of vertices should specify different edges"
def test_add_edge(self) -> None: g = DiGraph() edge = g.add_edge(2, 1, weight=4.5, color="blue", mass=42) assert isinstance(edge, DiEdge), "new edge should an DiEdge object" assert g.get_edge( 2, 1).weight == 4.5, "edge (2, 1) should have weight 4.5" assert edge[ "color"] == "blue", "edge should have 'color' attribute set to 'blue'" assert edge[ "mass"] == 42, "edge should have 'mass' attribute set to 42" edge_dup = g.add_edge(2, 1, weight=1.5, color="red", mass=57) assert ( edge is edge_dup ), "adding an edge with same vertices as existing edge should return existing edge" g.add_edge(3, 4) assert (g.get_edge(3, 4).weight == edge_module.DEFAULT_WEIGHT ), "edge should have default weight" assert not g.get_edge(3, 4).has_attributes_dict( ), "edge should not have attributes dictionary" assert not g.has_edge(1, 2), "digraph should not have edge (1, 2)"