Ejemplo n.º 1
0
def is_k_edge_connected(G, k):
    """
    Tests to see if a graph is k-edge-connected

    See Also
    --------
    is_locally_k_edge_connected

    Example
    -------
    >>> G = nx.barbell_graph(10, 0)
    >>> is_k_edge_connected(G, k=1)
    True
    >>> is_k_edge_connected(G, k=2)
    False
    """
    if k < 1:
        raise ValueError('k must be positive, not {}'.format(k))
    # First try to quickly determine if G is not k-edge-connected
    if G.number_of_nodes() < k + 1:
        return False
    elif any(d < k for n, d in G.degree()):
        return False
    else:
        # Otherwise perform the full check
        if k == 1:
            return nx.is_connected(G)
        elif k == 2:
            return not nx.has_bridges(G)
        else:
            # return nx.edge_connectivity(G, cutoff=k) >= k
            return nx.edge_connectivity(G) >= k
def is_k_edge_connected(G, k):
    """Tests to see if a graph is k-edge-connected.

    Is it impossible to disconnect the graph by removing fewer than k edges?
    If so, then G is k-edge-connected.

    Parameters
    ----------
    G : NetworkX graph
       An undirected graph.

    k : integer
        edge connectivity to test for

    Returns
    -------
    boolean
        True if G is k-edge-connected.

    See Also
    --------
    :func:`is_locally_k_edge_connected`

    Example
    -------
    >>> G = nx.barbell_graph(10, 0)
    >>> nx.is_k_edge_connected(G, k=1)
    True
    >>> nx.is_k_edge_connected(G, k=2)
    False
    """
    if k < 1:
        raise ValueError('k must be positive, not {}'.format(k))
    # First try to quickly determine if G is not k-edge-connected
    if G.number_of_nodes() < k + 1:
        return False
    elif any(d < k for n, d in G.degree()):
        return False
    else:
        # Otherwise perform the full check
        if k == 1:
            return nx.is_connected(G)
        elif k == 2:
            return not nx.has_bridges(G)
        else:
            return nx.edge_connectivity(G, cutoff=k) >= k
Ejemplo n.º 3
0
def is_k_edge_connected(G, k):
    """Tests to see if a graph is k-edge-connected.

    Is it impossible to disconnect the graph by removing fewer than k edges?
    If so, then G is k-edge-connected.

    Parameters
    ----------
    G : NetworkX graph
       An undirected graph.

    k : integer
        edge connectivity to test for

    Returns
    -------
    boolean
        True if G is k-edge-connected.

    See Also
    --------
    :func:`is_locally_k_edge_connected`

    Example
    -------
    >>> G = nx.barbell_graph(10, 0)
    >>> nx.is_k_edge_connected(G, k=1)
    True
    >>> nx.is_k_edge_connected(G, k=2)
    False
    """
    if k < 1:
        raise ValueError('k must be positive, not {}'.format(k))
    # First try to quickly determine if G is not k-edge-connected
    if G.number_of_nodes() < k + 1:
        return False
    elif any(d < k for n, d in G.degree()):
        return False
    else:
        # Otherwise perform the full check
        if k == 1:
            return nx.is_connected(G)
        elif k == 2:
            return not nx.has_bridges(G)
        else:
            return nx.edge_connectivity(G, cutoff=k) >= k
def weighted_bridge_augmentation(G, avail, weight=None):
    """Finds an approximate min-weight 2-edge-augmentation of G.

    This is an implementation of the approximation algorithm detailed in [1]_.
    It chooses a set of edges from avail to add to G that renders it
    2-edge-connected if such a subset exists.  This is done by finding a
    minimum spanning arborescence of a specially constructed metagraph.

    Parameters
    ----------
    G : NetworkX graph
       An undirected graph.

    avail : set of 2 or 3 tuples.
        candidate edges (with optional weights) to choose from

    weight : string
        key to use to find weights if avail is a set of 3-tuples where the
        third item in each tuple is a dictionary.

    Yields
    ------
    edge : tuple
        Edges in the subset of avail chosen to bridge augment G.

    Notes
    -----
    Finding a weighted 2-edge-augmentation is NP-hard.
    Any edge not in ``avail`` is considered to have a weight of infinity.
    The approximation factor is 2 if ``G`` is connected and 3 if it is not.
    Runs in :math:`O(m + n log(n))` time

    References
    ----------
    .. [1] Khuller, Samir, and Ramakrishna Thurimella. (1993) Approximation
        algorithms for graph augmentation.
        http://www.sciencedirect.com/science/article/pii/S0196677483710102

    See Also
    --------
    :func:`bridge_augmentation`
    :func:`k_edge_augmentation`

    Example
    -------
    >>> G = nx.path_graph((1, 2, 3, 4))
    >>> # When the weights are equal, (1, 4) is the best
    >>> avail = [(1, 4, 1), (1, 3, 1), (2, 4, 1)]
    >>> sorted(weighted_bridge_augmentation(G, avail))
    [(1, 4)]
    >>> # Giving (1, 4) a high weight makes the two edge solution the best.
    >>> avail = [(1, 4, 1000), (1, 3, 1), (2, 4, 1)]
    >>> sorted(weighted_bridge_augmentation(G, avail))
    [(1, 3), (2, 4)]
    >>> #------
    >>> G = nx.path_graph((1, 2, 3, 4))
    >>> G.add_node(5)
    >>> avail = [(1, 5, 11), (2, 5, 10), (4, 3, 1), (4, 5, 1)]
    >>> sorted(weighted_bridge_augmentation(G, avail=avail))
    [(1, 5), (4, 5)]
    >>> avail = [(1, 5, 11), (2, 5, 10), (4, 3, 1), (4, 5, 51)]
    >>> sorted(weighted_bridge_augmentation(G, avail=avail))
    [(1, 5), (2, 5), (4, 5)]
    """

    if weight is None:
        weight = 'weight'

    # If input G is not connected the approximation factor increases to 3
    if not nx.is_connected(G):
        H = G.copy()
        connectors = list(one_edge_augmentation(H, avail=avail, weight=weight))
        H.add_edges_from(connectors)

        for edge in connectors:
            yield edge
    else:
        connectors = []
        H = G

    if len(avail) == 0:
        if nx.has_bridges(H):
            raise nx.NetworkXUnfeasible('no augmentation possible')

    avail_uv, avail_w = _unpack_available_edges(avail, weight=weight, G=H)

    # Collapse input into a metagraph. Meta nodes are bridge-ccs
    bridge_ccs = nx.connectivity.bridge_components(H)
    C = collapse(H, bridge_ccs)

    # Use the meta graph to shrink avail to a small feasible subset
    mapping = C.graph['mapping']
    # Choose the minimum weight feasible edge in each group
    meta_to_wuv = {
        (mu, mv): (w, uv)
        for (mu, mv), uv, w in _lightest_meta_edges(mapping, avail_uv, avail_w)
    }

    # Mapping of terms from (Khuller and Thurimella):
    #     C         : G_0 = (V, E^0)
    #        This is the metagraph where each node is a 2-edge-cc in G.
    #        The edges in C represent bridges in the original graph.
    #     (mu, mv)  : E - E^0  # they group both avail and given edges in E
    #     T         : \Gamma
    #     D         : G^D = (V, E_D)

    #     The paper uses ancestor because children point to parents, which is
    #     contrary to networkx standards.  So, we actually need to run
    #     nx.least_common_ancestor on the reversed Tree.

    # Pick an arbitrary leaf from C as the root
    root = next(n for n in C.nodes() if C.degree(n) == 1)
    # Root C into a tree TR by directing all edges away from the root
    # Note in their paper T directs edges towards the root
    TR = nx.dfs_tree(C, root)

    # Add to D the directed edges of T and set their weight to zero
    # This indicates that it costs nothing to use edges that were given.
    D = nx.reverse(TR).copy()

    nx.set_edge_attributes(D, name='weight', values=0)

    # The LCA of mu and mv in T is the shared ancestor of mu and mv that is
    # located farthest from the root.
    lca_gen = nx.tree_all_pairs_lowest_common_ancestor(
        TR, root=root, pairs=meta_to_wuv.keys())

    for (mu, mv), lca in lca_gen:
        w, uv = meta_to_wuv[(mu, mv)]
        if lca == mu:
            # If u is an ancestor of v in TR, then add edge u->v to D
            D.add_edge(lca, mv, weight=w, generator=uv)
        elif lca == mv:
            # If v is an ancestor of u in TR, then add edge v->u to D
            D.add_edge(lca, mu, weight=w, generator=uv)
        else:
            # If neither u nor v is a ancestor of the other in TR
            # let t = lca(TR, u, v) and add edges t->u and t->v
            # Track the original edge that GENERATED these edges.
            D.add_edge(lca, mu, weight=w, generator=uv)
            D.add_edge(lca, mv, weight=w, generator=uv)

    # Then compute a minimum rooted branching
    try:
        # Note the original edges must be directed towards to root for the
        # branching to give us a bridge-augmentation.
        A = _minimum_rooted_branching(D, root)
    except nx.NetworkXException:
        # If there is no branching then augmentation is not possible
        raise nx.NetworkXUnfeasible('no 2-edge-augmentation possible')

    # For each edge e, in the branching that did not belong to the directed
    # tree T, add the correponding edge that **GENERATED** it (this is not
    # necesarilly e itself!)

    # ensure the third case does not generate edges twice
    bridge_connectors = set()
    for mu, mv in A.edges():
        data = D.get_edge_data(mu, mv)
        if 'generator' in data:
            # Add the avail edge that generated the branching edge.
            edge = data['generator']
            bridge_connectors.add(edge)

    for edge in bridge_connectors:
        yield edge
Ejemplo n.º 5
0
def weighted_bridge_augmentation(G, avail, weight=None):
    """Finds an approximate min-weight 2-edge-augmentation of G.

    This is an implementation of the approximation algorithm detailed in [1]_.
    It chooses a set of edges from avail to add to G that renders it
    2-edge-connected if such a subset exists.  This is done by finding a
    minimum spanning arborescence of a specially constructed metagraph.

    Parameters
    ----------
    G : NetworkX graph
       An undirected graph.

    avail : set of 2 or 3 tuples.
        candidate edges (with optional weights) to choose from

    weight : string
        key to use to find weights if avail is a set of 3-tuples where the
        third item in each tuple is a dictionary.

    Yields
    ------
    edge : tuple
        Edges in the subset of avail chosen to bridge augment G.

    Notes
    -----
    Finding a weighted 2-edge-augmentation is NP-hard.
    Any edge not in ``avail`` is considered to have a weight of infinity.
    The approximation factor is 2 if ``G`` is connected and 3 if it is not.
    Runs in :math:`O(m + n log(n))` time

    References
    ----------
    .. [1] Khuller, Samir, and Ramakrishna Thurimella. (1993) Approximation
        algorithms for graph augmentation.
        http://www.sciencedirect.com/science/article/pii/S0196677483710102

    See Also
    --------
    :func:`bridge_augmentation`
    :func:`k_edge_augmentation`

    Example
    -------
    >>> G = nx.path_graph((1, 2, 3, 4))
    >>> # When the weights are equal, (1, 4) is the best
    >>> avail = [(1, 4, 1), (1, 3, 1), (2, 4, 1)]
    >>> sorted(weighted_bridge_augmentation(G, avail))
    [(1, 4)]
    >>> # Giving (1, 4) a high weight makes the two edge solution the best.
    >>> avail = [(1, 4, 1000), (1, 3, 1), (2, 4, 1)]
    >>> sorted(weighted_bridge_augmentation(G, avail))
    [(1, 3), (2, 4)]
    >>> #------
    >>> G = nx.path_graph((1, 2, 3, 4))
    >>> G.add_node(5)
    >>> avail = [(1, 5, 11), (2, 5, 10), (4, 3, 1), (4, 5, 1)]
    >>> sorted(weighted_bridge_augmentation(G, avail=avail))
    [(1, 5), (4, 5)]
    >>> avail = [(1, 5, 11), (2, 5, 10), (4, 3, 1), (4, 5, 51)]
    >>> sorted(weighted_bridge_augmentation(G, avail=avail))
    [(1, 5), (2, 5), (4, 5)]
    """

    if weight is None:
        weight = 'weight'

    # If input G is not connected the approximation factor increases to 3
    if not nx.is_connected(G):
        H = G.copy()
        connectors = list(one_edge_augmentation(H, avail=avail, weight=weight))
        H.add_edges_from(connectors)

        for edge in connectors:
            yield edge
    else:
        connectors = []
        H = G

    if len(avail) == 0:
        if nx.has_bridges(H):
            raise nx.NetworkXUnfeasible('no augmentation possible')

    avail_uv, avail_w = _unpack_available_edges(avail, weight=weight, G=H)

    # Collapse input into a metagraph. Meta nodes are bridge-ccs
    bridge_ccs = nx.connectivity.bridge_components(H)
    C = collapse(H, bridge_ccs)

    # Use the meta graph to shrink avail to a small feasible subset
    mapping = C.graph['mapping']
    # Choose the minimum weight feasible edge in each group
    meta_to_wuv = {
        (mu, mv): (w, uv)
        for (mu, mv), uv, w in _lightest_meta_edges(mapping, avail_uv, avail_w)
    }

    # Mapping of terms from (Khuller and Thurimella):
    #     C         : G_0 = (V, E^0)
    #        This is the metagraph where each node is a 2-edge-cc in G.
    #        The edges in C represent bridges in the original graph.
    #     (mu, mv)  : E - E^0  # they group both avail and given edges in E
    #     T         : \Gamma
    #     D         : G^D = (V, E_D)

    #     The paper uses ancestor because children point to parents, which is
    #     contrary to networkx standards.  So, we actually need to run
    #     nx.least_common_ancestor on the reversed Tree.

    # Pick an arbitrary leaf from C as the root
    root = next(n for n in C.nodes() if C.degree(n) == 1)
    # Root C into a tree TR by directing all edges away from the root
    # Note in their paper T directs edges towards the root
    TR = nx.dfs_tree(C, root)

    # Add to D the directed edges of T and set their weight to zero
    # This indicates that it costs nothing to use edges that were given.
    D = nx.reverse(TR).copy()

    nx.set_edge_attributes(D, name='weight', values=0)

    # The LCA of mu and mv in T is the shared ancestor of mu and mv that is
    # located farthest from the root.
    lca_gen = nx.tree_all_pairs_lowest_common_ancestor(
        TR, root=root, pairs=meta_to_wuv.keys())

    for (mu, mv), lca in lca_gen:
        w, uv = meta_to_wuv[(mu, mv)]
        if lca == mu:
            # If u is an ancestor of v in TR, then add edge u->v to D
            D.add_edge(lca, mv, weight=w, generator=uv)
        elif lca == mv:
            # If v is an ancestor of u in TR, then add edge v->u to D
            D.add_edge(lca, mu, weight=w, generator=uv)
        else:
            # If neither u nor v is a ancestor of the other in TR
            # let t = lca(TR, u, v) and add edges t->u and t->v
            # Track the original edge that GENERATED these edges.
            D.add_edge(lca, mu, weight=w, generator=uv)
            D.add_edge(lca, mv, weight=w, generator=uv)

    # Then compute a minimum rooted branching
    try:
        # Note the original edges must be directed towards to root for the
        # branching to give us a bridge-augmentation.
        A = _minimum_rooted_branching(D, root)
    except nx.NetworkXException:
        # If there is no branching then augmentation is not possible
        raise nx.NetworkXUnfeasible('no 2-edge-augmentation possible')

    # For each edge e, in the branching that did not belong to the directed
    # tree T, add the correponding edge that **GENERATED** it (this is not
    # necesarilly e itself!)

    # ensure the third case does not generate edges twice
    bridge_connectors = set()
    for mu, mv in A.edges():
        data = D.get_edge_data(mu, mv)
        if 'generator' in data:
            # Add the avail edge that generated the branching edge.
            edge = data['generator']
            bridge_connectors.add(edge)

    for edge in bridge_connectors:
        yield edge
Ejemplo n.º 6
0
def edgeConnectivity(G, layout):
    graphs = list()
    figures = list()
    graphData, bridges, articulationPoints = list(), list(), list()
    sortedEdges = sorted(dict(G.edges), key=lambda g: g[0])

    graphData.append('')
    graphData.append(nx.is_connected(G))
    if nx.has_bridges(G):
        graphData.append(nx.has_bridges(G))
        bridges.extend(nx.bridges(G))
        graphData.append(bridges)
        articulationPoints.extend(nx.articulation_points(G))
        graphData.append(articulationPoints)
    else:
        graphData.append(nx.has_bridges(G))
    graphs.append(graphData)

    sortedNodes = sorted(dict(G.nodes), key=lambda g: g[0])
    nodeColor = list()
    for n in sortedNodes:
        if n in list(articulationPoints):
            nodeColor.append("green")
        else:
            nodeColor.append("#1f78b4")

    edgeColor = list()
    for e in dict(G.edges):
        if e in list(bridges):
            edgeColor.append("#ff8000")
        else:
            edgeColor.append("black")

    figures.append(
        createFigure(G,
                     layout=layout,
                     sortedNodes=sortedNodes,
                     articulationPoints=articulationPoints,
                     bridges=bridges,
                     nodeColor=nodeColor,
                     edgeColor=edgeColor))

    for edge in sortedEdges:
        graphData, bridges, articulationPoints = list(), list(), list()
        newG = G.copy()
        newG.remove_edge(edge[0], edge[1])
        graphData.append(edge)
        graphData.append(nx.is_connected(newG))
        if nx.has_bridges(newG):
            graphData.append(nx.has_bridges(newG))
            bridges.extend(nx.bridges(newG))
            graphData.append(bridges)
            articulationPoints.extend(nx.articulation_points(newG))
            graphData.append(articulationPoints)
        else:
            graphData.append(nx.has_bridges(newG))
        graphs.append(graphData)

        sortedNodes = sorted(dict(G.nodes), key=lambda g: g[0])
        nodeColor = list()
        for n in sortedNodes:
            if n in list(articulationPoints):
                nodeColor.append("green")
            else:
                nodeColor.append("#1f78b4")

        edgeColor = list()
        for e in dict(G.edges):
            if e == edge:
                edgeColor.append("red")
            elif e in list(bridges):
                edgeColor.append("#ff8000")
            else:
                edgeColor.append("black")

        figures.append(
            createFigure(G,
                         layout=layout,
                         sortedNodes=sortedNodes,
                         removedEdge=edge,
                         articulationPoints=articulationPoints,
                         bridges=bridges,
                         nodeColor=nodeColor,
                         edgeColor=edgeColor))

    return graphs, figures
Ejemplo n.º 7
0
def kNodeAlgorithm(G, layout):
    # For k=3
    newG = G.copy()
    articulationPoints = list()
    newEndpoints = set()
    graphs, figures, nodes = list(), list(), list()
    figures.append(createFigure(
        G,
        layout=layout,
    ))
    graphs.append(G)
    nodes.append([])
    if nx.has_bridges(newG):
        articulationPoints.extend(nx.articulation_points(G))
        for point in nx.articulation_points(G):
            edges = newG.edges(point)
            for edge in edges:
                newEndpoints.add(edge[0] + "'")
                if edge[1] not in newEndpoints:
                    newG.add_edge(edge[0] + "'", edge[1])

            # for point in articulationPoints:
            #     newG.add_edge(point, point + 10)

    sortedNodes = sorted(dict(newG.nodes), key=lambda g: g[0])
    nodeColor = list()
    for n in sortedNodes:
        if n in newEndpoints:
            nodeColor.append("lightblue")
        elif n in articulationPoints:
            nodeColor.append("green")
        else:
            nodeColor.append("#1f78b4")

    graphs.append(newG.copy())
    nodes.append(list(newEndpoints))
    figures.append(
        createFigure(newG,
                     layout=layout,
                     sortedNodes=sortedNodes,
                     articulationPoints=articulationPoints,
                     nodeColor=nodeColor,
                     kAugmentedNodes=newEndpoints))
    """K=3"""
    criticalNodes = list()
    for node1 in dict(newG.nodes):
        loopG = newG.copy()
        loopG.remove_node(node1)
        for node2 in dict(loopG.nodes):
            loopG2 = loopG.copy()
            loopG2.remove_node(node2)
            if not nx.is_connected(loopG2):
                criticalNodes.append((node1, node2))
            newG.add_node(node2)
        newG.add_node(node1)

    loopG3 = newG.copy()
    usedNodes = set()
    for critNode in criticalNodes:
        edges1 = loopG3.edges(critNode[0])
        edges2 = loopG3.edges(critNode[1])
        edgeSet = set()
        for edge in edges1:
            edgeSet.add(edge)
        for edge in edges2:
            edgeSet.add(edge)
        for edge in edgeSet:
            if critNode[1] + critNode[0] not in usedNodes:
                newG.add_edge(critNode[0] + critNode[1], edge[1])
                usedNodes.add(critNode[0] + critNode[1])
    createFigure(newG, layout=layout)

    sortedNodes = sorted(dict(newG.nodes), key=lambda g: g[0])
    nodeColor = list()
    for n in sortedNodes:
        if n in usedNodes:
            nodeColor.append("lightblue")
        else:
            nodeColor.append("#1f78b4")

    edgeColor = list()
    usedEdges = list()
    for e in newG.edges:
        if e[1] in usedNodes:
            edgeColor.append("green")
            usedEdges.append(e)
        else:
            edgeColor.append("black")

    graphs.append(newG)
    nodes.append(list(usedNodes))
    figures.append(
        createFigure(newG,
                     layout=layout,
                     sortedNodes=sortedNodes,
                     nodeColor=nodeColor,
                     edgeColor=edgeColor,
                     kAugmentedNodes=usedNodes,
                     kAugmentedEdges=usedEdges))
    print(graphs, figures)
    return graphs, figures, nodes
Ejemplo n.º 8
0
def recursive_algorithmic_play(player_output, cutter_flag=True):
    '''
    this one will check all algorithmically approved moves in the step
        (according to our playing algorithms)
    
    what I need to change is the edges that are recursed into
        so, remove edges from the thing.
        also, run the trim function
    '''
    graph = player_output[0]
    drawn_name = str(hash(graph))
    draw(graph, drawn_name)
    # base case
    if player_output[1] == 'saver':
        # draw(graph, 'saver_' + str(hash(graph)))
        return (drawn_name, []), {'saver_wins': 1, 'cutter_wins': 0}
    if player_output[1] == 'cutter':
        # draw(graph, 'cutter_' + str(hash(graph)))
        return (drawn_name, []), {'saver_wins': 0, 'cutter_wins': 1}

    trim(graph)  # edit the graph in place to remove all extra nodes

    # recursive step
    # get all the result dicts in a list
    results = []
    recursive_step = []

    if cutter_flag:  # cutter move
        #TODO
        # get list of edges to try cutting
        move_list = []
        if ('A', 'B') in list(graph.edges()):
            move_list = [('A', 'B')]
        elif nx.has_bridges(nx.Graph(graph)):  # cut a bridge between A and B
            # get bridges from a simple graph (not implemented for multi)
            possible_bridges = list(nx.bridges(nx.Graph(graph)))
            # remove the ones that are parallel edges and thus not bridges
            for edge in possible_bridges:
                if (edge[0], edge[1], 1) not in list(graph.edges):
                    move_list.append((edge[0], edge[1], 0))
        elif False:  # TODO implement creation of long bridge test
            pass
        else:
            move_list = list(graph.edges)

        for edge in move_list:
            recursive_step.append(
                recursive_algorithmic_play(cut(graph, edge), False))

    else:  # saver move
        # get list of edges to try saving
        # list(graph.edges) is the list of edges in the graph
        move_list = []
        if ('A', 'B') in list(graph.edges()):  # winning move for saver
            move_list = [('A', 'B')]
        elif nx.has_bridges(nx.Graph(graph)):  # save a bridge between A and B
            # get bridges from a simple graph (not implemented for multi)
            possible_bridges = list(nx.bridges(nx.Graph(graph)))
            # remove the ones that are parallel edges
            for edge in possible_bridges:
                if (edge[0], edge[1], 1) not in list(graph.edges):
                    move_list.append((edge[0], edge[1], 0))
        else:
            move_list = list(graph.edges)

        for edge in move_list:
            # we don't want to remove A or B from the graph when contracting
            # so we make sure A, then B are at the beginning of the edge
            if edge[1] == 'B':
                edge = edge[1], edge[0]
            if edge[1] == 'A':
                edge = edge[1], edge[0]
            recursive_step.append(
                recursive_algorithmic_play(save(graph, edge), True))

    # we currently have recursive_step as a tuple as below

    # get the results for game winners
    results = [item[1] for item in recursive_step]
    # add them together
    output = {'saver_wins': 0, 'cutter_wins': 0}
    for result in results:
        output['saver_wins'] += result['saver_wins']
        output['cutter_wins'] += result['cutter_wins']

    lower_levels = [item[0] for item in recursive_step]

    # graph is the current graph's state
    # lower levels is a list of these tuples
    return (str(hash(graph)), lower_levels), output
Ejemplo n.º 9
0
 def calculate(graph):
     return nx.has_bridges(graph)
Ejemplo n.º 10
0
    df,
    "state1",
    "state2", ["ratio", "p", "h"],
    create_using=(nx.DiGraph if valid_comps else nx.Graph))
pos = nx.spring_layout(graph,
                       center=(0.5, 0.5),
                       scale=0.5,
                       k=1 / len(graph)**0.1,
                       seed=1)
# pos = nx.kamada_kawai_layout(graph, center=(0.5, 0.5), scale=0.5)

# Base edges
nx.draw_networkx_edges(graph, pos=pos, width=0.2)

# Bridges
if type(graph) is not nx.DiGraph and nx.has_bridges(graph):
    nx.draw_networkx_edges(graph,
                           edgelist=list(nx.bridges(graph)),
                           pos=pos,
                           width=3,
                           alpha=0.5,
                           edge_color="r")

# Nodes with colors
groups = list(asyn_lpa_communities(graph, weight="h"))
colors = [[state in com for com in groups].index(True) for state in graph]
nx.draw_networkx_nodes(graph, pos=pos, node_color=colors, cmap="tab20")

# Labels
nx.draw_networkx_labels(graph, pos, font_size=10)
Ejemplo n.º 11
0
def Analyze(G):
    GraphData['Has Bridges?'] = nx.has_bridges(G)
    addBridges(G)
    logtoFile()