def test_directed_aux_graph(): # Graph similar to the one in # http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0136264 a, b, c, d, e, f, g, h, i = "abcdefghi" dipaths = [ (a, d, b, f, c), (a, e, b), (a, e, b, c, g, b, a), (c, b), (f, g, f), (h, i), ] G = nx.DiGraph(it.chain(*[pairwise(path) for path in dipaths])) aux_graph = EdgeComponentAuxGraph.construct(G) components_1 = fset(aux_graph.k_edge_subgraphs(k=1)) target_1 = fset([{a, b, c, d, e, f, g}, {h}, {i}]) assert target_1 == components_1 # Check that the directed case for k=1 agrees with SCCs alt_1 = fset(nx.strongly_connected_components(G)) assert alt_1 == components_1 components_2 = fset(aux_graph.k_edge_subgraphs(k=2)) target_2 = fset([{i}, {e}, {d}, {b, c, f, g}, {h}, {a}]) assert target_2 == components_2 components_3 = fset(aux_graph.k_edge_subgraphs(k=3)) target_3 = fset([{a}, {b}, {c}, {d}, {e}, {f}, {g}, {h}, {i}]) assert target_3 == components_3
def test_undirected_aux_graph(): # Graph similar to the one in # http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0136264 a, b, c, d, e, f, g, h, i = 'abcdefghi' paths = [(a, d, b, f, c), (a, e, b), (a, e, b, c, g, b, a), (c, b), (f, g, f), (h, i)] G = nx.Graph(it.chain(*[pairwise(path) for path in paths])) aux_graph = EdgeComponentAuxGraph.construct(G) components_1 = fset(aux_graph.k_edge_subgraphs(k=1)) target_1 = fset([{a, b, c, d, e, f, g}, {h, i}]) assert_equal(target_1, components_1) # Check that the undirected case for k=1 agrees with CCs alt_1 = fset(nx.k_edge_subgraphs(G, k=1)) assert_equal(alt_1, components_1) components_2 = fset(aux_graph.k_edge_subgraphs(k=2)) target_2 = fset([{a, b, c, d, e, f, g}, {h}, {i}]) assert_equal(target_2, components_2) # Check that the undirected case for k=2 agrees with bridge components alt_2 = fset(nx.k_edge_subgraphs(G, k=2)) assert_equal(alt_2, components_2) components_3 = fset(aux_graph.k_edge_subgraphs(k=3)) target_3 = fset([{a}, {b, c, f, g}, {d}, {e}, {h}, {i}]) assert_equal(target_3, components_3) components_4 = fset(aux_graph.k_edge_subgraphs(k=4)) target_4 = fset([{a}, {b}, {c}, {d}, {e}, {f}, {g}, {h}, {i}]) assert_equal(target_4, components_4) _check_edge_connectivity(G)
def test_local_subgraph_difference(): paths = [ (11, 12, 13, 14, 11, 13, 14, 12), # first 4-clique (21, 22, 23, 24, 21, 23, 24, 22), # second 4-clique # paths connecting each node of the 4 cliques (11, 101, 21), (12, 102, 22), (13, 103, 23), (14, 104, 24), ] G = nx.Graph(it.chain(*[pairwise(path) for path in paths])) aux_graph = EdgeComponentAuxGraph.construct(G) # Each clique is returned separately in k-edge-subgraphs subgraph_ccs = fset(aux_graph.k_edge_subgraphs(3)) subgraph_target = fset([{101}, {102}, {103}, {104}, {21, 22, 23, 24}, {11, 12, 13, 14}]) assert subgraph_ccs == subgraph_target # But in k-edge-ccs they are returned together # because they are locally 3-edge-connected local_ccs = fset(aux_graph.k_edge_components(3)) local_target = fset([{101}, {102}, {103}, {104}, {11, 12, 13, 14, 21, 22, 23, 24}]) assert local_ccs == local_target
def test_directed_aux_graph(): # Graph similar to the one in # http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0136264 a, b, c, d, e, f, g, h, i = 'abcdefghi' dipaths = [ (a, d, b, f, c), (a, e, b), (a, e, b, c, g, b, a), (c, b), (f, g, f), (h, i) ] G = nx.DiGraph(it.chain(*[pairwise(path) for path in dipaths])) aux_graph = EdgeComponentAuxGraph.construct(G) components_1 = fset(aux_graph.k_edge_subgraphs(k=1)) target_1 = fset([{a, b, c, d, e, f, g}, {h}, {i}]) assert_equal(target_1, components_1) # Check that the directed case for k=1 agrees with SCCs alt_1 = fset(nx.strongly_connected_components(G)) assert_equal(alt_1, components_1) components_2 = fset(aux_graph.k_edge_subgraphs(k=2)) target_2 = fset([{i}, {e}, {d}, {b, c, f, g}, {h}, {a}]) assert_equal(target_2, components_2) components_3 = fset(aux_graph.k_edge_subgraphs(k=3)) target_3 = fset([{a}, {b}, {c}, {d}, {e}, {f}, {g}, {h}, {i}]) assert_equal(target_3, components_3)
def test_local_subgraph_difference(): paths = [ (11, 12, 13, 14, 11, 13, 14, 12), # first 4-clique (21, 22, 23, 24, 21, 23, 24, 22), # second 4-clique # paths connecting each node of the 4 cliques (11, 101, 21), (12, 102, 22), (13, 103, 23), (14, 104, 24), ] G = nx.Graph(it.chain(*[pairwise(path) for path in paths])) aux_graph = EdgeComponentAuxGraph.construct(G) # Each clique is returned separately in k-edge-subgraphs subgraph_ccs = fset(aux_graph.k_edge_subgraphs(3)) subgraph_target = fset([{101}, {102}, {103}, {104}, {21, 22, 23, 24}, {11, 12, 13, 14}]) assert_equal(subgraph_ccs, subgraph_target) # But in k-edge-ccs they are returned together # because they are locally 3-edge-connected local_ccs = fset(aux_graph.k_edge_components(3)) local_target = fset([{101}, {102}, {103}, {104}, {11, 12, 13, 14, 21, 22, 23, 24}]) assert_equal(local_ccs, local_target)
def test_directed_aux_graph(): # Graph similar to the one in # http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0136264 a, b, c, d, e, f, g, h, i = 'abcdefghi' dipaths = [ (a, d, b, f, c), (a, e, b), (a, e, b, c, g, b, a), (c, b), (f, g, f), (h, i) ] G = nx.DiGraph(it.chain(*[pairwise(path) for path in dipaths])) aux_graph = EdgeComponentAuxGraph.construct(G) components_1 = fset(aux_graph.k_edge_subgraphs(k=1)) target_1 = fset([set([a, b, c, d, e, f, g]), set([h]), set([i])]) assert_equal(target_1, components_1) # Check that the directed case for k=1 agrees with SCCs alt_1 = fset(nx.strongly_connected_components(G)) assert_equal(alt_1, components_1) components_2 = fset(aux_graph.k_edge_subgraphs(k=2)) target_2 = fset([set([i]), set([e]), set([d]), set([b, c, f, g]), set([h]), set([a])]) assert_equal(target_2, components_2) components_3 = fset(aux_graph.k_edge_subgraphs(k=3)) target_3 = fset([set([a]), set([b]), set([c]), set([d]), set([e]), set([f]), set([g]), set([h]), set([i])]) assert_equal(target_3, components_3)
def _check_edge_connectivity(G): """ Helper - generates all k-edge-components using the aux graph. Checks the both local and subgraph edge connectivity of each cc. Also checks that alternate methods of computing the k-edge-ccs generate the same result. """ # Construct the auxillary graph that can be used to make each k-cc or k-sub aux_graph = EdgeComponentAuxGraph.construct(G) # memoize the local connectivity in this graph memo = {} for k in it.count(1): # Test "local" k-edge-components and k-edge-subgraphs ccs_local = fset(aux_graph.k_edge_components(k)) ccs_subgraph = fset(aux_graph.k_edge_subgraphs(k)) # Check connectivity properties that should be garuenteed by the # algorithms. _assert_local_cc_edge_connectivity(G, ccs_local, k, memo) _assert_subgraph_edge_connectivity(G, ccs_subgraph, k) if k == 1 or k == 2 and not G.is_directed(): assert_equal( ccs_local, ccs_subgraph, 'Subgraphs and components should be the same ' 'when k == 1 or (k == 2 and not G.directed())') if G.is_directed(): # Test special case methods are the same as the aux graph if k == 1: alt_sccs = fset(nx.strongly_connected_components(G)) assert_equal(alt_sccs, ccs_local, 'k=1 failed alt') assert_equal(alt_sccs, ccs_subgraph, 'k=1 failed alt') else: # Test special case methods are the same as the aux graph if k == 1: alt_ccs = fset(nx.connected_components(G)) assert_equal(alt_ccs, ccs_local, 'k=1 failed alt') assert_equal(alt_ccs, ccs_subgraph, 'k=1 failed alt') elif k == 2: alt_bridge_ccs = fset(bridge_components(G)) assert_equal(alt_bridge_ccs, ccs_local, 'k=2 failed alt') assert_equal(alt_bridge_ccs, ccs_subgraph, 'k=2 failed alt') # if new methods for k == 3 or k == 4 are implemented add them here # Check the general subgraph method works by itself alt_subgraph_ccs = fset( [set(C.nodes()) for C in general_k_edge_subgraphs(G, k=k)]) assert_equal(alt_subgraph_ccs, ccs_subgraph, 'alt subgraph method failed') # Stop once k is larger than all special case methods # and we cannot break down ccs any further. if k > 2 and all(len(cc) == 1 for cc in ccs_local): break
def _check_edge_connectivity(G): """ Helper - generates all k-edge-components using the aux graph. Checks the both local and subgraph edge connectivity of each cc. Also checks that alternate methods of computing the k-edge-ccs generate the same result. """ # Construct the auxiliary graph that can be used to make each k-cc or k-sub aux_graph = EdgeComponentAuxGraph.construct(G) # memoize the local connectivity in this graph memo = {} for k in it.count(1): # Test "local" k-edge-components and k-edge-subgraphs ccs_local = fset(aux_graph.k_edge_components(k)) ccs_subgraph = fset(aux_graph.k_edge_subgraphs(k)) # Check connectivity properties that should be garuenteed by the # algorithms. _assert_local_cc_edge_connectivity(G, ccs_local, k, memo) _assert_subgraph_edge_connectivity(G, ccs_subgraph, k) if k == 1 or k == 2 and not G.is_directed(): assert_equal(ccs_local, ccs_subgraph, 'Subgraphs and components should be the same ' 'when k == 1 or (k == 2 and not G.directed())') if G.is_directed(): # Test special case methods are the same as the aux graph if k == 1: alt_sccs = fset(nx.strongly_connected_components(G)) assert_equal(alt_sccs, ccs_local, 'k=1 failed alt') assert_equal(alt_sccs, ccs_subgraph, 'k=1 failed alt') else: # Test special case methods are the same as the aux graph if k == 1: alt_ccs = fset(nx.connected_components(G)) assert_equal(alt_ccs, ccs_local, 'k=1 failed alt') assert_equal(alt_ccs, ccs_subgraph, 'k=1 failed alt') elif k == 2: alt_bridge_ccs = fset(bridge_components(G)) assert_equal(alt_bridge_ccs, ccs_local, 'k=2 failed alt') assert_equal(alt_bridge_ccs, ccs_subgraph, 'k=2 failed alt') # if new methods for k == 3 or k == 4 are implemented add them here # Check the general subgraph method works by itself alt_subgraph_ccs = fset([set(C.nodes()) for C in general_k_edge_subgraphs(G, k=k)]) assert_equal(alt_subgraph_ccs, ccs_subgraph, 'alt subgraph method failed') # Stop once k is larger than all special case methods # and we cannot break down ccs any further. if k > 2 and all(len(cc) == 1 for cc in ccs_local): break
def test_zero_k_exception(): G = nx.Graph() # functions that return generators error immediately pytest.raises(ValueError, nx.k_edge_components, G, k=0) pytest.raises(ValueError, nx.k_edge_subgraphs, G, k=0) # actual generators only error when you get the first item aux_graph = EdgeComponentAuxGraph.construct(G) pytest.raises(ValueError, list, aux_graph.k_edge_components(k=0)) pytest.raises(ValueError, list, aux_graph.k_edge_subgraphs(k=0)) pytest.raises(ValueError, list, general_k_edge_subgraphs(G, k=0))
def test_zero_k_exception(): G = nx.Graph() # functions that return generators error immediately assert_raises(ValueError, nx.k_edge_components, G, k=0) assert_raises(ValueError, nx.k_edge_subgraphs, G, k=0) # actual generators only error when you get the first item aux_graph = EdgeComponentAuxGraph.construct(G) assert_raises(ValueError, list, aux_graph.k_edge_components(k=0)) assert_raises(ValueError, list, aux_graph.k_edge_subgraphs(k=0)) assert_raises(ValueError, list, general_k_edge_subgraphs(G, k=0))