예제 #1
0
def main():
    powerg = ig.Graph.Read_GML('data/power.gml')
    powerx = nx.Graph()
    powerx.add_nodes_from(powerg.vs.indices)
    powerx.add_edges_from([(x.source, x.target) for x in powerg.es])

    work_graph = nx.Graph(powerx)
    deg_dict = nx.degree(work_graph)
    iteration = 0
    k = 2
    while min(deg_dict.values()) < k:
        deg2_nodes = [n for n, d in deg_dict.items() if d > k - 1]
        work_graph = nx.Graph(work_graph.subgraph(deg2_nodes))
        deg_dict = nx.degree(work_graph)
        iteration += 1
        print("Interation {0}. length deg_dict = {1}".format(
            iteration, len(deg_dict)))

    nodes_to_remove = set()
    iteration = 0
    for nodes in nx.all_node_cuts(work_graph, 1):
        sys.stdout.write("{0}\r".format(iteration))
        iteration += 1
        nodes_to_remove = nodes_to_remove.union(nodes)

    sys.stdout.write("\n")
    nodes_to_keep = set(work_graph.nodes()) - nodes_to_remove
    work_graph = nx.Graph(work_graph.subgraph(list(nodes_to_keep)))
    components = list(nx.connected_components(work_graph))
    largest_component = max(components, key=lambda x: len(x))
    work_graph = nx.Graph(work_graph.subgraph(list(largest_component)))
    save_nx_as_gml(work_graph, "data/large_power_2_connected.gml")

    k = 3
    iteration = 0
    while min(deg_dict.values()) < k:
        deg3_nodes = [n for n, d in deg_dict.items() if d > k - 1]
        work_graph = nx.Graph(work_graph.subgraph(deg3_nodes))
        deg_dict = nx.degree(work_graph)
        iteration += 1
        print("Interation {0}. length deg_dict = {1}".format(
            iteration, len(deg_dict)))

    nodes_to_keep = set(work_graph.nodes()) - nodes_to_remove
    work_graph = nx.Graph(work_graph.subgraph(list(nodes_to_keep)))
    components = list(nx.connected_components(work_graph))
    largest_component = max(components, key=lambda x: len(x))
    work_graph = nx.Graph(work_graph.subgraph(list(largest_component)))

    iteration = 0
    nodes_to_remove = set()
    for nodes in nx.all_node_cuts(work_graph, 2):
        sys.stdout.write("{0}\r".format(iteration))
        iteration += 1
        nodes_to_remove = nodes_to_remove.union(nodes)

    if not nodes_to_remove:
        save_nx_as_gml(work_graph, "data/power_subset.gml")

    return
예제 #2
0
def test_articulation_points():
    Ggen = _generate_no_biconnected()
    for i in range(2):
        G = next(Ggen)
        articulation_points = list({a} for a in nx.articulation_points(G))
        for cut in nx.all_node_cuts(G):
            assert_true(cut in articulation_points)
예제 #3
0
def test_articulation_points():
    Ggen = _generate_no_biconnected()
    for i in range(1):  # change 1 to 3 or more for more realizations.
        G = next(Ggen)
        articulation_points = list({a} for a in nx.articulation_points(G))
        for cut in nx.all_node_cuts(G):
            assert_true(cut in articulation_points)
예제 #4
0
def test_cycle_graph():
    G = nx.cycle_graph(5)
    solution = [{0, 2}, {0, 3}, {1, 3}, {1, 4}, {2, 4}]
    cuts = list(nx.all_node_cuts(G))
    assert_true(len(solution) == len(cuts))
    for cut in cuts:
        assert_true(cut in solution)
예제 #5
0
def test_articulation_points():
    Ggen = _generate_no_biconnected()
    for i in range(2):
        G = next(Ggen)
        articulation_points = list({a} for a in nx.articulation_points(G))
        for cut in nx.all_node_cuts(G):
            assert_true(cut in articulation_points)
예제 #6
0
def test_articulation_points():
    Ggen = _generate_no_biconnected()
    for i in range(1):  # change 1 to 3 or more for more realizations.
        G = next(Ggen)
        articulation_points = list({a} for a in nx.articulation_points(G))
        for cut in nx.all_node_cuts(G):
            assert_true(cut in articulation_points)
예제 #7
0
def test_cycle_graph():
    G = nx.cycle_graph(5)
    solution = [{0, 2}, {0, 3}, {1, 3}, {1, 4}, {2, 4}]
    cuts = list(nx.all_node_cuts(G))
    assert_true(len(solution) == len(cuts))
    for cut in cuts:
        assert_true(cut in solution)
예제 #8
0
def test_complete_graph():
    G = nx.complete_graph(5)
    solution = [{0, 1, 2, 3}, {0, 1, 2, 4}, {0, 1, 3, 4}, {0, 2, 3, 4},
                {1, 2, 3, 4}]
    cuts = list(nx.all_node_cuts(G))
    assert len(solution) == len(cuts)
    for cut in cuts:
        assert cut in solution
예제 #9
0
def P(A, E, V, G):
    G_A = G.subgraph(A)
    cutsets = list(nx.all_node_cuts(G_A))
    cutvertices = []
    for i in cutsets:
        if (len(i) == 1):
            cutvertices.append(i.pop())
    return cutvertices
예제 #10
0
def _check_separating_sets(G):
    for Gc in nx.connected_component_subgraphs(G):
        if len(Gc) < 3:
            continue
        for cut in nx.all_node_cuts(Gc):
            assert_equal(nx.node_connectivity(Gc), len(cut))
            H = Gc.copy()
            H.remove_nodes_from(cut)
            assert_false(nx.is_connected(H))
예제 #11
0
def test_grid_2d_graph():
    # All minimum node cuts of a 2d grid
    # are the four pairs of nodes that are
    # neighbors of the four corner nodes.
    G = nx.grid_2d_graph(5, 5)
    solution = [{(0, 1), (1, 0)}, {(3, 0), (4, 1)}, {(3, 4), (4, 3)},
                {(0, 3), (1, 4)}]
    for cut in nx.all_node_cuts(G):
        assert cut in solution
예제 #12
0
def _check_separating_sets(G):
    for Gc in nx.connected_component_subgraphs(G):
        if len(Gc) < 3:
            continue
        for cut in nx.all_node_cuts(Gc):
            assert_equal(nx.node_connectivity(Gc), len(cut))
            H = Gc.copy()
            H.remove_nodes_from(cut)
            assert_false(nx.is_connected(H))
예제 #13
0
def test_alternative_flow_functions():
    graph_funcs = [graph_example_1, nx.davis_southern_women_graph]
    for graph_func in graph_funcs:
        G = graph_func()
        for flow_func in flow_funcs:
            for cut in nx.all_node_cuts(G, flow_func=flow_func):
                assert_equal(nx.node_connectivity(G), len(cut))
                H = G.copy()
                H.remove_nodes_from(cut)
                assert_false(nx.is_connected(H))
def test_alternative_flow_functions():
    graphs = [nx.grid_2d_graph(4, 4), nx.cycle_graph(5)]
    for G in graphs:
        node_conn = nx.node_connectivity(G)
        for flow_func in flow_funcs:
            all_cuts = nx.all_node_cuts(G, flow_func=flow_func)
            # Only test a limited number of cut sets to reduce test time.
            for cut in itertools.islice(all_cuts, MAX_CUTSETS_TO_TEST):
                assert_equal(node_conn, len(cut))
                assert_false(nx.is_connected(nx.restricted_view(G, cut, [])))
예제 #15
0
def test_alternative_flow_functions():
    graph_funcs = [graph_example_1, nx.davis_southern_women_graph]
    for graph_func in graph_funcs:
        G = graph_func()
        for flow_func in flow_funcs:
            for cut in nx.all_node_cuts(G, flow_func=flow_func):
                assert_equal(nx.node_connectivity(G), len(cut))
                H = G.copy()
                H.remove_nodes_from(cut)
                assert_false(nx.is_connected(H))
예제 #16
0
def test_alternative_flow_functions():
    graphs = [nx.grid_2d_graph(4, 4),
              nx.cycle_graph(5)]
    for G in graphs:
        node_conn = nx.node_connectivity(G)
        for flow_func in flow_funcs:
            all_cuts = nx.all_node_cuts(G, flow_func=flow_func)
            # Only test a limited number of cut sets to reduce test time.
            for cut in itertools.islice(all_cuts, MAX_CUTSETS_TO_TEST):
                assert_equal(node_conn, len(cut))
                assert_false(nx.is_connected(nx.restricted_view(G, cut, [])))
예제 #17
0
def test_alternative_flow_functions():
    graphs = [nx.grid_2d_graph(4, 4), nx.cycle_graph(5)]
    for G in graphs:
        node_conn = nx.node_connectivity(G)
        for flow_func in flow_funcs:
            all_cuts = nx.all_node_cuts(G, flow_func=flow_func)
            for cut in all_cuts:
                assert_equal(node_conn, len(cut))
                H = G.copy()
                H.remove_nodes_from(cut)
                assert_false(nx.is_connected(H))
예제 #18
0
def _check_separating_sets(G):
    for cc in nx.connected_components(G):
        if len(cc) < 3:
            continue
        Gc = G.subgraph(cc)
        node_conn = nx.node_connectivity(Gc)
        all_cuts = nx.all_node_cuts(Gc)
        # Only test a limited number of cut sets to reduce test time.
        for cut in itertools.islice(all_cuts, MAX_CUTSETS_TO_TEST):
            assert_equal(node_conn, len(cut))
            assert_false(nx.is_connected(nx.restricted_view(G, cut, [])))
def _check_separating_sets(G):
    for cc in nx.connected_components(G):
        if len(cc) < 3:
            continue
        Gc = G.subgraph(cc)
        node_conn = nx.node_connectivity(Gc)
        all_cuts = nx.all_node_cuts(Gc)
        # Only test a limited number of cut sets to reduce test time.
        for cut in itertools.islice(all_cuts, MAX_CUTSETS_TO_TEST):
            assert_equal(node_conn, len(cut))
            assert_false(nx.is_connected(nx.restricted_view(G, cut, [])))
예제 #20
0
    def cut_sets(self):
        """Return list of cut sets.  Each cut set is a set of nodes describing
        a sub-graph G'.  Removing all the edges of G' from the graph
        disconnects it.  This will fail if there are unconnected
        components."""

        # It may be better to return a list of sets of edges.

        if hasattr(self, '_cutsets'):
            return self._cutsets
        self._cutsets = list(nx.all_node_cuts(self.G))
        return self._cutsets
def find_case_1_two_connected_subgraphs(g, q, verbose=False):
    """Find subgraphs of g that has a single separating pair (ie, that is
    suitable for the first 2-connected case in section 3.2 of the DBCP
    paper. Each subgraph Gi must have |Vi| < |V|(q-1)/q. Make a
    generating function that returns valid subgraphs and nodes.

    """
    g = remove_degree_x_vertices(g, 1, verbose)

    all_nodes = g.nodes()
    size = len(all_nodes)
    q = float(q)
    max_subgraph_size = (q - 1.0) / q * size

    if any(nx.all_node_cuts(g, 1)):
        raise GraphNot2ConnectedException()

    min_size = float('inf')
    found_one = False
    for nodes in nx.all_node_cuts(g, 2):
        sub_graph_nodes = [n for n in all_nodes if n not in nodes]
        disconnected_graph = nx.Graph(g.subgraph(sub_graph_nodes))
        try:
            for component in nx.connected_components(disconnected_graph):
                if verbose:
                    print("Subcomponent has size {0}".format(len(component)))
                if len(component) >= max_subgraph_size:
                    print("{} is too big!".format(len(component)))
                    min_size = min(min_size, len(component))
                    raise SubgraphTooBigException()
        except SubgraphTooBigException:
            print("For nodes {0} found a subgraph > (q-1)/q*size = {1}".format(
                nodes, max_subgraph_size))
            continue
        found_one = True
        yield (nodes, disconnected_graph)
    if not found_one:
        print("Found no suitable components. Smallest one was {}".format(
            min_size))
    return
예제 #22
0
def _check_separating_sets(G):
    for Gc in nx.connected_component_subgraphs(G):
        if len(Gc) < 3:
            continue
        node_conn = nx.node_connectivity(Gc)
        all_cuts = nx.all_node_cuts(Gc)
        # Only test a limited number of cut sets to reduce
        # test time.
        for cut in itertools.islice(all_cuts, MAX_CUTSETS_TO_TEST):
            assert_equal(node_conn, len(cut))
            H = Gc.copy()
            H.remove_nodes_from(cut)
            assert_false(nx.is_connected(H))
def test_complete_graph():
    G = nx.complete_graph(5)
    solution = [
        set([0, 1, 2, 3]),
        set([0, 1, 2, 4]),
        set([0, 1, 3, 4]),
        set([0, 2, 3, 4]),
        set([1, 2, 3, 4]),
    ]
    cuts = list(nx.all_node_cuts(G))
    assert_true(len(solution) == len(cuts))
    for cut in cuts:
        assert_true(cut in solution)
def test_cycle_graph():
    G = nx.cycle_graph(5)
    solution = [
        set([0, 2]),
        set([0, 3]),
        set([1, 3]),
        set([1, 4]),
        set([2, 4])
    ]
    cuts = list(nx.all_node_cuts(G))
    assert_true(len(solution) == len(cuts))
    for cut in cuts:
        assert_true(cut in solution)
예제 #25
0
def test_grid_2d_graph():
    # All minimum node cuts of a 2d grid
    # are the four pairs of nodes that are
    # neighbors of the four corner nodes.
    G = nx.grid_2d_graph(5, 5)
    solution = [
        set([(0, 1), (1, 0)]),
        set([(3, 0), (4, 1)]),
        set([(3, 4), (4, 3)]),
        set([(0, 3), (1, 4)]),
    ]
    for cut in nx.all_node_cuts(G):
        assert_true(cut in solution)
예제 #26
0
def test_grid_2d_graph():
    # All minimum node cuts of a 2d grid
    # are the four pairs of nodes that are
    # neighbors of the four corner nodes.
    G = nx.grid_2d_graph(5, 5)
    solution = [
        set([(0, 1), (1, 0)]),
        set([(3, 0), (4, 1)]),
        set([(3, 4), (4, 3)]),
        set([(0, 3), (1, 4)]),
    ]
    for cut in nx.all_node_cuts(G):
        assert_true(cut in solution)
예제 #27
0
def test_complete_graph():
    G = nx.complete_graph(5)
    solution = [
        {0, 1, 2, 3},
        {0, 1, 2, 4},
        {0, 1, 3, 4},
        {0, 2, 3, 4},
        {1, 2, 3, 4},
    ]
    cuts = list(nx.all_node_cuts(G))
    assert_true(len(solution) == len(cuts))
    for cut in cuts:
        assert_true(cut in solution)
예제 #28
0
def test_non_repeated_cuts():
    # The algorithm was repeating the cut {0, 1} for the giant biconnected
    # component of the Karate club graph.
    K = nx.karate_club_graph()
    G = max(list(nx.biconnected_component_subgraphs(K)), key=len)
    solution = [{32, 33}, {2, 33}, {0, 3}, {0, 1}, {29, 33}]
    cuts = list(nx.all_node_cuts(G))
    if len(solution) != len(cuts):
        print(nx.info(G))
        print("Solution: {}".format(solution))
        print("Result: {}".format(cuts))
    assert_true(len(solution) == len(cuts))
    for cut in cuts:
        assert_true(cut in solution)
예제 #29
0
def test_non_repeated_cuts():
    # The algorithm was repeating the cut {0, 1} for the giant biconnected
    # component of the Karate club graph.
    K = nx.karate_club_graph()
    G = max(list(nx.biconnected_component_subgraphs(K)), key=len)
    solution = [{32, 33}, {2, 33}, {0, 3}, {0, 1}, {29, 33}]
    cuts = list(nx.all_node_cuts(G))
    if len(solution) != len(cuts):
        print(nx.info(G))
        print("Solution: {}".format(solution))
        print("Result: {}".format(cuts))
    assert_true(len(solution) == len(cuts))
    for cut in cuts:
        assert_true(cut in solution)
예제 #30
0
def test_non_repeated_cuts():
    # The algorithm was repeating the cut {0, 1} for the giant biconnected
    # component of the Karate club graph.
    K = nx.karate_club_graph()
    bcc = max(list(nx.biconnected_components(K)), key=len)
    G = K.subgraph(bcc)
    solution = [{32, 33}, {2, 33}, {0, 3}, {0, 1}, {29, 33}]
    cuts = list(nx.all_node_cuts(G))
    if len(solution) != len(cuts):
        print(nx.info(G))
        print(f"Solution: {solution}")
        print(f"Result: {cuts}")
    assert len(solution) == len(cuts)
    for cut in cuts:
        assert cut in solution
def find_two_connected_subgraphs(g, verbose=False):
    """Find the largest 2-connected subgraph of the graph passed in."""
    work_graph = remove_degree_x_vertices(g, 1, verbose)

    nodes_to_remove = set()
    iteration = 0
    for nodes in nx.all_node_cuts(work_graph, 1):
        if verbose:
            sys.stdout.write("{0}\r".format(iteration))
        iteration += 1
        nodes_to_remove = nodes_to_remove.union(nodes)

    if verbose:
        sys.stdout.write("\n")

    if nodes_to_remove:
        nodes_to_keep = set(work_graph.nodes()) - nodes_to_remove
        work_graph = nx.Graph(work_graph.subgraph(list(nodes_to_keep)))
        components = list(nx.connected_components(work_graph))
        for component in components:
            yield (nx.Graph(work_graph.subgraph(list(component))))
    return
예제 #32
0
def big_cut_reduction(Graph, MIS, big_cut_dict):
    cuts = nx.all_node_cuts(Graph, 1)
    for i in cuts:
        node = list(i)[0]
        break
    G = copy.deepcopy(Graph)
    G.remove_node(node)
    G_list = get_subgraph(G)
    neighbors = nx.all_neighbors(Graph, node)
    for G_sub in G_list:
        G_sub.add_node(node, weight=Graph.nodes[node]['weight'])
    for i in neighbors:
        for G_sub in G_list:
            if i in G_sub.nodes:
                G_sub.add_edge(node, i)
    flag = 0
    new_weight = Graph.nodes[node]['weight']
    for i in range(len(G_list)):
        G_sub = G_list[i]
        G_sub.nodes[node]['weight'] = new_weight
        S1, s1 = Cut(G_sub)
        if node in S1:
            S1.remove(node)
        G_sub.remove_node(node)
        S0, s0 = Cut(G_sub)
        if s0 >= s1:
            MIS += S0
            if node in big_cut_dict:
                MIS += big_cut_dict[node][0]
                _ = big_cut_dict.pop(node)
            if i + 1 < len(G_list):
                flag = 1
            break
        else:
            new_weight = s1 - s0
            for u in S0:
                if node not in big_cut_dict:
                    big_cut_dict[node] = {0: [], 1: []}
                big_cut_dict[node][0] += [u]
                if u in big_cut_dict:
                    if u in S1:
                        continue
                    else:
                        big_cut_dict[node][0] += big_cut_dict[u][1]
                        big_cut_dict[node][1] += big_cut_dict[u][0]
            for w in S1:
                if node not in big_cut_dict:
                    big_cut_dict[node] = {0: [], 1: []}
                big_cut_dict[node][1] += [w]
                if w in big_cut_dict:
                    if w in S0:
                        continue
                    else:
                        big_cut_dict[node][1] += big_cut_dict[w][1]
                        big_cut_dict[node][0] += big_cut_dict[w][0]
            for u in S0:
                if u in big_cut_dict:
                    _ = big_cut_dict.pop(u)
            for w in S1:
                if w in big_cut_dict:
                    _ = big_cut_dict.pop(w)
    if flag == 1:
        for j in range(i + 1, len(G_list)):
            G_new = G_list[j]
            G_new.remove_node(node)
            S, _ = Cut(G_new)
            MIS += S
    return 0
예제 #33
0
def test_disconnected_graph():
    G = nx.fast_gnp_random_graph(100, 0.01)
    cuts = nx.all_node_cuts(G)
    assert_raises(nx.NetworkXError, next, cuts)
예제 #34
0
def k_components(G, flow_func=None):
    r"""Returns the k-component structure of a graph G.

    A `k`-component is a maximal subgraph of a graph G that has, at least,
    node connectivity `k`: we need to remove at least `k` nodes to break it
    into more components. `k`-components have an inherent hierarchical
    structure because they are nested in terms of connectivity: a connected
    graph can contain several 2-components, each of which can contain
    one or more 3-components, and so forth.

    Parameters
    ----------
    G : NetworkX graph

    flow_func : function
        Function to perform the underlying flow computations. Default value
        :meth:`edmonds_karp`. This function performs better in sparse graphs with
        right tailed degree distributions. :meth:`shortest_augmenting_path` will
        perform better in denser graphs.

    Returns
    -------
    k_components : dict
        Dictionary with all connectivity levels `k` in the input Graph as keys
        and a list of sets of nodes that form a k-component of level `k` as
        values.

    Raises
    ------
    NetworkXNotImplemented:
        If the input graph is directed.

    Examples
    --------
    >>> # Petersen graph has 10 nodes and it is triconnected, thus all
    >>> # nodes are in a single component on all three connectivity levels
    >>> G = nx.petersen_graph()
    >>> k_components = nx.k_components(G)

    Notes
    -----
    Moody and White [1]_ (appendix A) provide an algorithm for identifying
    k-components in a graph, which is based on Kanevsky's algorithm [2]_
    for finding all minimum-size node cut-sets of a graph (implemented in
    :meth:`all_node_cuts` function):

        1. Compute node connectivity, k, of the input graph G.

        2. Identify all k-cutsets at the current level of connectivity using
           Kanevsky's algorithm.

        3. Generate new graph components based on the removal of
           these cutsets. Nodes in a cutset belong to both sides
           of the induced cut.

        4. If the graph is neither complete nor trivial, return to 1;
           else end.

    This implementation also uses some heuristics (see [3]_ for details)
    to speed up the computation.

    See also
    --------
    node_connectivity
    all_node_cuts
    biconnected_components : special case of this function when k=2
    k_edge_components : similar to this function, but uses edge-connectivity
        instead of node-connectivity

    References
    ----------
    .. [1]  Moody, J. and D. White (2003). Social cohesion and embeddedness:
            A hierarchical conception of social groups.
            American Sociological Review 68(1), 103--28.
            http://www2.asanet.org/journals/ASRFeb03MoodyWhite.pdf

    .. [2]  Kanevsky, A. (1993). Finding all minimum-size separating vertex
            sets in a graph. Networks 23(6), 533--541.
            http://onlinelibrary.wiley.com/doi/10.1002/net.3230230604/abstract

    .. [3]  Torrents, J. and F. Ferraro (2015). Structural Cohesion:
            Visualization and Heuristics for Fast Computation.
            http://arxiv.org/pdf/1503.04476v1

    """
    # Dictionary with connectivity level (k) as keys and a list of
    # sets of nodes that form a k-component as values. Note that
    # k-compoents can overlap (but only k - 1 nodes).
    k_components = defaultdict(list)
    # Define default flow function
    if flow_func is None:
        flow_func = default_flow_func
    # Bicomponents as a base to check for higher order k-components
    for component in nx.connected_components(G):
        # isolated nodes have connectivity 0
        comp = set(component)
        if len(comp) > 1:
            k_components[1].append(comp)
    bicomponents = list(nx.biconnected_component_subgraphs(G))
    for bicomponent in bicomponents:
        bicomp = set(bicomponent)
        # avoid considering dyads as bicomponents
        if len(bicomp) > 2:
            k_components[2].append(bicomp)
    for B in bicomponents:
        if len(B) <= 2:
            continue
        k = nx.node_connectivity(B, flow_func=flow_func)
        if k > 2:
            k_components[k].append(set(B.nodes()))
        # Perform cuts in a DFS like order.
        cuts = list(nx.all_node_cuts(B, k=k, flow_func=flow_func))
        stack = [(k, _generate_partition(B, cuts, k))]
        while stack:
            (parent_k, partition) = stack[-1]
            try:
                nodes = next(partition)
                C = B.subgraph(nodes)
                this_k = nx.node_connectivity(C, flow_func=flow_func)
                if this_k > parent_k and this_k > 2:
                    k_components[this_k].append(set(C.nodes()))
                cuts = list(nx.all_node_cuts(C, k=this_k, flow_func=flow_func))
                if cuts:
                    stack.append((this_k, _generate_partition(C, cuts,
                                                              this_k)))
            except StopIteration:
                stack.pop()

    # This is necessary because k-components may only be reported at their
    # maximum k level. But we want to return a dictionary in which keys are
    # connectivity levels and values list of sets of components, without
    # skipping any connectivity level. Also, it's possible that subsets of
    # an already detected k-component appear at a level k. Checking for this
    # in the while loop above penalizes the common case. Thus we also have to
    # _consolidate all connectivity levels in _reconstruct_k_components.
    return _reconstruct_k_components(k_components)
def compute_3_connected_k_dominating_set(G, D):

    graphCDS = G.subgraph(D)

    if nx.node_connectivity(graphCDS) < 2:
        print "Input is not 2-connected.Exiting"
        return D

    separators = list(nx.all_node_cuts(graphCDS))

    # print "separators"
    # print separators

    while separators and nx.node_connectivity(graphCDS) < 3:

        broken = False

        discD = list(set(D) - separators[0])

        # print "discD"
        # print discD

        temp_graph_D = G.subgraph(discD)

        genD = nx.connected_components(temp_graph_D)

        components = list(genD)
        # print "Components"
        # print components

        for v in components[0]:

            tempD = list(D)
            tempD.remove(v)

            for u in components[1]:

                tempD.remove(u)

                newG = G.copy()
                newG.remove_nodes_from(tempD)

                if nx.has_path(newG, v, u):
                    Hpath = nx.shortest_path(newG, v, u)

                    # print "Hpath is",
                    # print Hpath

                    broken = True
                    break

            if broken:
                break

        for node in Hpath:
            if node not in D:
                D.append(node)

        graphCDS = G.subgraph(D)
        separators = list(nx.all_node_cuts(graphCDS))

        # print "separators"
        # print separators

    return D
예제 #36
0
# In[4]:

qzo = [[0 if i == 0. else 1 for i in q[j]] for j in range(len(q))]

# In[20]:

A = nx.adjacency_matrix(Gvc)

# In[6]:

A

# In[27]:

t = list(nx.all_node_cuts(Gvc))

# In[22]:

t

# In[28]:

Gvc.remove_node(16)
Gvc.remove_node(25)
Gvc.remove_node(26)
Gvc.remove_node(27)

# In[29]:

nx.draw_networkx(Gvc)
예제 #37
0
#ap = nv.BasePlot(G, node_grouping='cluster', node_color = 'connectivity', node_size = 'cluster', node_label='connectivity')

color = nx.betweenness_centrality(G, weight='count').values()
nx.draw(G,
        cmap=plt.get_cmap('jet'),
        alpha=0.4,
        node_order='count',
        node_color=color,
        node_size=65,
        with_labels=True,
        font_size=8,
        radius=20)
#ap.draw()
#plt.show()
plt.savefig('network.png', dpi=300)

cutsets = list(nx.all_node_cuts(G))
len(cutsets)

# In[10]:

all(1 == len(cutset) for cutset in cutsets)

# In[11]:

color

# In[12]:

color.items()
예제 #38
0
def test_disconnected_graph():
    G = nx.fast_gnp_random_graph(100, 0.01, seed=42)
    cuts = nx.all_node_cuts(G)
    pytest.raises(nx.NetworkXError, next, cuts)
예제 #39
0
def k_components(G, flow_func=None):
    r"""Returns the k-component structure of a graph G.

    A `k`-component is a maximal subgraph of a graph G that has, at least,
    node connectivity `k`: we need to remove at least `k` nodes to break it
    into more components. `k`-components have an inherent hierarchical
    structure because they are nested in terms of connectivity: a connected
    graph can contain several 2-components, each of which can contain
    one or more 3-components, and so forth.

    Parameters
    ----------
    G : NetworkX graph

    flow_func : function
        Function to perform the underlying flow computations. Default value
        :meth:`edmonds_karp`. This function performs better in sparse graphs with
        right tailed degree distributions. :meth:`shortest_augmenting_path` will
        perform better in denser graphs.

    Returns
    -------
    k_components : dict
        Dictionary with all connectivity levels `k` in the input Graph as keys
        and a list of sets of nodes that form a k-component of level `k` as
        values.

    Raises
    ------
    NetworkXNotImplemented:
        If the input graph is directed.

    Examples
    --------
    >>> # Petersen graph has 10 nodes and it is triconnected, thus all
    >>> # nodes are in a single component on all three connectivity levels
    >>> G = nx.petersen_graph()
    >>> k_components = nx.k_components(G)

    Notes
    -----
    Moody and White [1]_ (appendix A) provide an algorithm for identifying
    k-components in a graph, which is based on Kanevsky's algorithm [2]_
    for finding all minimum-size node cut-sets of a graph (implemented in
    :meth:`all_node_cuts` function):

        1. Compute node connectivity, k, of the input graph G.

        2. Identify all k-cutsets at the current level of connectivity using
           Kanevsky's algorithm.

        3. Generate new graph components based on the removal of
           these cutsets. Nodes in a cutset belong to both sides
           of the induced cut.

        4. If the graph is neither complete nor trivial, return to 1;
           else end.

    This implementation also uses some heuristics (see [3]_ for details)
    to speed up the computation.

    See also
    --------
    node_connectivity
    all_node_cuts
    biconnected_components : special case of this function when k=2
    k_edge_components : similar to this function, but uses edge-connectivity
        instead of node-connectivity

    References
    ----------
    .. [1]  Moody, J. and D. White (2003). Social cohesion and embeddedness:
            A hierarchical conception of social groups.
            American Sociological Review 68(1), 103--28.
            http://www2.asanet.org/journals/ASRFeb03MoodyWhite.pdf

    .. [2]  Kanevsky, A. (1993). Finding all minimum-size separating vertex
            sets in a graph. Networks 23(6), 533--541.
            http://onlinelibrary.wiley.com/doi/10.1002/net.3230230604/abstract

    .. [3]  Torrents, J. and F. Ferraro (2015). Structural Cohesion:
            Visualization and Heuristics for Fast Computation.
            https://arxiv.org/pdf/1503.04476v1

    """
    # Dictionary with connectivity level (k) as keys and a list of
    # sets of nodes that form a k-component as values. Note that
    # k-compoents can overlap (but only k - 1 nodes).
    k_components = defaultdict(list)
    # Define default flow function
    if flow_func is None:
        flow_func = default_flow_func
    # Bicomponents as a base to check for higher order k-components
    for component in nx.connected_components(G):
        # isolated nodes have connectivity 0
        comp = set(component)
        if len(comp) > 1:
            k_components[1].append(comp)
    bicomponents = list(nx.biconnected_component_subgraphs(G))
    for bicomponent in bicomponents:
        bicomp = set(bicomponent)
        # avoid considering dyads as bicomponents
        if len(bicomp) > 2:
            k_components[2].append(bicomp)
    for B in bicomponents:
        if len(B) <= 2:
            continue
        k = nx.node_connectivity(B, flow_func=flow_func)
        if k > 2:
            k_components[k].append(set(B.nodes()))
        # Perform cuts in a DFS like order.
        cuts = list(nx.all_node_cuts(B, k=k, flow_func=flow_func))
        stack = [(k, _generate_partition(B, cuts, k))]
        while stack:
            (parent_k, partition) = stack[-1]
            try:
                nodes = next(partition)
                C = B.subgraph(nodes)
                this_k = nx.node_connectivity(C, flow_func=flow_func)
                if this_k > parent_k and this_k > 2:
                    k_components[this_k].append(set(C.nodes()))
                cuts = list(nx.all_node_cuts(C, k=this_k, flow_func=flow_func))
                if cuts:
                    stack.append((this_k, _generate_partition(C, cuts, this_k)))
            except StopIteration:
                stack.pop()

    # This is necessary because k-components may only be reported at their
    # maximum k level. But we want to return a dictionary in which keys are
    # connectivity levels and values list of sets of components, without
    # skipping any connectivity level. Also, it's possible that subsets of
    # an already detected k-component appear at a level k. Checking for this
    # in the while loop above penalizes the common case. Thus we also have to
    # _consolidate all connectivity levels in _reconstruct_k_components.
    return _reconstruct_k_components(k_components)
예제 #40
0
def reduction_rule_6(graph, oct_set):
    """
    node cuts of size 2 can be handled.
    """

    # print("Entered RR6")
    # find cut of size 2: {u, v}
    # find vertex sets C1, ..., Cn of connected component in G-{u,v}
    # If Ci is bipartite:
    #   If Ci + {u, v} is bipartite, handle
    #   If Ci + {u} or Ci + {v} is bipartite, handle

    # Loop until no cuts of size 2 remain
    changed = False
    updated = True
    while (updated):
        updated = False

        # If the graph isn't 2-connected or if it's a clique on three vertices,
        # return the graph
        if graph.order() == 0 or \
           nx.node_connectivity(graph) != 2 or \
           graph.order() == 3:
            return changed, graph, oct_set

        # Else find a cut vertex and proceed
        node_u, node_v = list(nx.all_node_cuts(graph, k=2))[0]

        node_cuts = sort_collection_of_sets(nx.all_node_cuts(graph, k=2))
        while node_cuts and not updated:
            node_u, node_v = node_cuts.pop()

            remaining_nodes = set(graph.nodes())
            remaining_nodes.remove(node_u)
            remaining_nodes.remove(node_v)

            component_views = sort_collection_of_sets(
                nx.connected_components(graph.subgraph(remaining_nodes)))

            while component_views and not updated:
                # Find the nodes in a component of G - {u, v}
                component_nodes = set(component_views.pop())

                # The original component needs to be bipartite
                if nx.is_bipartite(graph.subgraph(component_nodes)):

                    # Case 1: Component + u + v is bipartite
                    component_nodes.add(node_u)
                    component_nodes.add(node_v)
                    if nx.is_bipartite(graph.subgraph(component_nodes)):
                        if len(component_nodes) > 3:
                            changed = True
                            updated = True
                            # Replace the component with one of equal parity.
                            # Check this by checking a 2-coloring of the
                            # component: If the neighborhood of {u, v} is one
                            # color then replace with a single new vertex.
                            # Otherwise replace with an edge.
                            # # print("component nodes before coloring:", component_nodes)
                            subgraph = graph.subgraph(component_nodes)
                            # # print("Subgraph: Nodes {} Edges {}".format(subgraph.nodes(), subgraph.edges()))
                            # # print("Connected?", nx.is_connected(graph.subgraph(component_nodes)))
                            coloring = nx.algorithms.bipartite.color(
                                graph.subgraph(component_nodes))

                            component_nodes.remove(node_u)
                            component_nodes.remove(node_v)
                            # # print("Coloring:",coloring)
                            # # print("v: {} u: {}".format(node_v, node_u))
                            if coloring[node_u] == coloring[node_v]:
                                new_midpoint = component_nodes.pop()
                                og_name_lookup = nx.get_node_attributes(
                                    graph, 'og_name')
                                og_name = og_name_lookup[new_midpoint]
                                graph.remove_node(new_midpoint)
                                graph.add_node(new_midpoint, og_name=og_name)
                                graph.add_edge(node_u, new_midpoint)
                                graph.add_edge(node_v, new_midpoint)
                            else:
                                graph.add_edge(node_u, node_v)

                            # In both cases, remove the component
                            # Update the preprocessing statistics
                            graph.graph['vertices_removed'] +=\
                                len(component_nodes)
                            graph.remove_nodes_from(component_nodes)
                        continue

                    # Case 2: Component + u is bipartite
                    component_nodes.remove(node_v)
                    if nx.is_bipartite(graph.subgraph(component_nodes)):
                        changed = True
                        updated = True

                        # Add v to OCT set
                        og_name_lookup = nx.get_node_attributes(
                            graph, 'og_name')
                        oct_set.add(og_name_lookup[node_v])
                        graph.remove_node(node_v)

                        # Remove this component
                        component_nodes.remove(node_u)
                        graph.remove_nodes_from(component_nodes)

                        # Update preprocessing statistics
                        graph.graph['oct'] += 1
                        graph.graph['vertices_removed'] += len(component_nodes)
                        continue

                    # Case 3: Component + v is bipartite
                    component_nodes.remove(node_u)
                    component_nodes.add(node_v)
                    if nx.is_bipartite(graph.subgraph(component_nodes)):
                        changed = True
                        updated = True

                        # Add u to OCT set
                        og_name_lookup = nx.get_node_attributes(
                            graph, 'og_name')
                        oct_set.add(og_name_lookup[node_u])
                        graph.remove_node(node_u)

                        # Remove component
                        component_nodes.remove(node_v)
                        graph.remove_nodes_from(component_nodes)

                        # Update preprocessing statistics
                        graph.graph['oct'] += 1
                        graph.graph['vertices_removed'] += len(component_nodes)
                        continue

    # print("Exited RR6")
    return changed, graph, oct_set
예제 #41
0
def reduction_rule_4(graph, oct_set):
    """
    Cut-vertices and their resulting components are examined.
    Note: OCT set may be updated.
    """

    # print("Entered RR4")

    # May need to remove multiple cut vertices
    changed = False
    updated = True
    while (updated):
        updated = False

        # Return if no cut vertex
        if graph.order() == 0 or nx.node_connectivity(graph) != 1:
            return changed, graph, oct_set

        # Else find a cut vertex and proceed
        # nx.all_node_cuts returns a "list" of "sets"
        # We know the sets are of size 1
        # So pull out the first set and store its only item in node_v
        node_cuts = sort_collection_of_sets(nx.all_node_cuts(graph, k=1))
        while node_cuts and not updated:
            # Pull off the next cut vertex
            node_v = node_cuts.pop().pop()

            # Compute remaining nodes
            remaining_nodes = set(graph.nodes())
            remaining_nodes.remove(node_v)

            # Range over the resulting components
            components = sort_collection_of_sets(
                nx.connected_components(graph.subgraph(remaining_nodes)))

            while components and not updated:
                component_nodes = set(components.pop())

                # Original component needs to be bipartite
                if nx.is_bipartite(graph.subgraph(component_nodes)):
                    changed = True
                    updated = True

                    # Case 1: Component + v is bipartite
                    component_nodes.add(node_v)
                    if nx.is_bipartite(graph.subgraph(component_nodes)):
                        component_nodes.remove(node_v)

                        # Update the preprocessing statistics
                        graph.graph['vertices_removed'] += len(component_nodes)
                        graph.remove_nodes_from(component_nodes)

                    # Case 2: Only component is bipartite
                    else:
                        # Update the preprocessing statistics
                        graph.graph['oct'] += 1
                        og_name_lookup = nx.get_node_attributes(
                            graph, 'og_name')
                        oct_set.add(og_name_lookup[node_v])
                        graph.remove_node(node_v)

    # print("Exited RR4")
    return changed, graph, oct_set
예제 #42
0
def test_disconnected_graph():
    G = nx.fast_gnp_random_graph(100, 0.01)
    cuts = nx.all_node_cuts(G)
    assert_raises(nx.NetworkXError, next, cuts)