Python networkx.strongly_connected_components() Examples

The following are 30 code examples of networkx.strongly_connected_components(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module networkx , or try the search function .
Example #1
Source File: test_minors.py    From Carnets with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def test_condensation_as_quotient(self):
        """This tests that the condensation of a graph can be viewed as the
        quotient graph under the "in the same connected component" equivalence
        relation.

        """
        # This example graph comes from the file `test_strongly_connected.py`.
        G = nx.DiGraph()
        G.add_edges_from([(1, 2), (2, 3), (2, 11), (2, 12), (3, 4), (4, 3),
                          (4, 5), (5, 6), (6, 5), (6, 7), (7, 8), (7, 9),
                          (7, 10), (8, 9), (9, 7), (10, 6), (11, 2), (11, 4),
                          (11, 6), (12, 6), (12, 11)])
        scc = list(nx.strongly_connected_components(G))
        C = nx.condensation(G, scc)
        component_of = C.graph['mapping']
        # Two nodes are equivalent if they are in the same connected component.

        def same_component(u, v):
            return component_of[u] == component_of[v]

        Q = nx.quotient_graph(G, same_component)
        assert_true(nx.is_isomorphic(C, Q)) 
Example #2
Source File: edge_kcomponents.py    From aws-kube-codesuite with Apache License 2.0 6 votes vote down vote up
def _high_degree_components(G, k):
    """Helper for filtering components that cant be k-edge-connected.

    Removes and generates each node with degree less than k.  Then generates
    remaining components where all nodes have degree at least k.
    """
    # Iteravely remove parts of the graph that are not k-edge-connected
    H = G.copy()
    singletons = set(_low_degree_nodes(H, k))
    while singletons:
        # Only search neighbors of removed nodes
        nbunch = set(it.chain.from_iterable(map(H.neighbors, singletons)))
        nbunch.difference_update(singletons)
        H.remove_nodes_from(singletons)
        for node in singletons:
            yield {node}
        singletons = set(_low_degree_nodes(H, k, nbunch))

    # Note: remaining connected components may not be k-edge-connected
    if G.is_directed():
        for cc in nx.strongly_connected_components(H):
            yield cc
    else:
        for cc in nx.connected_components(H):
            yield cc 
Example #3
Source File: test_minors.py    From aws-kube-codesuite with Apache License 2.0 6 votes vote down vote up
def test_condensation_as_quotient(self):
        """This tests that the condensation of a graph can be viewed as the
        quotient graph under the "in the same connected component" equivalence
        relation.

        """
        # This example graph comes from the file `test_strongly_connected.py`.
        G = nx.DiGraph()
        G.add_edges_from([(1, 2), (2, 3), (2, 11), (2, 12), (3, 4), (4, 3),
                          (4, 5), (5, 6), (6, 5), (6, 7), (7, 8), (7, 9),
                          (7, 10), (8, 9), (9, 7), (10, 6), (11, 2), (11, 4),
                          (11, 6), (12, 6), (12, 11)])
        scc = list(nx.strongly_connected_components(G))
        C = nx.condensation(G, scc)
        component_of = C.graph['mapping']
        # Two nodes are equivalent if they are in the same connected component.

        def same_component(u, v):
            return component_of[u] == component_of[v]

        Q = nx.quotient_graph(G, same_component)
        assert_true(nx.is_isomorphic(C, Q)) 
Example #4
Source File: test_strongly_connected.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 6 votes vote down vote up
def test_contract_scc1(self):
        G = nx.DiGraph()
        G.add_edges_from([
            (1, 2), (2, 3), (2, 11), (2, 12), (3, 4), (4, 3), (4, 5), (5, 6),
            (6, 5), (6, 7), (7, 8), (7, 9), (7, 10), (8, 9), (9, 7), (10, 6),
            (11, 2), (11, 4), (11, 6), (12, 6), (12, 11),
        ])
        scc = list(nx.strongly_connected_components(G))
        cG = nx.condensation(G, scc)
        # DAG
        assert_true(nx.is_directed_acyclic_graph(cG))
        # nodes
        assert_equal(sorted(cG.nodes()), [0, 1, 2, 3])
        # edges
        mapping={}
        for i, component in enumerate(scc):
            for n in component:
                mapping[n] = i
        edge = (mapping[2], mapping[3])
        assert_true(cG.has_edge(*edge))
        edge = (mapping[2], mapping[5])
        assert_true(cG.has_edge(*edge))
        edge = (mapping[3], mapping[5])
        assert_true(cG.has_edge(*edge)) 
Example #5
Source File: edge_kcomponents.py    From Carnets with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def _high_degree_components(G, k):
    """Helper for filtering components that can't be k-edge-connected.

    Removes and generates each node with degree less than k.  Then generates
    remaining components where all nodes have degree at least k.
    """
    # Iteravely remove parts of the graph that are not k-edge-connected
    H = G.copy()
    singletons = set(_low_degree_nodes(H, k))
    while singletons:
        # Only search neighbors of removed nodes
        nbunch = set(it.chain.from_iterable(map(H.neighbors, singletons)))
        nbunch.difference_update(singletons)
        H.remove_nodes_from(singletons)
        for node in singletons:
            yield {node}
        singletons = set(_low_degree_nodes(H, k, nbunch))

    # Note: remaining connected components may not be k-edge-connected
    if G.is_directed():
        for cc in nx.strongly_connected_components(H):
            yield cc
    else:
        for cc in nx.connected_components(H):
            yield cc 
Example #6
Source File: strongly_connected.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 6 votes vote down vote up
def number_strongly_connected_components(G):
    """Return number of strongly connected components in graph.

    Parameters
    ----------
    G : NetworkX graph
       A directed graph.

    Returns
    -------
    n : integer
       Number of strongly connected components

    See Also
    --------
    connected_components

    Notes
    -----
    For directed graphs only.
    """
    return len(list(strongly_connected_components(G))) 
Example #7
Source File: test_minors.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 6 votes vote down vote up
def test_condensation_as_quotient(self):
        """This tests that the condensation of a graph can be viewed as the
        quotient graph under the "in the same connected component" equivalence
        relation.

        """
        # This example graph comes from the file `test_strongly_connected.py`.
        G = nx.DiGraph()
        G.add_edges_from([(1, 2), (2, 3), (2, 11), (2, 12), (3, 4), (4, 3),
                          (4, 5), (5, 6), (6, 5), (6, 7), (7, 8), (7, 9),
                          (7, 10), (8, 9), (9, 7), (10, 6), (11, 2), (11, 4),
                          (11, 6), (12, 6), (12, 11)])
        scc = list(nx.strongly_connected_components(G))
        C = nx.condensation(G, scc)
        component_of = C.graph['mapping']
        # Two nodes are equivalent if they are in the same connected component.
        same_component = lambda u, v: component_of[u] == component_of[v]
        Q = nx.quotient_graph(G, same_component)
        assert_true(nx.is_isomorphic(C, Q)) 
Example #8
Source File: test_DAG.py    From pathpy with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_strong_connected_components(random_network):
    from pathpy.classes.network import network_to_networkx
    from networkx import strongly_connected_components
    from pathpy.algorithms.components import connected_components

    wrong_gcc = 0
    for i in range(200):
        hn = random_network(n=10, m=30, directed=True, seed=i)

        hn_nx = network_to_networkx(hn)
        size_largest_nx = len(max(strongly_connected_components(hn_nx), key=len))

        components = connected_components(hn)
        size_largest = max(len(c) for c in components)

        if size_largest_nx != size_largest:
            # print(f'seed {i} | nx: {size_largest_nx}, pp: {size_largest}')
            wrong_gcc += 1

    assert wrong_gcc < 1, 'wrong results {wrong_gcc/i:0.1%}' 
Example #9
Source File: deadlock_detector.py    From Ciw with MIT License 6 votes vote down vote up
def detect_deadlock(self):
        """
        Detects whether the system is in a deadlocked state,
        that is, is there a knot. Note that this code is taken
        and adapted from the NetworkX Developer Zone Ticket
        #663 knot.py (09/06/2015).
        """
        knots = []
        for c in nx.strongly_connected_components(self.statedigraph):
            subgraph = self.statedigraph.subgraph(c)
            nodes = set(subgraph.nodes())
            if len(nodes) == 1:
                n = nodes.pop()
                nodes.add(n)
                if set(self.statedigraph.successors(n)) == nodes:
                    knots.append(subgraph)
            else:
                for n in nodes:
                    successors = nx.descendants(self.statedigraph, n)
                    if successors <= nodes:
                        knots.append(subgraph)
                        break
        if len(knots) > 0:
            return True
        return False 
Example #10
Source File: loopfinder.py    From angr with BSD 2-Clause "Simplified" License 6 votes vote down vote up
def _parse_loops_from_graph(self, graph):
        """
        Return all Loop instances that can be extracted from a graph.

        :param graph:   The graph to analyze.

        :return:        A list of all the Loop instances that were found in the graph.
        """
        outtop = []
        outall = []
        for subg in ( networkx.induced_subgraph(graph, nodes).copy() for nodes in networkx.strongly_connected_components(graph)):
            if len(subg.nodes()) == 1:
                if len(list(subg.successors(list(subg.nodes())[0]))) == 0:
                    continue
            thisloop, allloops = self._parse_loop_graph(subg, graph)
            if thisloop is not None:
                outall += allloops
                outtop.append(thisloop)
        return outtop, outall 
Example #11
Source File: nx_edge_kcomponents.py    From ibeis with Apache License 2.0 6 votes vote down vote up
def _high_degree_components(G, k):
    """Helper for filtering components that cant be k-edge-connected.

    Removes and generates each node with degree less than k.  Then generates
    remaining components where all nodes have degree at least k.
    """
    # Iteravely remove parts of the graph that are not k-edge-connected
    H = G.copy()
    singletons = set(_low_degree_nodes(H, k))
    while singletons:
        # Only search neighbors of removed nodes
        nbunch = set(it.chain.from_iterable(map(H.neighbors, singletons)))
        nbunch.difference_update(singletons)
        H.remove_nodes_from(singletons)
        for node in singletons:
            yield {node}
        singletons = set(_low_degree_nodes(H, k, nbunch))

    # Note: remaining connected components may not be k-edge-connected
    if G.is_directed():
        for cc in nx.strongly_connected_components(H):
            yield cc
    else:
        for cc in nx.connected_components(H):
            yield cc 
Example #12
Source File: test_strongly_connected.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_tarjan(self):
        scc = nx.strongly_connected_components
        for G, C in self.gc:
            assert_equal({frozenset(g) for g in scc(G)}, C) 
Example #13
Source File: test_strongly_connected.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_connected_raise(self):
        G = nx.Graph()
        assert_raises(NetworkXNotImplemented, nx.strongly_connected_components, G)
        assert_raises(NetworkXNotImplemented, nx.kosaraju_strongly_connected_components, G)
        assert_raises(NetworkXNotImplemented, nx.strongly_connected_components_recursive, G)
        assert_raises(NetworkXNotImplemented, nx.is_strongly_connected, G)
        assert_raises(nx.NetworkXPointlessConcept, nx.is_strongly_connected, nx.DiGraph())
        assert_raises(NetworkXNotImplemented, nx.condensation, G)
        # deprecated
        assert_raises(NetworkXNotImplemented, nx.strongly_connected_component_subgraphs, G)

#    Commented out due to variability on Travis-CI hardware/operating systems
#    def test_linear_time(self):
#        # See Issue #2831
#        count = 100  # base case
#        dg = nx.DiGraph()
#        dg.add_nodes_from([0, 1])
#        for i in range(2, count):
#            dg.add_node(i)
#            dg.add_edge(i, 1)
#            dg.add_edge(0, i)
#        t = time.time()
#        ret = tuple(nx.strongly_connected_components(dg))
#        dt = time.time() - t
#
#        count = 200
#        dg = nx.DiGraph()
#        dg.add_nodes_from([0, 1])
#        for i in range(2, count):
#            dg.add_node(i)
#            dg.add_edge(i, 1)
#            dg.add_edge(0, i)
#        t = time.time()
#        ret = tuple(nx.strongly_connected_components(dg))
#        dt2 = time.time() - t
#        assert_less(dt2, dt * 2.3)  # should be 2 times longer for this graph 
Example #14
Source File: test_strongly_connected.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_null_graph(self):
        G = nx.DiGraph()
        assert_equal(list(nx.strongly_connected_components(G)), [])
        assert_equal(list(nx.kosaraju_strongly_connected_components(G)), [])
        assert_equal(list(nx.strongly_connected_components_recursive(G)), [])
        assert_equal(len(nx.condensation(G)), 0)
        assert_raises(nx.NetworkXPointlessConcept, nx.is_strongly_connected, nx.DiGraph()) 
Example #15
Source File: attracting.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def attracting_components(G):
    """Generates the attracting components in `G`.

    An attracting component in a directed graph `G` is a strongly connected
    component with the property that a random walker on the graph will never
    leave the component, once it enters the component.

    The nodes in attracting components can also be thought of as recurrent
    nodes.  If a random walker enters the attractor containing the node, then
    the node will be visited infinitely often.

    Parameters
    ----------
    G : DiGraph, MultiDiGraph
        The graph to be analyzed.

    Returns
    -------
    attractors : generator of sets
        A generator of sets of nodes, one for each attracting component of G.

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

    See Also
    --------
    number_attracting_components
    is_attracting_component

    """
    scc = list(nx.strongly_connected_components(G))
    cG = nx.condensation(G, scc)
    for n in cG:
        if cG.out_degree(n) == 0:
            yield scc[n] 
Example #16
Source File: test_strongly_connected.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_contract_scc_edge(self):
        G = nx.DiGraph()
        G.add_edge(1, 2)
        G.add_edge(2, 1)
        G.add_edge(2, 3)
        G.add_edge(3, 4)
        G.add_edge(4, 3)
        scc = list(nx.strongly_connected_components(G))
        cG = nx.condensation(G, scc)
        assert_equal(sorted(cG.nodes()), [0, 1])
        if 1 in scc[0]:
            edge = (0, 1)
        else:
            edge = (1, 0)
        assert_equal(list(cG.edges()), [edge]) 
Example #17
Source File: test_strongly_connected.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_contract_scc_isolate(self):
        # Bug found and fixed in [1687].
        G = nx.DiGraph()
        G.add_edge(1, 2)
        G.add_edge(2, 1)
        scc = list(nx.strongly_connected_components(G))
        cG = nx.condensation(G, scc)
        assert_equal(list(cG.nodes()), [0])
        assert_equal(list(cG.edges()), []) 
Example #18
Source File: hierarchy.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def flow_hierarchy(G, weight=None):
    """Returns the flow hierarchy of a directed network.

    Flow hierarchy is defined as the fraction of edges not participating
    in cycles in a directed graph [1]_.

    Parameters
    ----------
    G : DiGraph or MultiDiGraph
       A directed graph

    weight : key,optional (default=None)
       Attribute to use for node weights. If None the weight defaults to 1.

    Returns
    -------
    h : float
       Flow heirarchy value

    Notes
    -----
    The algorithm described in [1]_ computes the flow hierarchy through
    exponentiation of the adjacency matrix.  This function implements an
    alternative approach that finds strongly connected components.
    An edge is in a cycle if and only if it is in a strongly connected
    component, which can be found in $O(m)$ time using Tarjan's algorithm.

    References
    ----------
    .. [1] Luo, J.; Magee, C.L. (2011),
       Detecting evolving patterns of self-organizing networks by flow
       hierarchy measurement, Complexity, Volume 16 Issue 6 53-61.
       DOI: 10.1002/cplx.20368
       http://web.mit.edu/~cmagee/www/documents/28-DetectingEvolvingPatterns_FlowHierarchy.pdf
    """
    if not G.is_directed():
        raise nx.NetworkXError("G must be a digraph in flow_heirarchy")
    scc = nx.strongly_connected_components(G)
    return 1. - sum(G.subgraph(c).size(weight) for c in scc) / float(G.size(weight)) 
Example #19
Source File: cluster_test.py    From yass with Apache License 2.0 5 votes vote down vote up
def get_cc(self, maha, maha_thresh):
        row, column = np.where(maha<maha_thresh)
        G = nx.DiGraph()
        for i in range(maha.shape[0]):
            G.add_node(i)
        for i, j in zip(row,column):
            G.add_edge(i, j)
        cc = [list(units) for units in nx.strongly_connected_components(G)]
        return cc 
Example #20
Source File: test_edge_kcomponents.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
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) 
Example #21
Source File: strongly_connected.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def number_strongly_connected_components(G):
    """Return number of strongly connected components in graph.

    Parameters
    ----------
    G : NetworkX graph
       A directed graph.

    Returns
    -------
    n : integer
       Number of strongly connected components

    Raises
    ------
    NetworkXNotImplemented:
        If G is undirected.

    See Also
    --------
    strongly_connected_components
    number_connected_components
    number_weakly_connected_components

    Notes
    -----
    For directed graphs only.
    """
    return len(list(strongly_connected_components(G))) 
Example #22
Source File: strongly_connected.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def is_strongly_connected(G):
    """Test directed graph for strong connectivity.

    Parameters
    ----------
    G : NetworkX Graph
       A directed graph.

    Returns
    -------
    connected : bool
      True if the graph is strongly connected, False otherwise.

    Raises
    ------
    NetworkXNotImplemented:
        If G is undirected.

    See Also
    --------
    is_weakly_connected
    is_semiconnected
    is_connected
    is_biconnected
    strongly_connected_components

    Notes
    -----
    For directed graphs only.
    """
    if len(G) == 0:
        raise nx.NetworkXPointlessConcept(
            """Connectivity is undefined for the null graph.""")

    return len(list(strongly_connected_components(G))[0]) == len(G) 
Example #23
Source File: test_strongly_connected.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def test_tarjan(self):
        scc = nx.strongly_connected_components
        for G, C in self.gc:
            assert_equal({frozenset(g) for g in scc(G)}, C) 
Example #24
Source File: test_strongly_connected.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def test_contract_scc_isolate(self):
        # Bug found and fixed in [1687].
        G = nx.DiGraph()
        G.add_edge(1, 2)
        G.add_edge(2, 1)
        scc = list(nx.strongly_connected_components(G))
        cG = nx.condensation(G, scc)
        assert_equal(list(cG.nodes()), [0])
        assert_equal(list(cG.edges()), []) 
Example #25
Source File: test_strongly_connected.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def test_contract_scc_edge(self):
        G = nx.DiGraph()
        G.add_edge(1, 2)
        G.add_edge(2, 1)
        G.add_edge(2, 3)
        G.add_edge(3, 4)
        G.add_edge(4, 3)
        scc = list(nx.strongly_connected_components(G))
        cG = nx.condensation(G, scc)
        assert_equal(sorted(cG.nodes()), [0, 1])
        if 1 in scc[0]:
            edge = (0, 1)
        else:
            edge = (1, 0)
        assert_equal(list(cG.edges()), [edge]) 
Example #26
Source File: test_strongly_connected.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def test_connected_raise(self):
        G=nx.Graph()
        assert_raises(NetworkXNotImplemented, nx.strongly_connected_components, G)
        assert_raises(NetworkXNotImplemented, nx.kosaraju_strongly_connected_components, G)
        assert_raises(NetworkXNotImplemented, nx.strongly_connected_components_recursive, G)
        assert_raises(NetworkXNotImplemented, nx.strongly_connected_component_subgraphs, G)
        assert_raises(NetworkXNotImplemented, nx.is_strongly_connected, G)
        assert_raises(nx.NetworkXPointlessConcept, nx.is_strongly_connected, nx.DiGraph())
        assert_raises(NetworkXNotImplemented, nx.condensation, G) 
Example #27
Source File: attracting.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def attracting_components(G):
    """Generates a list of attracting components in `G`.

    An attracting component in a directed graph `G` is a strongly connected
    component with the property that a random walker on the graph will never
    leave the component, once it enters the component.

    The nodes in attracting components can also be thought of as recurrent
    nodes.  If a random walker enters the attractor containing the node, then
    the node will be visited infinitely often.

    Parameters
    ----------
    G : DiGraph, MultiDiGraph
        The graph to be analyzed.

    Returns
    -------
    attractors : generator of sets
        A generator of sets of nodes, one for each attracting component of G.

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

    See Also
    --------
    number_attracting_components
    is_attracting_component
    attracting_component_subgraphs

    """
    scc = list(nx.strongly_connected_components(G))
    cG = nx.condensation(G, scc)
    for n in cG:
        if cG.out_degree(n) == 0:
            yield scc[n] 
Example #28
Source File: cluster.py    From yass with Apache License 2.0 5 votes vote down vote up
def get_cc(self, maha, maha_thresh):
        row, column = np.where(maha<maha_thresh)
        G = nx.DiGraph()
        for i in range(maha.shape[0]):
            G.add_node(i)
        for i, j in zip(row,column):
            G.add_edge(i, j)
        cc = [list(units) for units in nx.strongly_connected_components(G)]
        return cc 
Example #29
Source File: ptp_split.py    From yass with Apache License 2.0 5 votes vote down vote up
def get_cc(maha, maha_thresh):
    row, column = np.where(maha<maha_thresh)
    G = nx.DiGraph()
    for i in range(maha.shape[0]):
        G.add_node(i)
    for i, j in zip(row,column):
        G.add_edge(i, j)
    cc = [list(units) for units in nx.strongly_connected_components(G)]
    return cc 
Example #30
Source File: test_strongly_connected.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 5 votes vote down vote up
def test_contract_scc_edge(self):
        G = nx.DiGraph()
        G.add_edge(1, 2)
        G.add_edge(2, 1)
        G.add_edge(2, 3)
        G.add_edge(3, 4)
        G.add_edge(4, 3)
        scc = list(nx.strongly_connected_components(G))
        cG = nx.condensation(G, scc)
        assert_equal(cG.nodes(), [0, 1])
        if 1 in scc[0]:
            edge = (0, 1)
        else:
            edge = (1, 0)
        assert_equal(list(cG.edges()), [edge])