Example #1
0
def grid_2d_graph(m,n,periodic=False,create_using=None):
    """ Return the 2d grid graph of mxn nodes,
        each connected to its nearest neighbors.
        Optional argument periodic=True will connect
        boundary nodes via periodic boundary conditions.
    """
    G=empty_graph(0,create_using)
    row_name, rows = m
    col_name, columns = n
    G.name="grid_2d_graph(%s, %s)"%(row_name, col_name)
    G.add_nodes_from( (i,j) for i in rows for j in columns )
    G.add_edges_from( ((i,j),(pi,j)) for pi,i in pairwise(rows) for j in columns )
    G.add_edges_from( ((i,j),(i,pj)) for i in rows for pj,j in pairwise(columns) )
    if G.is_directed():
        G.add_edges_from( ((pi,j),(i,j)) for pi,i in pairwise(rows) for j in columns )
        G.add_edges_from( ((i,pj),(i,j)) for i in rows for pj,j in pairwise(columns) )
    if periodic:
        if len(columns)>2:
            f = columns[0]
            l = columns[-1]
            G.add_edges_from( ((i,f),(i,l)) for i in rows )
            if G.is_directed():
                G.add_edges_from( ((i,l),(i,f)) for i in rows )
        if len(rows)>2:
            f = rows[0]
            l = rows[-1]
            G.add_edges_from( ((f,j),(l,j)) for j in columns )
            if G.is_directed():
                G.add_edges_from( ((l,j),(f,j)) for j in columns )
        G.name="periodic_grid_2d_graph(%s,%s)"%(m,n)
    return G
Example #2
0
def validate_path(G, s, t, soln_len, path):
    assert_equal(path[0], s)
    assert_equal(path[-1], t)
    if not G.is_multigraph():
        computed = sum(G[u][v].get('weight', 1) for u, v in pairwise(path))
        assert_equal(soln_len, computed)
    else:
        computed = sum(min(e.get('weight', 1) for e in G[u][v].values())
                       for u, v in pairwise(path))
        assert_equal(soln_len, computed)
Example #3
0
def grid_2d_graph(m, n, periodic=False, create_using=None):
    """Returns the two-dimensional grid graph.

    The grid graph has each node connected to its four nearest neighbors.

    Parameters
    ----------
    m, n : int or iterable container of nodes
        If an integer, nodes are from `range(n)`.
        If a container, elements become the coordinate of the nodes.

    periodic : bool (default: False)
        If this is ``True`` the nodes on the grid boundaries are joined
        to the corresponding nodes on the opposite grid boundaries.

    create_using : NetworkX graph (default: Graph())
        If provided this graph is cleared of nodes and edges and filled
        with the new graph. Usually used to set the type of the graph.

    Returns
    -------
    NetworkX graph
        The (possibly periodic) grid graph of the specified dimensions.

    """
    G = empty_graph(0, create_using)
    row_name, rows = m
    col_name, cols = n
    G.add_nodes_from((i, j) for i in rows for j in cols)
    G.add_edges_from(((i, j), (pi, j))
                     for pi, i in pairwise(rows) for j in cols)
    G.add_edges_from(((i, j), (i, pj))
                     for i in rows for pj, j in pairwise(cols))
    if periodic is True:
        if len(rows) > 2:
            first = rows[0]
            last = rows[-1]
            G.add_edges_from(((first, j), (last, j)) for j in cols)
        if len(cols) > 2:
            first = cols[0]
            last = cols[-1]
            G.add_edges_from(((i, first), (i, last)) for i in rows)
    # both directions for directed
    if G.is_directed():
        G.add_edges_from((v, u) for u, v in G.edges())

    # set name
    G.name = "grid_2d_graph(%s, %s)" % (row_name, col_name)
    if periodic is True:
        G.name = "periodic_" + G.name
    return G
Example #4
0
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_hamiltonian__edge_path():
    from itertools import permutations

    G = nx.complete_graph(4)
    paths = hamiltonian_edge_path(G, 0)
    exact = [list(pairwise([0] + list(p))) for p in permutations([1, 2, 3], 3)]
    assert sorted(exact) == [p for p in sorted(paths)]
Example #6
0
 def getall_pair_shortest_path(self):
     """
       this function computes two shortest path for each pair and adds them in a dictionary where key is the pair of nodes. 
       self.all_pair_shortest_path is similiar to {(2,3):[[2,4,3],[2,5,6,3]]}
     """
     edges = self.net.edges()
     edges = set(edges)
     edges = list(edges)
     nodes = self.net.nodes
     nodes = set(nodes)
     nodes = list(nodes)
     pairs = set(itertools.product(nodes, nodes))
     graph = copy.copy(self.net)
     total_edges = graph.edges()
     for pair in pairs:
         src, dst = pair
         try:
             edges_remain = []
             path1 = nx.shortest_path(graph, src, dst)
             edges_used = pairwise(path1)
             edges_remain = set(total_edges) - set(edges_used)
             if len(edges_remain) > 0:
                 newgraph = nx.DiGraph()
                 newgraph.add_edges_from(edges_remain)
                 path2 = nx.shortest_path(newgraph, src, dst)
                 self.all_pair_shortest_path[pair] = [path1, path2]
         except:
             pass
Example #7
0
    def test_unorderable_nodes(self):
        """Tests that computing the longest path does not depend on
        nodes being orderable.

        For more information, see issue #1989.

        """
        # TODO In Python 3, instances of the `object` class are
        # unorderable by default, so we wouldn't need to define our own
        # class here, we could just instantiate an instance of the
        # `object` class. However, we still support Python 2; when
        # support for Python 2 is dropped, this test can be simplified
        # by replacing `Unorderable()` by `object()`.
        class Unorderable(object):

            def __le__(self):
                raise NotImplemented

            def __ge__(self):
                raise NotImplemented

        # Create the directed path graph on four nodes, with nodes
        # represented as (unorderable) Python objects.
        nodes = [Unorderable() for n in range(4)]
        G = nx.DiGraph()
        G.add_edges_from(pairwise(nodes))
        path = list(nx.dag_longest_path(G))
        assert_equal(path, nodes)
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 test_triangles():
    paths = [
        (11, 12, 13, 11),  # first 3-clique
        (21, 22, 23, 21),  # second 3-clique
        (11, 21),  # connected by an edge
    ]
    G = nx.Graph(it.chain(*[pairwise(path) for path in paths]))

    # subgraph and ccs are the same in all cases here
    assert_equal(
        fset(nx.k_edge_components(G, k=1)),
        fset(nx.k_edge_subgraphs(G, k=1))
    )

    assert_equal(
        fset(nx.k_edge_components(G, k=2)),
        fset(nx.k_edge_subgraphs(G, k=2))
    )

    assert_equal(
        fset(nx.k_edge_components(G, k=3)),
        fset(nx.k_edge_subgraphs(G, k=3))
    )

    _check_edge_connectivity(G)
def test_local_subgraph_difference_directed():
    dipaths = [
        (1, 2, 3, 4, 1),
        (1, 3, 1),
    ]
    G = nx.DiGraph(it.chain(*[pairwise(path) for path in dipaths]))

    assert_equal(
        fset(nx.k_edge_components(G, k=1)),
        fset(nx.k_edge_subgraphs(G, k=1))
    )

    # Unlike undirected graphs, when k=2, for directed graphs there is a case
    # where the k-edge-ccs are not the same as the k-edge-subgraphs.
    # (in directed graphs ccs and subgraphs are the same when k=2)
    assert_not_equal(
        fset(nx.k_edge_components(G, k=2)),
        fset(nx.k_edge_subgraphs(G, k=2))
    )

    assert_equal(
        fset(nx.k_edge_components(G, k=3)),
        fset(nx.k_edge_subgraphs(G, k=3))
    )

    _check_edge_connectivity(G)
Example #11
0
def add_path(G, nodes, **attr):
    """Add a path to the Graph G.

    Parameters
    ----------
    nodes : iterable container
        A container of nodes.  A path will be constructed from
        the nodes (in order) and added to the graph.
    attr : keyword arguments, optional (default= no attributes)
        Attributes to add to every edge in path.

    See Also
    --------
    add_star, add_cycle

    Examples
    --------
    >>> G = nx.Graph()
    >>> nx.add_path(G, [0, 1, 2, 3])
    >>> nx.add_path(G, [10, 11, 12], weight=7)
    """
    nlist = iter(nodes)
    try:
        first_node = next(nlist)
    except StopIteration:
        return
    G.add_node(first_node)
    G.add_edges_from(pairwise(chain((first_node,), nlist)), **attr)
def coopers_steiner_tree(G, terminal_nodes, weight='weight', verbose=False):
    '''
    Just do pairwise dijkstra distances for the terminal nodes
    we care about
    Parameters
    ----------
    G : NetworkX graph

    terminal_nodes : list
         A list of terminal nodes for which minimum steiner tree is
         to be found.

    '''
    H = nx.Graph()
    for u, v in combinations(terminal_nodes, 2):

        distance = nx.dijkstra_path_length(G, u, v, weight=weight)
        path = nx.dijkstra_path(G, u, v, weight=weight)
        H.add_edge(u, v, distance=distance, path=path)

    mst_edges = nx.minimum_spanning_edges(H, weight='distance', data=True)

    # Create an iterator over each edge in each shortest path; repeats are okay
    #if verbose: print("Begin iterator thing")
    edges = chain.from_iterable(pairwise(d['path']) for u, v, d in mst_edges)
    T = G.edge_subgraph(edges)
    return T
Example #13
0
def ladder_graph(n, create_using=None):
    """Return the Ladder graph of length n.

    This is two paths of n nodes, with
    each pair connected by a single edge.

    Node labels are the integers 0 to 2*n - 1.

    """
    if create_using is not None and create_using.is_directed():
        raise NetworkXError("Directed Graph not supported")
    G = empty_graph(2 * n, create_using)
    G.add_edges_from(pairwise(range(n)))
    G.add_edges_from(pairwise(range(n, 2 * n)))
    G.add_edges_from((v, v + n) for v in range(n))
    return G
Example #14
0
def add_cycle(G_to_add_to, nodes_for_cycle, **attr):
    """Add a cycle to the Graph G_to_add_to.

    Parameters
    ----------
    G_to_add_to : graph
        A NetworkX graph
    nodes_for_cycle: iterable container
        A container of nodes.  A cycle will be constructed from
        the nodes (in order) and added to the graph.
    attr : keyword arguments, optional (default= no attributes)
        Attributes to add to every edge in cycle.

    See Also
    --------
    add_path, add_star

    Examples
    --------
    >>> G = nx.Graph()   # or DiGraph, MultiGraph, MultiDiGraph, etc
    >>> nx.add_cycle(G, [0, 1, 2, 3])
    >>> nx.add_cycle(G, [10, 11, 12], weight=7)
    """
    nlist = iter(nodes_for_cycle)
    try:
        first_node = next(nlist)
    except StopIteration:
        return
    G_to_add_to.add_node(first_node)
    G_to_add_to.add_edges_from(pairwise(chain((first_node,), nlist), cyclic=True), **attr)
Example #15
0
def dag_longest_path_length(G, weight='weight', default_weight=1):
    """Returns the longest path length in a DAG

    Parameters
    ----------
    G : NetworkX DiGraph
        A directed acyclic graph (DAG)

    weight : string, optional
        Edge data key to use for weight

    default_weight : int, optional
        The weight of edges that do not have a weight attribute

    Returns
    -------
    int
        Longest path length

    Raises
    ------
    NetworkXNotImplemented
        If `G` is not directed

    See also
    --------
    dag_longest_path
    """
    path = nx.dag_longest_path(G, weight, default_weight)
    path_length = 0
    for (u, v) in pairwise(path):
        path_length += G[u][v].get(weight, default_weight)

    return path_length
Example #16
0
    def test_unorderable_nodes(self):
        """Tests that A* accomodates nodes that are not orderable.

        For more information, see issue #554.

        """

        # TODO In Python 3, instances of the `object` class are
        # unorderable by default, so we wouldn't need to define our own
        # class here, we could just instantiate an instance of the
        # `object` class. However, we still support Python 2; when
        # support for Python 2 is dropped, this test can be simplified
        # by replacing `Unorderable()` by `object()`.
        class Unorderable(object):
            def __le__(self):
                raise NotImplemented

            def __ge__(self):
                raise NotImplemented

        # Create the cycle graph on four nodes, with nodes represented
        # as (unorderable) Python objects.
        nodes = [Unorderable() for n in range(4)]
        G = nx.Graph()
        G.add_edges_from(pairwise(nodes, cyclic=True))
        path = nx.astar_path(G, nodes[0], nodes[2])
        assert_equal(len(path), 3)
Example #17
0
    def getModifiedSteinerTree(self, graph, steiner_nodes, steiner_edges):
        biGraph = self.bidirected(graph)

        M = self.metric_closure(biGraph, weight='weight')
        H = M.subgraph(steiner_nodes)

        for edge in steiner_edges:
            # To-Do check this condition...
            if edge[0] in H.edges and edge[2] in H.edges:
                H[edge[0]][edge[2]]['distance'] = -1

        mst_edges = nx.minimum_spanning_edges(H, weight='weight', data=True)
        edges = chain.from_iterable(
            pairwise(d['path']) for u, v, d in mst_edges)

        selected_edges = []
        for edge in edges:
            selected_edges += [edge]
            selected_edges += [(edge[1], edge[0])]

        tree = graph.edge_subgraph(
            selected_edges) if selected_edges else graph.subgraph(
                steiner_nodes)

        return tree
Example #18
0
def complete_multipartite_graph(*subset_sizes):
    # The complete multipartite graph is an undirected simple graph.
    G = Graph()

    if len(subset_sizes) == 0:
        return G

    # set up subsets of nodes
    try:
        extents = pairwise(accumulate((0, ) + subset_sizes))
        subsets = [range(start, end) for start, end in extents]
    except TypeError:
        subsets = subset_sizes

    # add nodes with subset attribute
    # while checking that ints are not mixed with iterables
    try:
        for (i, subset) in enumerate(subsets):
            G.add_nodes_from(subset, subset=i)
    except TypeError:
        raise NetworkXError("Arguments must be all ints or all iterables")

    # Across subsets, all vertices should be adjacent.
    # We can use itertools.combinations() because undirected.
    for subset1, subset2 in itertools.combinations(subsets, 2):
        G.add_edges_from(itertools.product(subset1, subset2))
    return G
Example #19
0
def add_path(G_to_add_to, nodes_for_path, **attr):
    """Add a path to the Graph G_to_add_to.

    Parameters
    ----------
    G_to_add_to : graph
        A NetworkX graph
    nodes_for_path : iterable container
        A container of nodes.  A path will be constructed from
        the nodes (in order) and added to the graph.
    attr : keyword arguments, optional (default= no attributes)
        Attributes to add to every edge in path.

    See Also
    --------
    add_star, add_cycle

    Examples
    --------
    >>> G = nx.Graph()
    >>> nx.add_path(G, [0, 1, 2, 3])
    >>> nx.add_path(G, [10, 11, 12], weight=7)
    """
    nlist = iter(nodes_for_path)
    try:
        first_node = next(nlist)
    except StopIteration:
        return
    G_to_add_to.add_node(first_node)
    G_to_add_to.add_edges_from(pairwise(chain((first_node, ), nlist)), **attr)
Example #20
0
def dag_longest_path_length(G, weight='weight', default_weight=1):
    """Returns the longest path length in a DAG

    Parameters
    ----------
    G : NetworkX DiGraph
        Graph

    weight : string (default 'weight')
        Edge data key to use for weight

    default_weight : integer (default 1)
        The weight of edges that do not have a weight attribute

    Returns
    -------
    path_length : int
        Longest path length

    Raises
    ------
    NetworkXNotImplemented
        If G is not directed

    See also
    --------
    dag_longest_path
    """
    path = nx.dag_longest_path(G, weight, default_weight)
    path_length = 0
    for (u, v) in pairwise(path):
        path_length += G[u][v].get(weight, default_weight)

    return path_length
Example #21
0
def dag_longest_path_length(G, weight="weight", default_weight=1):
    """Returns the longest path length in a DAG

    Parameters
    ----------
    G : NetworkX DiGraph
        A directed acyclic graph (DAG)

    weight : string, optional
        Edge data key to use for weight

    default_weight : int, optional
        The weight of edges that do not have a weight attribute

    Returns
    -------
    int
        Longest path length

    Raises
    ------
    NetworkXNotImplemented
        If `G` is not directed

    See also
    --------
    dag_longest_path
    """
    path = nx.dag_longest_path(G, weight, default_weight)
    path_length = 0
    for (u, v) in pairwise(path):
        path_length += G[u][v].get(weight, default_weight)

    return path_length
def test_four_clique():
    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 the 4 cliques such that they are
        # 3-connected in G, but not in the subgraph.
        # Case where the nodes bridging them do not have degree less than 3.
        (100, 13),
        (12, 100, 22),
        (13, 200, 23),
        (14, 300, 24),
    ]
    G = nx.Graph(it.chain(*[pairwise(path) for path in paths]))

    # The subgraphs and ccs are different for k=3
    local_ccs = fset(nx.k_edge_components(G, k=3))
    subgraphs = fset(nx.k_edge_subgraphs(G, k=3))
    assert_not_equal(local_ccs, subgraphs)

    # The cliques ares in the same cc
    clique1 = frozenset(paths[0])
    clique2 = frozenset(paths[1])
    assert_in(clique1.union(clique2).union({100}), local_ccs)

    # but different subgraphs
    assert_in(clique1, subgraphs)
    assert_in(clique2, subgraphs)

    assert_equal(G.degree(100), 3)

    _check_edge_connectivity(G)
Example #23
0
    def test_unorderable_nodes(self):
        """Tests that A* accomodates nodes that are not orderable.

        For more information, see issue #554.

        """
        # TODO In Python 3, instances of the `object` class are
        # unorderable by default, so we wouldn't need to define our own
        # class here, we could just instantiate an instance of the
        # `object` class. However, we still support Python 2; when
        # support for Python 2 is dropped, this test can be simplified
        # by replacing `Unorderable()` by `object()`.
        class Unorderable(object):

            def __le__(self):
                raise NotImplemented

            def __ge__(self):
                raise NotImplemented

        # Create the cycle graph on four nodes, with nodes represented
        # as (unorderable) Python objects.
        nodes = [Unorderable() for n in range(4)]
        G = nx.Graph()
        G.add_edges_from(pairwise(nodes, cyclic=True))
        path = nx.astar_path(G, nodes[0], nodes[2])
        assert_equal(len(path), 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([{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 #26
0
    def test_unorderable_nodes(self):
        """Tests that computing the longest path does not depend on
        nodes being orderable.

        For more information, see issue #1989.

        """

        # TODO In Python 3, instances of the `object` class are
        # unorderable by default, so we wouldn't need to define our own
        # class here, we could just instantiate an instance of the
        # `object` class. However, we still support Python 2; when
        # support for Python 2 is dropped, this test can be simplified
        # by replacing `Unorderable()` by `object()`.
        class Unorderable(object):
            def __le__(self):
                raise NotImplemented

            def __ge__(self):
                raise NotImplemented

        # Create the directed path graph on four nodes, with nodes
        # represented as (unorderable) Python objects.
        nodes = [Unorderable() for n in range(4)]
        G = nx.DiGraph()
        G.add_edges_from(pairwise(nodes))
        path = list(nx.dag_longest_path(G))
        assert_equal(path, nodes)
Example #27
0
def wheel_graph(n, create_using=None):
    """ Return the wheel graph
    
    The wheel graph consists of a hub node connected to a cycle of (n-1) nodes.

    Parameters
    ==========
    n : int or iterable
        If an integer, node labels are 0 to n with center 0.
        If an iterable of nodes, the center is the first.
    create_using : Graph, optional (default Graph())
        If provided this graph is cleared of nodes and edges and filled
        with the new graph. Usually used to set the type of the graph.
    Node labels are the integers 0 to n - 1.

    """
    n_name, nodes = n
    if n_name == 0:
        G = nx.empty_graph(0, create_using=create_using)
        G.name = "wheel_graph(0)"
        return G
    G = star_graph(nodes, create_using)
    G.name = "wheel_graph(%s)" % (n_name, )
    if len(G) > 2:
        G.add_edges_from(pairwise(nodes[1:]))
        G.add_edge(nodes[-1], nodes[1])
    return G
Example #28
0
def wheel_graph(n, create_using=None):
    """ Return the wheel graph
    
    The wheel graph consists of a hub node connected to a cycle of (n-1) nodes.

    Parameters
    ==========
    n : int or iterable
        If an integer, node labels are 0 to n with center 0.
        If an iterable of nodes, the center is the first.
    create_using : Graph, optional (default Graph())
        If provided this graph is cleared of nodes and edges and filled
        with the new graph. Usually used to set the type of the graph.
    Node labels are the integers 0 to n - 1.

    """
    n_name, nodes = n
    if n_name == 0:
        G = nx.empty_graph(0, create_using=create_using)
        G.name = "wheel_graph(0)"
        return G
    G = star_graph(nodes, create_using)
    G.name = "wheel_graph(%s)" % (n_name,)
    if len(G) > 2:
        G.add_edges_from(pairwise(nodes[1:]))
        G.add_edge(nodes[-1], nodes[1])
    return G
def test_local_subgraph_difference_directed():
    dipaths = [
        (1, 2, 3, 4, 1),
        (1, 3, 1),
    ]
    G = nx.DiGraph(it.chain(*[pairwise(path) for path in dipaths]))

    assert_equal(
        fset(nx.k_edge_components(G, k=1)),
        fset(nx.k_edge_subgraphs(G, k=1))
    )

    # Unlike undirected graphs, when k=2, for directed graphs there is a case
    # where the k-edge-ccs are not the same as the k-edge-subgraphs.
    # (in directed graphs ccs and subgraphs are the same when k=2)
    assert_not_equal(
        fset(nx.k_edge_components(G, k=2)),
        fset(nx.k_edge_subgraphs(G, k=2))
    )

    assert_equal(
        fset(nx.k_edge_components(G, k=3)),
        fset(nx.k_edge_subgraphs(G, k=3))
    )

    _check_edge_connectivity(G)
Example #30
0
def test_five_clique():
    # Make a graph that can be disconnected less than 4 edges, but no node has
    # degree less than 4.
    G = nx.disjoint_union(nx.complete_graph(5), nx.complete_graph(5))
    paths = [
        # add aux-connections
        (1, 100, 6),
        (2, 100, 7),
        (3, 200, 8),
        (4, 200, 100),
    ]
    G.add_edges_from(it.chain(*[pairwise(path) for path in paths]))
    assert_equal(min(dict(nx.degree(G)).values()), 4)

    # For k=3 they are the same
    assert_equal(fset(nx.k_edge_components(G, k=3)),
                 fset(nx.k_edge_subgraphs(G, k=3)))

    # For k=4 they are the different
    # the aux nodes are in the same CC as clique 1 but no the same subgraph
    assert_not_equal(fset(nx.k_edge_components(G, k=4)),
                     fset(nx.k_edge_subgraphs(G, k=4)))

    # For k=5 they are not the same
    assert_not_equal(fset(nx.k_edge_components(G, k=5)),
                     fset(nx.k_edge_subgraphs(G, k=5)))

    # For k=6 they are the same
    assert_equal(fset(nx.k_edge_components(G, k=6)),
                 fset(nx.k_edge_subgraphs(G, k=6)))
    _check_edge_connectivity(G)
Example #31
0
def cycle_graph(n, create_using=None):
    """Return the cycle graph `C_n` of cyclicly connected nodes.

    `C_n` is a path with its two end-nodes connected.

    Parameters
    ==========
    n : int or iterable container of nodes
        If n is an integer, nodes are from `range(n)`.
        If n is a container of nodes, those nodes appear in the graph.
    create_using : Graph, optional (default Graph())
        If provided this graph is cleared of nodes and edges and filled
        with the new graph. Usually used to set the type of the graph.

    Notes
    =====
    If create_using is directed, the direction is in increasing order.

    """
    n_orig, nodes = n
    G = empty_graph(nodes, create_using)
    G.name = "cycle_graph(%s)" % (n_orig, )
    G.add_edges_from(pairwise(nodes))
    G.add_edge(nodes[-1], nodes[0])
    return G
Example #32
0
def test_four_clique():
    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 the 4 cliques such that they are
        # 3-connected in G, but not in the subgraph.
        # Case where the nodes bridging them do not have degree less than 3.
        (100, 13),
        (12, 100, 22),
        (13, 200, 23),
        (14, 300, 24),
    ]
    G = nx.Graph(it.chain(*[pairwise(path) for path in paths]))

    # The subgraphs and ccs are different for k=3
    local_ccs = fset(nx.k_edge_components(G, k=3))
    subgraphs = fset(nx.k_edge_subgraphs(G, k=3))
    assert_not_equal(local_ccs, subgraphs)

    # The cliques ares in the same cc
    clique1 = frozenset(paths[0])
    clique2 = frozenset(paths[1])
    assert_in(clique1.union(clique2).union({100}), local_ccs)

    # but different subgraphs
    assert_in(clique1, subgraphs)
    assert_in(clique2, subgraphs)

    assert_equal(G.degree(100), 3)

    _check_edge_connectivity(G)
Example #33
0
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)
Example #34
0
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)
Example #35
0
def ladder_graph(n, create_using=None):
    """Return the Ladder graph of length n.

    This is two paths of n nodes, with
    each pair connected by a single edge.

    Node labels are the integers 0 to 2*n - 1.

    """
    if create_using is not None and create_using.is_directed():
        raise NetworkXError("Directed Graph not supported")
    G = empty_graph(2 * n, create_using)
    G.add_edges_from(pairwise(range(n)))
    G.add_edges_from(pairwise(range(n, 2 * n)))
    G.add_edges_from((v, v + n) for v in range(n))
    return G
def test_triangles():
    paths = [
        (11, 12, 13, 11),  # first 3-clique
        (21, 22, 23, 21),  # second 3-clique
        (11, 21),  # connected by an edge
    ]
    G = nx.Graph(it.chain(*[pairwise(path) for path in paths]))

    # subgraph and ccs are the same in all cases here
    assert_equal(
        fset(nx.k_edge_components(G, k=1)),
        fset(nx.k_edge_subgraphs(G, k=1))
    )

    assert_equal(
        fset(nx.k_edge_components(G, k=2)),
        fset(nx.k_edge_subgraphs(G, k=2))
    )

    assert_equal(
        fset(nx.k_edge_components(G, k=3)),
        fset(nx.k_edge_subgraphs(G, k=3))
    )

    _check_edge_connectivity(G)
Example #37
0
 def allocate_flow(self, intent: Intent, use_virtual=False):
     capacity_key = self._get_capacity_key(use_virtual)
     path = intent.path
     req = intent.required_bw
     intent_uuid = intent.id
     for s, d in pairwise(path):
         self[s][d][capacity_key] -= req
         self[s][d]["bilink"].intents[intent_uuid] = intent
Example #38
0
 def test_multidigraph_unweighted(self):
     # This is the twice-singly-linked directed cycle graph on six nodes.
     edges = list(pairwise(range(6), cyclic=True))
     G = nx.MultiDiGraph(2 * edges)
     H = nx.DiGraph(G)
     G_cells = nx.voronoi_cells(G, {0, 3})
     H_cells = nx.voronoi_cells(H, {0, 3})
     assert G_cells == H_cells
Example #39
0
    def getGrid(self):
        rows = input("Rows?: ")
        rows = int(rows)
        cols = input("Columns: ")
        cols = int(cols)

        input("Start the sensor at the bottom left of the grid, hit enter when ready.")
       
        
        for i in range(rows):
            for j in range(cols):
                self.map.add_node(self.getData())
                input("Move the sensor to the next position and hit enter when ready.")

        self.map.add_edges_from(((i, j), (pi, j)) for pi, i in pairwise(list(range(rows))) for j in range(cols))
        
        self.map.add_edges_from(((i, j), (i, pj)) for i in range(rows) for pj, j in pairwise(list(range(cols))))
Example #40
0
def grid_2d_graph(m, n, periodic=False, create_using=None):
    """Returns the two-dimensional grid graph.

    The grid graph has each node connected to its four nearest neighbors.

    Parameters
    ----------
    m, n : int or iterable container of nodes
        If an integer, nodes are from `range(n)`.
        If a container, elements become the coordinate of the nodes.

    periodic : bool (default: False)
        If this is ``True`` the nodes on the grid boundaries are joined
        to the corresponding nodes on the opposite grid boundaries.

    create_using : NetworkX graph (default: Graph())
        If provided this graph is cleared of nodes and edges and filled
        with the new graph. Usually used to set the type of the graph.

    Returns
    -------
    NetworkX graph
        The (possibly periodic) grid graph of the specified dimensions.

    """
    G = empty_graph(0, create_using)
    row_name, rows = m
    col_name, cols = n
    G.add_nodes_from((i, j) for i in rows for j in cols)
    G.add_edges_from(
        ((i, j), (pi, j)) for pi, i in pairwise(rows) for j in cols)
    G.add_edges_from(
        ((i, j), (i, pj)) for i in rows for pj, j in pairwise(cols))
    if periodic is True:
        if len(rows) > 2:
            first = rows[0]
            last = rows[-1]
            G.add_edges_from(((first, j), (last, j)) for j in cols)
        if len(cols) > 2:
            first = cols[0]
            last = cols[-1]
            G.add_edges_from(((i, first), (i, last)) for i in rows)
    # both directions for directed
    if G.is_directed():
        G.add_edges_from((v, u) for u, v in G.edges())
    return G
Example #41
0
 def test_multidigraph_unweighted(self):
     # This is the twice-singly-linked directed cycle graph on six nodes.
     edges = list(pairwise(range(6), cyclic=True))
     G = nx.MultiDiGraph(2 * edges)
     H = nx.DiGraph(G)
     G_cells = nx.voronoi_cells(G, {0, 3})
     H_cells = nx.voronoi_cells(H, {0, 3})
     assert_equal(G_cells, H_cells)
Example #42
0
def grid_2d_graph(m, n, periodic=False, create_using=None):
    """ Return the 2d grid graph of mxn nodes
    
    The grid graph has each node connected to its four nearest neighbors.

    Parameters
    ==========
    m, n : int or iterable container of nodes (default = 0)
        If an integer, nodes are from `range(n)`.
        If a container, those become the coordinate of the node.
    periodic : bool (default = False)
        If True will connect boundary nodes in periodic fashion.
    create_using : Graph, optional (default Graph())
        If provided this graph is cleared of nodes and edges and filled
        with the new graph. Usually used to set the type of the graph.
    """
    G = empty_graph(0, create_using)
    row_name, rows = m
    col_name, columns = n
    G.name = "grid_2d_graph(%s, %s)" % (row_name, col_name)
    G.add_nodes_from((i, j) for i in rows for j in columns)
    G.add_edges_from(((i, j), (pi, j))
                     for pi, i in pairwise(rows) for j in columns)
    G.add_edges_from(((i, j), (i, pj))
                     for i in rows for pj, j in pairwise(columns))
    if G.is_directed():
        G.add_edges_from(((pi, j), (i, j))
                         for pi, i in pairwise(rows) for j in columns)
        G.add_edges_from(((i, pj), (i, j))
                         for i in rows for pj, j in pairwise(columns))
    if periodic:
        if len(columns) > 2:
            f = columns[0]
            l = columns[-1]
            G.add_edges_from(((i, f), (i, l)) for i in rows)
            if G.is_directed():
                G.add_edges_from(((i, l), (i, f)) for i in rows)
        if len(rows) > 2:
            f = rows[0]
            l = rows[-1]
            G.add_edges_from(((f, j), (l, j)) for j in columns)
            if G.is_directed():
                G.add_edges_from(((l, j), (f, j)) for j in columns)
        G.name = "periodic_grid_2d_graph(%s,%s)" % (m, n)
    return G
Example #43
0
def grid_2d_graph(m, n, periodic=False, create_using=None):
    """Returns the two-dimensional grid graph.

    The grid graph has each node connected to its four nearest neighbors.

    Parameters
    ----------
    m, n : int or iterable container of nodes
        If an integer, nodes are from `range(n)`.
        If a container, elements become the coordinate of the nodes.

    periodic : bool (default: False)
        If this is ``True`` the nodes on the grid boundaries are joined
        to the corresponding nodes on the opposite grid boundaries.

    create_using : NetworkX graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.

    Returns
    -------
    NetworkX graph
        The (possibly periodic) grid graph of the specified dimensions.

    """
    G = empty_graph(0, create_using)
    row_name, rows = m
    col_name, cols = n
    G.add_nodes_from((i, j) for i in rows for j in cols)
    G.add_edges_from(((i, j), (pi, j))
                     for pi, i in pairwise(rows) for j in cols)
    G.add_edges_from(((i, j), (i, pj))
                     for i in rows for pj, j in pairwise(cols))
    if periodic is True:
        if len(rows) > 2:
            first = rows[0]
            last = rows[-1]
            G.add_edges_from(((first, j), (last, j)) for j in cols)
        if len(cols) > 2:
            first = cols[0]
            last = cols[-1]
            G.add_edges_from(((i, first), (i, last)) for i in rows)
    # both directions for directed
    if G.is_directed():
        G.add_edges_from((v, u) for u, v in G.edges())
    return G
Example #44
0
    def test_weight_functions(self):
        def heuristic(*z):
            return hash(z)

        def getpath(pred, v, s):
            return [v] if v == s else getpath(pred, pred[v], s) + [v]

        def goldberg_radzik(g, s, t, weight="weight"):
            pred, dist = nx.goldberg_radzik(g, s, weight=weight)
            dist = dist[t]
            return dist, getpath(pred, t, s)

        def astar(g, s, t, weight="weight"):
            path = nx.astar_path(g, s, t, heuristic, weight=weight)
            dist = nx.astar_path_length(g, s, t, heuristic, weight=weight)
            return dist, path

        def vlp(G, s, t, l, F, w):
            res = F(G, s, t, weight=w)
            validate_length_path(G, s, t, l, *res, weight=w)

        G = self.cycle
        s = 6
        t = 4
        path = [6] + list(range(t + 1))

        def weight(u, v, _):
            return 1 + v**2

        length = sum(weight(u, v, None) for u, v in pairwise(path))
        vlp(G, s, t, length, nx.bidirectional_dijkstra, weight)
        vlp(G, s, t, length, nx.single_source_dijkstra, weight)
        vlp(G, s, t, length, nx.single_source_bellman_ford, weight)
        vlp(G, s, t, length, goldberg_radzik, weight)
        vlp(G, s, t, length, astar, weight)

        def weight(u, v, _):
            return 2**(u * v)

        length = sum(weight(u, v, None) for u, v in pairwise(path))
        vlp(G, s, t, length, nx.bidirectional_dijkstra, weight)
        vlp(G, s, t, length, nx.single_source_dijkstra, weight)
        vlp(G, s, t, length, nx.single_source_bellman_ford, weight)
        vlp(G, s, t, length, goldberg_radzik, weight)
        vlp(G, s, t, length, astar, weight)
Example #45
0
    def __init__(self, fname):
        self.G = nx.Graph()
        self.G.add_node(0, n=0)
        self.max_stufe = 0

        with open(fname) as f:
            lines = f.readlines()

        for line in lines:
            match = self.tree_line.match(line)
            if match:
                move_str = match.group(0)
                moves_raw = self.move_regex.findall(match.group(0))
                moves = [(0, "here")] + \
                        [(make_move_id(i,m, moves_raw), m)
                         for i, m in enumerate(moves_raw) ]
                attrs = [atrr.split('=') for atrr in self.attr_regex.findall(move_str)]
                _attrs = {k:v for k,v in attrs}

                f=int (_attrs['F'])

                for i, ((mv_id_a, a),(mv_id_b, b)) in enumerate(pairwise(moves[::-1])):
                    attrs = _attrs
                    attrs['F'] = str(f)
                    attrs['n'] = i

                    self.G.add_edge(mv_id_b , mv_id_a, ** attrs,
                                    width=2,
                                    color='black'
                                    )

                    print (attrs)
                    self.G.add_node(
                        mv_id_a,
                        label = str(a) + ( f" {attrs['b']}" ),
                        color='black',
                        **attrs
                    )


                    if (len(moves)) > self.max_stufe:
                        self.max_stufe = len(moves)

                    if 'x' in attrs:
                        self.G.nodes[mv_id_b]['color'] = 'red'


                        if (attrs['x'] == 'PIVOT'):
                                self.G.edges[mv_id_a,mv_id_b]['color'] = 'red'
                                self.G.edges[mv_id_a,mv_id_b]['width'] = 10
                                self.G.nodes[mv_id_b]['color'] = 'red'
                        else:
                            self.G.edges[mv_id_a,mv_id_b]['label'] =f" {attrs['x']}"


                    f *= -1
Example #46
0
def runner():
    "Create and run a custom topo with adjustable link parameters"
    topo = CompleteGraphTopo( )
    c = RemoteController('c', '127.0.0.1', 6633)
    net = Mininet( topo=topo,
                   controller=None,
                              host=CPULimitedHost, link=TCLink ,waitConnected=True,autoSetMacs=True)

    net.addController(c)           
    net.start()
    enable_BFD(net)# enable bfd
    link_fail_dict=sw_link_map(net)
    edges=link_fail_dict.keys() # keys of link_fail_dict has all the edges of the graph
    edges=bi_direct_edges(edges) # make edges bi directional so that nx can find path
    graph=nx.DiGraph()
    graph.add_edges_from(edges) # construct graph from edges obtained from mininet net obj
    random.seed(30) # set seed for random number
    test_pair=[(0,7),(3,8),(0,9),(8,6),(9,1)] 
    result={'hop':[],'delay':[],'throughput':[]}
    time.sleep(8)
    for pair in test_pair:
        host1,host2=pair
        src=net.getNodeByName('h'+str(host1+1))
        dst=net.getNodeByName('h'+str(host2+1))
        path=nx.shortest_path(graph,host1+1,host2+1) # compute shortest path from graph
        links_between_pair=pairwise(path) # make links from path
        randindex=random.randint(0,len(links_between_pair)-1) # find random index  to be used to get failed link
        link_to_fail=links_between_pair[randindex] # get random link to be failed using random index
        print 'Failing link between',link_to_fail
        
        if link_fail_dict.has_key(link_to_fail):
           link_to_fail_obj=link_fail_dict[link_to_fail] # find the link obj to fail
        elif link_fail_dict.has_key(link_to_fail[::-1]): # link might be with reverse key
             link_to_fail_obj=link_fail_dict[link_to_fail[::-1]] # find the link obj to fail 
             link_to_fail= link_to_fail[::-1]  
        try:
           print ping(net,[src,dst],64,2)# send some packets before calculation
           net.delLink(link_to_fail_obj) # delete link to fail it
        except:
          import pdb;pdb.set_trace()
        time.sleep(5)        
        sent,received,min_,avg=ping(net,[src,dst],1024,5)
        print 'Delay ',avg,' for ',pair
        result['delay'].append(float(avg))
        hop=get_path_length(net,src,dst)
        print 'Hop ',hop,' for ',pair
        result['hop'].append(float(hop))
        time_perf,datasize_tx,bitrate=doIperf(net,src,dst)
        print 'Throughput ',bitrate,' for ',pair
        result['throughput'].append(float(bitrate))
        link_fail_dict[link_to_fail]=net.addLink("s%d" %link_to_fail[0],"s%d" %link_to_fail[1])
    print 'Average Number of Hop:', getavg(result['hop'])
    print 'Average Delay: ', getavg(result['delay'])
    print 'Throughput:',getavg(result['throughput'])
    CLI(net)
    net.stop()
Example #47
0
def _path_to_cycle(path):
    """
    Removes the edges from path that occur even number of times.
    Returns a set of edges
    """
    edges = set()
    for edge in pairwise(path):
        # Toggle whether to keep the current edge.
        edges ^= {edge}
    return edges
def test_bridge_cc():
    # define 2-connected components and bridges
    cc2 = [(1, 2, 4, 3, 1, 4), (8, 9, 10, 8), (11, 12, 13, 11)]
    bridges = [(4, 8), (3, 5), (20, 21), (22, 23, 24)]
    G = nx.Graph(it.chain(*(pairwise(path) for path in cc2 + bridges)))
    bridge_ccs = fset(bridge_components(G))
    target_ccs = fset([{1, 2, 3, 4}, {5}, {8, 9, 10}, {11, 12, 13}, {20}, {21},
                       {22}, {23}, {24}])
    assert bridge_ccs == target_ccs
    _check_edge_connectivity(G)
Example #49
0
def are_edge_disjoint_paths(G, paths):
    if not paths:
        return False
    for path in paths:
        assert_true(is_path(G, path))
    paths_edges = [list(pairwise(p)) for p in paths]
    num_of_edges = sum(len(e) for e in paths_edges)
    num_unique_edges = len(set.union(*[set(es) for es in paths_edges]))
    if num_of_edges == num_unique_edges:
        return True
    return False
Example #50
0
    def test_directed_inward(self):
        """Tests that reversing the graph gives the "inward" Voronoi
        partition.

        """
        # This is the singly-linked reverse directed cycle graph on six nodes.
        G = nx.DiGraph(pairwise(range(6), cyclic=True))
        G = G.reverse(copy=False)
        cells = nx.voronoi_cells(G, {0, 3})
        expected = {0: {0, 4, 5}, 3: {1, 2, 3}}
        assert_equal(expected, cells)
def test_tarjan_bridge():
    # graph from tarjan paper
    # RE Tarjan - "A note on finding the bridges of a graph"
    # Information Processing Letters, 1974 - Elsevier
    # doi:10.1016/0020-0190(74)90003-9.
    # define 2-connected components and bridges
    ccs = [(1, 2, 4, 3, 1, 4), (5, 6, 7, 5), (8, 9, 10, 8),
           (17, 18, 16, 15, 17), (11, 12, 14, 13, 11, 14)]
    bridges = [(4, 8), (3, 5), (3, 17)]
    G = nx.Graph(it.chain(*(pairwise(path) for path in ccs + bridges)))
    _check_edge_connectivity(G)
def test_bridge_cc():
    # define 2-connected components and bridges
    cc2 = [(1, 2, 4, 3, 1, 4), (8, 9, 10, 8), (11, 12, 13, 11)]
    bridges = [(4, 8), (3, 5), (20, 21), (22, 23, 24)]
    G = nx.Graph(it.chain(*(pairwise(path) for path in cc2 + bridges)))
    bridge_ccs = fset(bridge_components(G))
    target_ccs = fset([
        {1, 2, 3, 4}, {5}, {8, 9, 10}, {11, 12, 13}, {20},
        {21}, {22}, {23}, {24}
    ])
    assert_equal(bridge_ccs, target_ccs)
    _check_edge_connectivity(G)
Example #53
0
def lollipop_graph(m, n, create_using=None):
    """Return the Lollipop Graph; `K_m` connected to `P_n`.

    This is the Barbell Graph without the right barbell.

    Parameters
    ==========
    m, n : int or iterable container of nodes (default = 0)
        If an integer, nodes are from `range(m)` and `range(m,m+n)`.
        If a container, the entries are the coordinate of the node.

        The nodes for m appear in the complete graph `K_m` and the nodes
        for n appear in the path `P_n`
    create_using : Graph, optional (default Graph())
        If provided this graph is cleared of nodes and edges and filled
        with the new graph. Usually used to set the type of the graph.

    Notes
    =====
    The 2 subgraphs are joined via an edge (m-1, m).  
    If n=0, this is merely a complete graph.

    (This graph is an extremal example in David Aldous and Jim
    Fill's etext on Random Walks on Graphs.)

    """
    m, m_nodes = m
    n, n_nodes = n
    M = len(m_nodes)
    N = len(n_nodes)
    if isinstance(m, int):
        n_nodes = [len(m_nodes) + i for i in n_nodes]
    if create_using is not None and create_using.is_directed():
        raise nx.NetworkXError("Directed Graph not supported")
    if M < 2:
        raise nx.NetworkXError(
            "Invalid graph description, m should be >=2")
    if N < 0:
        raise nx.NetworkXError(
            "Invalid graph description, n should be >=0")

    # the ball
    G = complete_graph(m_nodes, create_using)
    # the stick
    G.add_nodes_from(n_nodes)
    if N > 1:
        G.add_edges_from(pairwise(n_nodes))
    # connect ball to stick
    if M > 0 and N > 0:
        G.add_edge(m_nodes[-1], n_nodes[0])
    G.name = "lollipop_graph(%s, %s)" % (m, n)
    return G
Example #54
0
def lollipop_graph(m, n, create_using=None):
    """Returns the Lollipop Graph; `K_m` connected to `P_n`.

    This is the Barbell Graph without the right barbell.

    Parameters
    ----------
    m, n : int or iterable container of nodes (default = 0)
        If an integer, nodes are from `range(m)` and `range(m,m+n)`.
        If a container, the entries are the coordinate of the node.

        The nodes for m appear in the complete graph $K_m$ and the nodes
        for n appear in the path $P_n$
    create_using : NetworkX graph constructor, optional (default=nx.Graph)
       Graph type to create. If graph instance, then cleared before populated.

    Notes
    -----
    The 2 subgraphs are joined via an edge (m-1, m).
    If n=0, this is merely a complete graph.

    (This graph is an extremal example in David Aldous and Jim
    Fill's etext on Random Walks on Graphs.)

    """
    m, m_nodes = m
    n, n_nodes = n
    M = len(m_nodes)
    N = len(n_nodes)
    if isinstance(m, int):
        n_nodes = [len(m_nodes) + i for i in n_nodes]
    if M < 2:
        raise NetworkXError(
            "Invalid graph description, m should be >=2")
    if N < 0:
        raise NetworkXError(
            "Invalid graph description, n should be >=0")

    # the ball
    G = complete_graph(m_nodes, create_using)
    if G.is_directed():
        raise NetworkXError("Directed Graph not supported")
    # the stick
    G.add_nodes_from(n_nodes)
    if N > 1:
        G.add_edges_from(pairwise(n_nodes))
    # connect ball to stick
    if M > 0 and N > 0:
        G.add_edge(m_nodes[-1], n_nodes[0])
    return G
Example #55
0
def is_semiconnected(G):
    """Return True if the graph is semiconnected, False otherwise.

    A graph is semiconnected if, and only if, for any pair of nodes, either one
    is reachable from the other, or they are mutually reachable.

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

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

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

    NetworkXPointlessConcept :
        If the graph is empty.

    Examples
    --------
    >>> G=nx.path_graph(4,create_using=nx.DiGraph())
    >>> print(nx.is_semiconnected(G))
    True
    >>> G=nx.DiGraph([(1, 2), (3, 2)])
    >>> print(nx.is_semiconnected(G))
    False

    See Also
    --------
    is_strongly_connected
    is_weakly_connected
    is_connected
    is_biconnected
    """
    if len(G) == 0:
        raise nx.NetworkXPointlessConcept(
            'Connectivity is undefined for the null graph.')

    if not nx.is_weakly_connected(G):
        return False

    G = nx.condensation(G)
    path = nx.topological_sort(G)
    return all(G.has_edge(u, v) for u, v in pairwise(path))
Example #56
0
 def test_nondecreasing_degree_sequence(self):
     # Check for lexicographically nondecreasing degree sequences
     # (for fixed number of nodes and edges).
     #
     # There are three exceptions to this rule in the order given in
     # the "Atlas of Graphs" book, so we need to manually exclude
     # those.
     exceptions = [('G55', 'G56'), ('G1007', 'G1008'), ('G1012', 'G1013')]
     for n, group in groupby(self.GAG, key=nx.number_of_nodes):
         for m, group in groupby(group, key=nx.number_of_edges):
             for G1, G2 in pairwise(group):
                 if (G1.name, G2.name) in exceptions:
                     continue
                 d1 = sorted(d for v, d in G1.degree())
                 d2 = sorted(d for v, d in G2.degree())
                 assert_less_equal(d1, d2)
Example #57
0
def path_graph(n, create_using=None):
    """Returns the Path graph `P_n` of linearly connected nodes.

    Parameters
    ----------
    n : int or iterable
        If an integer, node labels are 0 to n with center 0.
        If an iterable of nodes, the center is the first.
    create_using : NetworkX graph constructor, optional (default=nx.Graph)
       Graph type to create. If graph instance, then cleared before populated.

    """
    n_name, nodes = n
    G = empty_graph(nodes, create_using)
    G.add_edges_from(pairwise(nodes))
    return G
Example #58
0
def wheel_graph(n, create_using=None):
    """ Return the wheel graph: a single hub node connected to each node of the (n-1)-node cycle graph.

    Node labels are the integers 0 to n - 1.

    """
    n_name, nodes = n
    if n_name == 0:
        G = nx.empty_graph(0, create_using=create_using)
        G.name = "wheel_graph(0)"
        return G
    G = star_graph(nodes, create_using)
    G.name="wheel_graph(%s)"%(n_name,)
    if len(G) > 2:
        G.add_edges_from(pairwise(nodes[1:]))
        G.add_edge(nodes[-1],nodes[1])
    return G
Example #59
0
def path_graph(n, create_using=None):
    """Return the Path graph `P_n` of linearly connected nodes.

    Parameters
    ----------
    n : int or iterable
        If an integer, node labels are 0 to n with center 0.
        If an iterable of nodes, the center is the first.
    create_using : Graph, optional (default Graph())
        If provided this graph is cleared of nodes and edges and filled
        with the new graph. Usually used to set the type of the graph.

    """
    n_name, nodes = n
    G = empty_graph(nodes, create_using)
    G.add_edges_from(pairwise(nodes))
    return G