Esempio n. 1
0
def exp_10():
  net = MinTTTLagrangianCTMProblem.load("/Users/jdr/Desktop/out.json")
  net.cache_props()
  print len(net.sources)
  print len(net.sinks)
  print len(net.all_routes())
  print len(net.get_links())
  # for route in net.all_routes():
  #   print net.max_flow(route), net.ff_travel_time(route)
  import networkx
  print networkx.is_weakly_connected(net)
  with open('/Users/jdr/Desktop/flowdata.csv','r') as fn:
    flows = {}
    for row in fn:
      splits = row[:-1].split(';')
      print splits
      name = splits[2]
      flow = float(splits[1])
      density = float(splits[0])
      flows[name] = {
        'flow': flow,
        'density': density
      }
  def get_flows(link):
    try:
      return flows[link.name]['flow']
    except:
      return 0.0
  for junction in net.junctions:
    lsum = sum(get_flows(link) for link in junction.in_links)
    rsum = sum(get_flows(link) for link in junction.out_links)
    print lsum, rsum
  for link in net.get_links():
    print bool(link.fd.q_max < get_flows(link)), link.fd.q_max, get_flows(link)
def subgraphs_product(G1, G2, length):
    assert length <= len(G1.nodes())
    assert length <= len(G2.nodes())

    a = it.combinations(G1.nodes(), length)
    b = it.combinations(G2.nodes(), length)
    gen = it.product(a, b)

    for pair in gen:
        sub1 = G1.subgraph(pair[0])
        sub2 = G2.subgraph(pair[1])
        if nx.is_weakly_connected(sub1) and nx.is_weakly_connected(sub2):
            yield (sub1, sub2)
Esempio n. 3
0
    def connected(self):
        """
        Test if the graph is connected.

        Return True if connected, False otherwise
        """
        return nx.is_weakly_connected(self.G)
Esempio n. 4
0
def gen_network(graph,machines,basedata):
    """ Generates an LLD network from a graph
        distributing participants in a list of machines
    """
    network = ET.Element('network')
    #network.set('type',graphtype)
    network.set('participants',str(graph.number_of_nodes()))
    network.set('edges',str(graph.size()))
    network.set('density',str(NX.density(graph)))

    network.set('connected',str(NX.is_weakly_connected(graph)))
    network.set('stronglyconnected',str(NX.is_strongly_connected(graph)))

    for node in graph.nodes_iter():
        nodelement = ET.SubElement(network,'participant')
        nodelement.set('id','participant'+str(node))
        hostelem = ET.SubElement(nodelement,'host')
        #hostelem.text = 'node'+str(int(node) % len(machines))
        hostelem.text = machines[int(node) % len(machines)]
        portelem = ET.SubElement(nodelement,'port')
        portelem.text = str(20500+int(node))
        baseelem = ET.SubElement(nodelement,'basedata')
        baseelem.text = basedata
        nodelement.append(gen_dynamic())
        for source in gen_sources(graph,node):
            nodelement.append(source)
    return network
def draw_graph(nodes, edges, graphs_dir, default_lang='all'):
    lang_graph = nx.MultiDiGraph()
    lang_graph.add_nodes_from(nodes)
    for edge in edges:
        if edges[edge] == 0:
            lang_graph.add_edge(edge[0], edge[1])
        else:
            lang_graph.add_edge(edge[0], edge[1], weight=float(edges[edge]), label=str(edges[edge]))

    # print graph info in stdout
    # degree centrality
    print('-----------------\n\n')
    print(default_lang)
    print(nx.info(lang_graph))
    try:
        # When ties are associated to some positive aspects such as friendship or collaboration,
        #  indegree is often interpreted as a form of popularity, and outdegree as gregariousness.
        DC = nx.degree_centrality(lang_graph)
        max_dc = max(DC.values())
        max_dc_list = [item for item in DC.items() if item[1] == max_dc]
    except ZeroDivisionError:
        max_dc_list = []
    # https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BF%D0%BB%D0%B5%D0%BA%D1%81%D0%BD%D1%8B%D0%B5_%D1%81%D0%B5%D1%82%D0%B8
    print('maxdc', str(max_dc_list), sep=': ')
    # assortativity coef
    AC = nx.degree_assortativity_coefficient(lang_graph)
    print('AC', str(AC), sep=': ')
    # connectivity
    print("Слабо-связный граф: ", nx.is_weakly_connected(lang_graph))
    print("количество слабосвязанных компонент: ", nx.number_weakly_connected_components(lang_graph))
    print("Сильно-связный граф: ", nx.is_strongly_connected(lang_graph))
    print("количество сильносвязанных компонент: ", nx.number_strongly_connected_components(lang_graph))
    print("рекурсивные? компоненты: ", nx.number_attracting_components(lang_graph))
    print("число вершинной связности: ", nx.node_connectivity(lang_graph))
    print("число рёберной связности: ", nx.edge_connectivity(lang_graph))
    # other info
    print("average degree connectivity: ", nx.average_degree_connectivity(lang_graph))
    print("average neighbor degree: ", sorted(nx.average_neighbor_degree(lang_graph).items(),
                                              key=itemgetter(1), reverse=True))
    # best for small graphs, and our graphs are pretty small
    print("pagerank: ", sorted(nx.pagerank_numpy(lang_graph).items(), key=itemgetter(1), reverse=True))

    plt.figure(figsize=(16.0, 9.0), dpi=80)
    plt.axis('off')
    pos = graphviz_layout(lang_graph)
    nx.draw_networkx_edges(lang_graph, pos, alpha=0.5, arrows=True)
    nx.draw_networkx(lang_graph, pos, node_size=1000, font_size=12, with_labels=True, node_color='green')
    nx.draw_networkx_edge_labels(lang_graph, pos, edges)

    # saving file to draw it with dot-graphviz
    # changing overall graph view, default is top-bottom
    lang_graph.graph['graph'] = {'rankdir': 'LR'}
    # marking with blue nodes with maximum degree centrality
    for max_dc_node in max_dc_list:
        lang_graph.node[max_dc_node[0]]['fontcolor'] = 'blue'
    write_dot(lang_graph, os.path.join(graphs_dir, default_lang + '_links.dot'))

    # plt.show()
    plt.savefig(os.path.join(graphs_dir, 'python_' + default_lang + '_graph.png'), dpi=100)
    plt.close()
Esempio n. 6
0
def evaluate(graph):
    """evaluate(Graph) -> None

    :class:`Graph` -> IO ()

    Starting from the root node, evaluate the branches.
    The graph nodes are updated in-place.

    Example:

    >>> @delayed()
    ... def foo(a):
    ...   return a
    >>> node = foo(42) & foo(24)
    >>> print evaluate(node.graph)
    None
    >>> for _, data in node.graph.nodes(data=True):
    ...   n = data['node']
    ...   print n.name, n.result.result()
    & None
    foo 42
    foo 24
    """

    assert nx.is_weakly_connected(graph)
    node = find_root_node(graph)
    node.eval()
Esempio n. 7
0
def average_shortest_path_length(G, weight=None):
    r"""Return the average shortest path length.

    The average shortest path length is

    .. math::

       a =\sum_{s,t \in V} \frac{d(s, t)}{n(n-1)}

    where `V` is the set of nodes in `G`,
    `d(s, t)` is the shortest path from `s` to `t`,
    and `n` is the number of nodes in `G`.

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

    weight : None or string, optional (default = None)
       If None, every edge has weight/distance/cost 1.
       If a string, use this edge attribute as the edge weight.
       Any edge attribute not present defaults to 1.

    Raises
    ------
    NetworkXError:
       if the graph is not connected.

    Examples
    --------
    >>> G=nx.path_graph(5)
    >>> print(nx.average_shortest_path_length(G))
    2.0

    For disconnected graphs you can compute the average shortest path
    length for each component:
    >>> G=nx.Graph([(1,2),(3,4)])
    >>> for g in nx.connected_component_subgraphs(G):
    ...     print(nx.average_shortest_path_length(g))
    1.0
    1.0

    """
    if G.is_directed():
        if not nx.is_weakly_connected(G):
            raise nx.NetworkXError("Graph is not connected.")
    else:
        if not nx.is_connected(G):
            raise nx.NetworkXError("Graph is not connected.")
    avg=0.0
    if weight is None:
        for node in G:
            path_length=nx.single_source_shortest_path_length(G, node)
            avg += sum(path_length.values())
    else:
        for node in G:
            path_length=nx.single_source_dijkstra_path_length(G, node, weight=weight)
            avg += sum(path_length.values())
    n=len(G)
    return avg/(n*(n-1))
Esempio n. 8
0
 def is_connected(self):
     """
     Return True if the Xmrs represents a connected graph.
     Subgraphs can be connected through things like arguments,
     QEQs, and label equalities.
     """
     try:
         return nx.is_weakly_connected(self._graph)
     except nx.exception.NetworkXPointlessConcept:
         raise XmrsError("Connectivity is undefined for an empty Xmrs.")
Esempio n. 9
0
def random_connected_graph(numNodes, numEdges):
    '''Generates a weakly connected random graph with numNodes nodes
       and numEdges edges
    '''
    tries = 0
    while tries < 100:
        tries += 1
        random_graph = nx.gnm_random_graph(numNodes,numEdges,directed = True)
        if nx.is_weakly_connected(random_graph): 
            return random_graph
    return None
Esempio n. 10
0
    def _infer_all_ratios(self, ratios):
        def compute_path_attribs(path, G, attribs):
            ret = {attr: 1.0 for attr in attribs}
            if len(path) > 1:
                for i in range(len(path) - 1):
                    for attr in attribs:
                        ret[attr] *= G[path[i]][path[i + 1]][attr]

            return ret

        G = nx.convert_matrix.from_pandas_edgelist(
            ratios,
            'v1',
            'v2',
            edge_attr=['weight', "ratio", "ratio_hi", "ratio_lo", 'error'],
            create_using=nx.DiGraph)

        assert len(G.edges()) % 2 == 0

        # strongly?
        if not nx.is_strongly_connected(G) or not nx.is_weakly_connected(
                G) or nx.number_connected_components(nx.Graph(G)) > 1:
            for comp in nx.connected_components(nx.Graph(G)):
                self._print_and_log(
                    f"Component with length {len(comp)}: {str(comp)}")
                self._error_flag = True

            self._print_and_log(
                f"Num. connected components: {nx.number_strongly_connected_components(G)}. "
                f"Directed graph is not strongly connected!")
            warnings.warn("Directed graph is not connected!")

            # ratios.to_csv("ratios_test.tsv", sep = '\t')

        paths = list(nx.all_pairs_dijkstra_path(G))
        self.paths = paths
        node_names = [el[0] for el in paths]
        W = pd.DataFrame(columns=node_names, index=node_names, dtype=float)
        W_lo = pd.DataFrame(columns=node_names, index=node_names, dtype=float)
        W_hi = pd.DataFrame(columns=node_names, index=node_names, dtype=float)

        self._print_and_log("Finding paths...")
        for p_obj in tqdm(paths):
            for p in p_obj[1].values():
                path_attrib_dict = compute_path_attribs(
                    p, G, ['weight', "ratio", "ratio_hi", "ratio_lo", 'error'])
                v1 = p[0]
                v2 = p[-1]
                W.loc[v1][v2] = path_attrib_dict['ratio']
                W_lo.loc[v1][v2] = path_attrib_dict['ratio_lo']
                W_hi.loc[v1][v2] = path_attrib_dict['ratio_hi']
        self._print_and_log("Paths done!")

        return W, W_lo, W_hi
Esempio n. 11
0
def answer_three():

    file = 'email_network.txt'
    G = nx.read_edgelist(file,
                         delimiter='\t',
                         data=[('time', int)],
                         create_using=nx.DiGraph())
    part1 = nx.is_strongly_connected(G)
    part2 = nx.is_weakly_connected(G)

    return (part1, part2)
def output_conectivity_info (graph, path):
    """Output connectivity information about the graph.
       graph : (networkx.Graph)
       path: (String) contains the path to the output file
    """
    with open(path, 'w') as out:
        out.write('***Conectivity***\n')
        out.write('Is weakly connected: %s\n' % nx.is_weakly_connected(graph))
        out.write('Number of weakly connected components: %d\n' % nx.number_weakly_connected_components(graph))
        out.write('Is strongly connected: %s\n' % nx.is_strongly_connected(graph))
        out.write('Number of strongly connected components: %d' % nx.number_strongly_connected_components(graph))
Esempio n. 13
0
 def _get_subgraphs(self, graph, name, size=3):
     subgraphs = set()
     # print "\nSubgraphs START: " + name
     target = nx.complete_graph(size)
     for sub_nodes in itertools.combinations(graph.nodes(),len(target.nodes())):
         subg = graph.subgraph(sub_nodes)
         if nx.is_weakly_connected(subg):
             # print subg.edges()
             subgraphs.add(subg)
     # print "Subgraphs END \n"
     return subgraphs
Esempio n. 14
0
 def _get_subgraphs(self, graph, name, size=3):
     subgraphs = set()
     # print "\nSubgraphs START: " + name
     target = nx.complete_graph(size)
     for sub_nodes in itertools.combinations(graph.nodes(),
                                             len(target.nodes())):
         subg = graph.subgraph(sub_nodes)
         if nx.is_weakly_connected(subg):
             # print subg.edges()
             subgraphs.add(subg)
     # print "Subgraphs END \n"
     return subgraphs
Esempio n. 15
0
    def set_domain(clz, dag):
        """ Sets the domain.  Should only be called once per class instantiation. """
        logging.info("Setting domain for poset %s" % clz.__name__)
        if nx.number_of_nodes(dag) == 0:
            raise CellConstructionFailure("Empty DAG structure.")
            
        if not nx.is_directed_acyclic_graph(dag):
            raise CellConstructionFailure("Must be directed and acyclic")

        if not nx.is_weakly_connected(dag):
            raise CellConstructionFailure("Must be connected")
        clz.domain_map[clz] = dag
Esempio n. 16
0
    def rooted_core_interface_pairs(self, root, thickness=None,  for_base=False,
                                        hash_bitmask=None,
                                      radius_list=[],
                                      thickness_list=None,
                                      node_filter=lambda x, y: True):
        """

        Parameters
        ----------
        root:
        thickness:
        args:

        Returns
        -------

        """

        ciplist = super(self.__class__, self).rooted_core_interface_pairs(root, thickness, for_base=for_base,
                                        hash_bitmask=hash_bitmask,
                                      radius_list=radius_list,
                                      thickness_list=thickness_list,
                                      node_filter=node_filter)



        # numbering shards if cip graphs not connected
        for cip in ciplist:
            if not nx.is_weakly_connected(cip.graph):
                comps = [list(node_list) for node_list in nx.weakly_connected_components(cip.graph)]
                comps.sort()

                for i, nodes in enumerate(comps):

                    for node in nodes:
                        cip.graph.node[node]['shard'] = i

        '''
        solve problem of single-ede-nodes in the core
        this may replace the need for fix_structure thing
        this is a little hard.. may fix later

        it isnt hard if i write this code in merge_core in ubergraphlearn

        for cip in ciplist:
            for n,d in cip.graph.nodes(data=True):
                if 'edge' in d and 'interface' not in d:
                    if 'interface' in cip.graph.node[ cip.graph.successors(n)[0]]:
                        #problem found
        '''

        return ciplist
Esempio n. 17
0
def check_weakly_connected(series):
    series = series[1]
    tmp_df = series.reset_index()
    tmp_df['sign'] = series.values
    delete_edges = tmp_df[tmp_df['sign'] == 0]
    dg = nx.from_pandas_dataframe(tmp_df,
                                  source='source',
                                  target='target',
                                  edge_attr=['sign'],
                                  create_using=nx.DiGraph())
    dg.remove_edges_from(delete_edges.edge.values.tolist())

    return nx.is_weakly_connected(dg)
Esempio n. 18
0
def check_connection(Graph):
    if nx.is_directed(Graph):
        try:
            is_connected = nx.is_weakly_connected(Graph)
        except (ValueError, RuntimeError, TypeError, NameError):
            pass
    else:
        try:
            is_connected = nx.is_connected(Graph)
        except (ValueError, RuntimeError, TypeError, NameError):
            pass

    return is_connected
Esempio n. 19
0
def random_generator(n: int, k: int, alpha: int, graph_version: int):
    """
    Generates a random connected graph with all the node attributes set to 3 and the edge weights to 1
    :param graph_version: file version
    :param alpha:
    :param n: number of nodes
    :param k:
    :return:
    """
    # Generate an almost complete graph
    graph = nx.DiGraph(
        nx.MultiDiGraph.to_directed(
            nx.random_k_out_graph(n, k, self_loops=False, alpha=alpha)))

    # # Delete incoming arcs from 0 -> starting node
    # graph.remove_edges_from([(v1, v2) for (v1, v2) in graph.in_edges if v2 is 0])

    # Connect the first and the last node
    graph.add_edges_from([(0, max(graph.nodes))])

    print(len(graph.edges))
    for node in graph.nodes:
        incoming = [(v1, v2) for (v1, v2) in graph.in_edges if v2 == node]
        deleted_nodes = 0
        # Randomly decide if an edge has to be kept or discarded
        for edge in incoming:
            keep = np.average(rnd.binomial(1, 0.55, 5))
            # Delete only if the nodes has more than one incoming and outcoming edge
            if keep >= 0.4 and deleted_nodes < len(incoming) - 1 and len(
                    graph.edges(edge[0])) > 1:
                graph.remove_edge(edge[0], edge[1])
                deleted_nodes = deleted_nodes + 1

    # Delete node cycles in order to save the graph as strict. Otherwise the graph is by default a multi-weight graph
    node_cycles = [(u, v) for (u, v) in graph.edges() if u in graph[v]]
    graph.remove_edges_from(node_cycles)

    # Connect every arc to the first one
    graph.add_edges_from([(node, 0) for node in graph.nodes if node is not 0])
    # Set the attributes
    nx.set_node_attributes(graph, 3, 'component_delay')
    nx.set_edge_attributes(graph, 1, 'wire_delay')
    # Save it only if it is connected
    if nx.is_weakly_connected(graph):
        nx.nx_agraph.write_dot(
            graph,
            os.getcwd() + '/../rand-graphs/clean/{}/rand-{}-{}.dot'.format(
                n, n, graph_version))
        return True
    else:
        return False
Esempio n. 20
0
def answer_three():
    df = pd.read_csv("email_network.txt",
                     delimiter="\t",
                     header=0,
                     dtype={
                         "#Sender": "str",
                         "Recipient": "str"
                     })
    directed = nx.from_pandas_dataframe(df,
                                        "#Sender",
                                        "Recipient",
                                        create_using=nx.MultiDiGraph())
    return (len(sorted(nx.strongly_connected_components(directed))) == 1
            ), nx.is_weakly_connected(directed)
Esempio n. 21
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))
def output_conectivity_info(graph, path):
    """Output connectivity information about the graph.
       graph : (networkx.Graph)
       path: (String) contains the path to the output file
    """
    with open(path, 'w') as out:
        out.write('***Conectivity***\n')
        out.write('Is weakly connected: %s\n' % nx.is_weakly_connected(graph))
        out.write('Number of weakly connected components: %d\n' %
                  nx.number_weakly_connected_components(graph))
        out.write('Is strongly connected: %s\n' %
                  nx.is_strongly_connected(graph))
        out.write('Number of strongly connected components: %d' %
                  nx.number_strongly_connected_components(graph))
Esempio n. 23
0
def get_subgraphs(graph):
    """
        extract subgraphs from a given annot
    """
    nodes_powerset = get_nodes_combinations(graph)
    #print("Doing")
    #draw_graph(graph)
    subgraphs = []
    for nodes in nodes_powerset:
        subg = graph.subgraph(nodes)
        nodes = subg.nodes(data=True)
        if nx.is_weakly_connected(subg):
            subgraphs.append(subg)
    return subgraphs
def is_semiconnected(G):
    """Returns 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))
Esempio n. 25
0
def answer_three():
        
    # Your Code Here
    '''
    nodes = answer_one().nodes()
    edges = answer_one().edges()
    starts = set(sorted([i[0] for i in edges]))
    ends = set(sorted([i[1] for i in edges]))
    print(set(sorted(nodes)).issubset(starts))
    print(set(sorted(nodes)).issubset(starts.union(ends)))
    print(nx.is_strongly_connected(answer_one()))
    print(nx.is_weakly_connected(answer_one()))
    '''
    return (nx.is_strongly_connected(answer_one()),nx.is_weakly_connected(answer_one()))# Your Answer Here
    def purify_graph(self):
        coverages = get_coverage(self.graph)
        first_edge = None
        for (edge, e_cov) in sorted(coverages.items(),
                                    key=lambda x: (-x[1], x[0])):
            if self.graph.out_degree(edge[0]) == 1 \
                    and self.graph.in_degree(edge[1]) == 1:
                first_edge = edge
                break

        first_edge_properties = self.graph.edges[first_edge]
        self.graph.remove_edge(*first_edge)

        while True:
            coverages = get_coverage(self.graph)
            edge2remove = None
            for (edge, e_cov) in sorted(coverages.items(),
                                        key=lambda x: (x[1], x[0])):
                gr = self.graph.copy()
                gr.remove_edge(*edge)
                if nx.is_weakly_connected(gr):
                    edge2remove = edge
                    break

            if edge2remove is not None:
                self.graph.remove_edge(*edge2remove)
                assert nx.is_weakly_connected(self.graph)
                self.graph.remove_nodes_from(list(nx.isolates(self.graph)))
                assert nx.is_weakly_connected(self.graph)
                self.collapse_nonbranching_paths(respect_color=False)
                assert nx.is_weakly_connected(self.graph)
            else:
                break

        self.graph.add_edge(*first_edge, **first_edge_properties)
        self.remove_tips()
        self.collapse_nonbranching_paths(respect_color=False)
Esempio n. 27
0
def get_largest_component(G, strongly=False):
    """
    Return the largest weakly or strongly connected component from a directed
    graph.

    Parameters
    ----------
    G : networkx multidigraph
    strongly : bool
        if True, return the largest strongly instead of weakly connected
        component

    Returns
    -------
    networkx multidigraph
    """

    start_time = time.time()
    original_len = len(list(G.nodes()))

    if strongly:
        # if the graph is not connected and caller did not request retain_all,
        # retain only the largest strongly connected component
        if not nx.is_strongly_connected(G):
            G = max(nx.strongly_connected_component_subgraphs(G), key=len)
            msg = (
                'Graph was not connected, retained only the largest strongly '
                'connected component ({:,} of {:,} total nodes) in {:.2f} seconds'
            )
            log(
                msg.format(len(list(G.nodes())), original_len,
                           time.time() - start_time))
    else:
        # if the graph is not connected and caller did not request retain_all,
        # retain only the largest weakly connected component
        if not nx.is_weakly_connected(G):
            subgraphs = [
                G.subgraph(c).copy() for c in nx.weakly_connected_components(G)
            ]
            G = max(subgraphs, key=len)
            msg = (
                'Graph was not connected, retained only the largest weakly '
                'connected component ({:,} of {:,} total nodes) in {:.2f} seconds'
            )
            log(
                msg.format(len(list(G.nodes())), original_len,
                           time.time() - start_time))

    return G
Esempio n. 28
0
def get_largest_component(G, strongly=False):
    """
    Get subgraph of MultiDiGraph's largest weakly/strongly connected component.

    Parameters
    ----------
    G : networkx.MultiDiGraph
        input graph
    strongly : bool
        if True, return the largest strongly instead of weakly connected
        component

    Returns
    -------
    G : networkx.MultiDiGraph
        the largest connected component subgraph from the original graph
    """
    original_len = len(list(G.nodes()))

    if strongly:
        # if the graph is not connected retain only the largest strongly connected component
        if not nx.is_strongly_connected(G):

            # get all the strongly connected components in graph then identify the largest
            sccs = nx.strongly_connected_components(G)
            largest_scc = max(sccs, key=len)
            G = induce_subgraph(G, largest_scc)

            msg = (
                f"Graph was not connected, retained only the largest strongly "
                f"connected component ({len(G)} of {original_len} total nodes)"
            )
            utils.log(msg)
    else:
        # if the graph is not connected retain only the largest weakly connected component
        if not nx.is_weakly_connected(G):

            # get all the weakly connected components in graph then identify the largest
            wccs = nx.weakly_connected_components(G)
            largest_wcc = max(wccs, key=len)
            G = induce_subgraph(G, largest_wcc)

            msg = (
                f"Graph was not connected, retained only the largest weakly "
                f"connected component ({len(G)} of {original_len} total nodes)"
            )
            utils.log(msg)

    return G
Esempio n. 29
0
def is_fully_connected(graph):
    r"""
    Checks whether the input graph is fully connected in the undirected case
    or weakly connected in the directed case.

    Connected means one can get from any vertex :math:`u` to vertex :math:`v` by traversing
    the graph. For a directed graph, weakly connected means that the graph
    is connected after it is converted to an unweighted graph (ignore the
    direction of each edge)

    Parameters
    ----------
    graph: nx.Graph, nx.DiGraph, nx.MultiDiGraph, nx.MultiGraph,
        scipy.sparse.csr_matrix, np.ndarray
        Input graph in any of the above specified formats. If np.ndarray,
        interpreted as an :math:`n \times n` adjacency matrix

    Returns
    -------
    boolean: True if the entire input graph is connected

    References
    ----------
    http://mathworld.wolfram.com/ConnectedGraph.html
    http://mathworld.wolfram.com/WeaklyConnectedDigraph.html

    Examples
    --------
    >>> a = np.array([
    ...    [0, 1, 0],
    ...    [1, 0, 0],
    ...    [0, 0, 0]])
    >>> is_fully_connected(a)
    False
    """

    if isinstance(graph, (np.ndarray, csr_matrix)):
        directed = not is_symmetric(graph)

        n_components = connected_components(
            csgraph=graph, directed=directed, connection="weak", return_labels=False
        )
        return n_components == 1

    else:
        if type(graph) in [nx.Graph, nx.MultiGraph]:
            return nx.is_connected(graph)
        elif type(graph) in [nx.DiGraph, nx.MultiDiGraph]:
            return nx.is_weakly_connected(graph)
Esempio n. 30
0
    def MSCG(self, G, E_neg):

        Q = sorted(E_neg, key=operator.itemgetter(1), reverse=True)
        num_weakly_connected = nx.number_weakly_connected_components(G)

        while len(Q) > 0 and not nx.is_weakly_connected(G):

            try:
                candidate_edge, candidate_score = Q.pop(0)
            except IndexError:
                break

            head, tail, label = candidate_edge
            if tail in G[head] or head in G[tail]:
                continue

            G.add_edge(*candidate_edge)
            new_num_weakly_connected = nx.number_weakly_connected_components(G)
            if new_num_weakly_connected < num_weakly_connected:
                num_weakly_connected = new_num_weakly_connected
            else:
                G.remove_edge(*candidate_edge[:2])

        assert nx.is_weakly_connected(G)
def answer_three():

    # Your Code Here

    # initialise the graph
    G = answer_one()

    # check if the graph is strongly connected to answer part 1
    strongly_connected_status = nx.is_strongly_connected(G)

    # check if the graph is weakly connected to answer part 2
    weakly_connected_status = nx.is_weakly_connected(G)

    return (strongly_connected_status, weakly_connected_status
            )  # Your Answer Here
Esempio n. 32
0
def is_connected(graph, kwargs={}):
    '''
    Checks if a network has a sequence of edges from each node to every other node regardless of edge direction.
    This is weak connectivity in a directed graph.
    :param graph: A dsgrn_net_gen.graphtranslation object
    :param kwargs: empty dictionary, here for API compliance
    :return: (True, "") or (False, error message), True if satisfied
    '''
    G = nx.DiGraph()
    G.add_edges_from(graph.edges())
    G.add_nodes_from(graph.vertices())
    if G and nx.is_weakly_connected(G):
        return True, ""
    else:
        return False, "Not connected"
Esempio n. 33
0
def IsRootedTree(digraph):
    if len(digraph.edges) != len(
            digraph.nodes) - 1 or not nx.is_weakly_connected(digraph):
        return False
    rootFound = False
    root = False
    for node in digraph:
        if digraph.in_degree(node) == 0:
            if rootFound:
                return False
            rootFound = True
            root = node
        if digraph.in_degree(node) > 1:
            return False
    return root
Esempio n. 34
0
def generate_triads_1(network):
	"""
	Generate triads by making all node combinations, filtering < 2 edges. 
	Not suitable for large graphs. 

	"""
	nodes = network.nodes()
	node_combos = list(itertools.combinations(nodes, 3))
	triads = []

	for combo in node_combos:
		sub_graph = network.subgraph(combo)
		if nx.is_weakly_connected(sub_graph):
			triads.append(sub_graph)
	return triads
Esempio n. 35
0
    def satisfies(self, graph):
        """
        This constraint is only satisfied if the provided graph as is weakly
        connected.

        :param graph: a graph to test
        :type graph: nx.DiGraph
        :returns: ``True`` if the digraph as the desired number of external
                  nodes
        """
        if super().satisfies(graph):
            try:
                return nx.is_weakly_connected(graph)
            except nx.exception.NetworkXException as err:
                raise ConstraintError() from err
Esempio n. 36
0
def get_largest_component(G, strongly=False, verbose=False):
    """
    https://github.com/gboeing/osmnx/blob/master/osmnx/utils.py
    Return a subgraph of the largest weakly or strongly connected component
    from a directed graph.
    Parameters
    ----------
    G : networkx multidigraph
    strongly : bool
        if True, return the largest strongly instead of weakly connected
        component
    Returns
    -------
    G : networkx multidigraph
        the largest connected component subgraph from the original graph
    """

    start_time = time.time()
    original_len = len(list(G.nodes()))

    if strongly:
        # if the graph is not connected retain only the largest strongly connected component
        if not nx.is_strongly_connected(G):

            # get all the strongly connected components in graph then identify the largest
            sccs = nx.strongly_connected_components(G)
            largest_scc = max(sccs, key=len)
            G = induce_subgraph(G, largest_scc)

            msg = ('Graph was not connected, retained only the largest strongly '
                   'connected component ({:,} of {:,} total nodes) in {:.2f} seconds')
            if verbose:
                print(msg.format(len(list(G.nodes())), original_len, time.time()-start_time))
    else:
        # if the graph is not connected retain only the largest weakly connected component
        if not nx.is_weakly_connected(G):

            # get all the weakly connected components in graph then identify the largest
            wccs = nx.weakly_connected_components(G)
            largest_wcc = max(wccs, key=len)
            G = induce_subgraph(G, largest_wcc)

            msg = ('Graph was not connected, retained only the largest weakly '
                   'connected component ({:,} of {:,} total nodes) in {:.2f} seconds')
            if verbose:
                print(msg.format(len(list(G.nodes())), original_len, time.time()-start_time))

    return G
Esempio n. 37
0
def random_dag(n, p=0.5, weakly_connected=True):
    """Return a random directed acyclic graph (DAG) with a n nodes and
    p(edges)."""

    adj_matrix = numpy.tril(numpy.random.binomial(1, p, size=(n, n)), -1)
    G = networkx.from_numpy_array(adj_matrix, create_using=PrecedenceGraph())

    if weakly_connected and not networkx.is_weakly_connected(G):
        for g in networkx.weakly_connected_component_subgraphs(G.copy()):
            nodes = list(networkx.topological_sort(g))
            G.add_edge('start', nodes[0])
            G.add_edge(nodes[-1], 'stop')

    assert (networkx.is_directed_acyclic_graph(G))

    return G
Esempio n. 38
0
    def compute_measures(self):
        """obtain measures"""
        #degrees = self.network.degree()
        degree_distr = dict(self.network.degree()).values()
        in_degree_distr = dict(self.network.in_degree()).values()
        out_degree_distr = dict(self.network.out_degree()).values()
        is_connected = nx.is_weakly_connected(self.network)
        #is_connected = nx.is_strongly_connected(self.network)  # must always be False
        try:
            node_centralities = nx.eigenvector_centrality(self.network)
        except:
            node_centralities = nx.betweenness_centrality(self.network)
        # TODO: and more, choose more meaningful ones...

        print("Graph is connected: ", is_connected, "\nIn degrees ", in_degree_distr, "\nOut degrees", out_degree_distr, \
              "\nCentralities", node_centralities)
Esempio n. 39
0
    def filter_molecules(molecules, connectivity=True, isomorphism=True):
        """
        Filter out molecules that are not connected and molecules with the same
        isomorphism (keep the lowest energy).

        Args:
            molecules (list of MoleculeWrapper): molecules
            connectivity (bool): whether to filter on connectivity
            isomorphism (bool): if `True`, filter on `charge`, `spin`, and `isomorphism`.
                The one with the lowest free energy will remain.

        Returns:
            A list of MoleculeWrapper objects.
        """
        n_unconnected_mol = 0
        n_not_unique_mol = 0

        filtered = []
        for i, m in enumerate(molecules):

            # check on connectivity
            if connectivity and not nx.is_weakly_connected(m.graph):
                n_unconnected_mol += 1
                continue

            # check for isomorphism
            if isomorphism:
                idx = -1
                for i_p_m, p_m in enumerate(filtered):
                    if (m.charge == p_m.charge
                            and m.spin_multiplicity == p_m.spin_multiplicity
                            and m.mol_graph.isomorphic_to(p_m.mol_graph)):
                        n_not_unique_mol += 1
                        idx = i_p_m
                        break
                if idx >= 0:
                    if m.free_energy < filtered[idx].free_energy:
                        filtered[idx] = m
                else:
                    filtered.append(m)

        logger.info(
            "Num molecules: {}; unconnected: {}; isomorphic: {}; remaining: {}"
            .format(len(molecules), n_unconnected_mol, n_not_unique_mol,
                    len(filtered)))

        return filtered
Esempio n. 40
0
def get_largest_component(G, strongly=False):
    """
    Return a subgraph of the largest weakly or strongly connected component
    from a directed graph.

    Parameters
    ----------
    G : networkx multidigraph
    strongly : bool
        if True, return the largest strongly instead of weakly connected
        component

    Returns
    -------
    G : networkx multidigraph
        the largest connected component subgraph from the original graph
    """

    start_time = time.time()
    original_len = len(list(G.nodes()))

    if strongly:
        # if the graph is not connected retain only the largest strongly connected component
        if not nx.is_strongly_connected(G):
            
            # get all the strongly connected components in graph then identify the largest
            sccs = nx.strongly_connected_components(G)
            largest_scc = max(sccs, key=len)
            G = induce_subgraph(G, largest_scc)
            
            msg = ('Graph was not connected, retained only the largest strongly '
                   'connected component ({:,} of {:,} total nodes) in {:.2f} seconds')
            log(msg.format(len(list(G.nodes())), original_len, time.time()-start_time))
    else:
        # if the graph is not connected retain only the largest weakly connected component
        if not nx.is_weakly_connected(G):
            
            # get all the weakly connected components in graph then identify the largest
            wccs = nx.weakly_connected_components(G)
            largest_wcc = max(wccs, key=len)
            G = induce_subgraph(G, largest_wcc)
            
            msg = ('Graph was not connected, retained only the largest weakly '
                   'connected component ({:,} of {:,} total nodes) in {:.2f} seconds')
            log(msg.format(len(list(G.nodes())), original_len, time.time()-start_time))

    return G
Esempio n. 41
0
def all_kgraphs_naive(V, K):
    graphlist = []
    kp = K + 1
    # This generates the set of all nonparallel kgraphs by generating the set of all numbers from 0 to
    # (K+1)^(V^2)
    #for each edge, it either
    for i in range(((kp)**(V * V))):
        # print "---"
        # print "i = {0}".format(i)
        # The algorithm used is actually the same to convert an integer into a (V^2) digit base-K number
        # pretty cool, huh?
        # clones i
        j = i
        # resets index
        index = 0
        # digit is the array of digits holding our graph info
        digit = [0] * (V * V)
        # print "j = {0}".format(j)
        while (j != 0):
            remainder = j % (kp)  # assume K > 1
            j = j / (kp)  #integer division
            digit[index] = remainder
            index += 1
        G = new_kgraph(V, K)
        #for every edge
        print digit
        for m in range(V):

            # print m
            for n in range(V):
                # print n
                #gets the index of the edge
                index = (m * V) + n
                # if the set digit is zero, do not add the edge
                # print "{0} {1}".format(index,digit[index])
                if (digit[index] != 0):

                    #otherwise, add the edge according to stored
                    G.add_edge(string.ascii_lowercase[m],
                               string.ascii_lowercase[n],
                               k=digit[index])
        if not nx.is_weakly_connected(G):
            continue
        if not quick_invalid(G):
            continue
        graphlist.append(G)
    return graphlist
 def test_build_worlds(self):
     n = 6
     G = nx.grid_2d_graph(n, n, create_using=nx.DiGraph())
     for n in G.nodes():
         G.nodes[n]['coords'] = (n[0], n[1])
     G = nx.convert_node_labels_to_integers(G)
     superworld = SplitSolver.build_superworld(G, 4)
     assert len(superworld) == 4
     for n in superworld.nodes(data=True):
         assert abs(len(n[1]['nodes']) - 9) <= 3  # might not be equal
         for n2 in n[1]['nodes']:
             assert G.has_node(n2)
         assert nx.is_weakly_connected(G.subgraph(n[1]['nodes']))
     assert superworld.number_of_edges() >= 4
     # might be greater than 8, because splitting might not be exactly square-based (due to hilbert approximation)
     for n in G.nodes(data=True):
         assert 'supernode' in n[1]
Esempio n. 43
0
def feature(node, edge):
    G = nx.MultiGraph()
    G = G.to_directed()
    G.add_nodes_from(node)
    G.add_edges_from(edge)
    f = np.zeros(10)
    f[0] = len(G.nodes)
    f[1] = len(G.edges)
    f[2] = nx.density(G)
    f[3] = nx.degree_pearson_correlation_coefficient(G)
    f[4] = nx.algorithms.reciprocity(G)
    f[5] = 0  #nx.transitivity(G)
    f[6] = nx.is_weakly_connected(G)
    f[7] = nx.number_weakly_connected_components(G)
    f[8] = nx.is_strongly_connected(G)
    f[9] = nx.number_strongly_connected_components(G)
    return f
Esempio n. 44
0
def has_eulerian_path(G):
    """Return True iff `G` has an Eulerian path.

    An Eulerian path is a path in a graph which uses each edge of a graph
    exactly once.

    A directed graph has an Eulerian path iff:
        - at most one vertex has out_degree - in_degree = 1,
        - at most one vertex has in_degree - out_degree = 1,
        - every other vertex has equal in_degree and out_degree,
        - and all of its vertices with nonzero degree belong to a
        - single connected component of the underlying undirected graph.

    An undirected graph has an Eulerian path iff:
        - exactly zero or two vertices have odd degree,
        - and all of its vertices with nonzero degree belong to a
        - single connected component.

    Parameters
    ----------
    G : NetworkX Graph
        The graph to find an euler path in.

    Returns
    -------
    Bool : True if G has an eulerian path.

    See Also
    --------
    is_eulerian
    eulerian_path
    """
    if G.is_directed():
        ins = G.in_degree
        outs = G.out_degree
        semibalanced_ins = sum(ins(v) - outs(v) == 1 for v in G)
        semibalanced_outs = sum(outs(v) - ins(v) == 1 for v in G)
        return (
            semibalanced_ins <= 1
            and semibalanced_outs <= 1
            and sum(G.in_degree(v) != G.out_degree(v) for v in G) <= 2
            and nx.is_weakly_connected(G)
        )
    else:
        return sum(d % 2 == 1 for v, d in G.degree()) in (0, 2) and nx.is_connected(G)
def is_semieulerian(G):
    """Returns ``True`` if and only if ``G`` has an Eulerian path.

    An Eulerian path is a path that crosses every edge in G
    exactly once.

    Parameters
    ----------
    G: NetworkX Graph, DiGraph, MultiGraph or MultiDiGraph
        A directed or undirected Graph or MultiGraph.

    Returns
    -------
    True, False

    See Also
    --------
    is_eulerian()

    Examples
    --------
    >>> G = nx.DiGraph([(1,2),(2,3)])
    >>> nx.is_semieulerian(G)
    True
    """
    is_directed = G.is_directed()

    # Verify that graph is connected, short circuit
    if is_directed and not nx.is_weakly_connected(G):
        return False

    # is undirected
    if not is_directed and not nx.is_connected(G):
        return False

    # Not all vertex have even degree, check if exactly two vertex
    # have odd degrees.  If yes, then there is an Euler path. If not,
    # raise an error (no Euler path can be found)

    # if the odd condition is not meet, raise an error.
    start = _find_path_start(G)
    if not start:
        return False

    return True
def test_create_forget_node():

    test_td = td.Tree_Decomposer(nx.complete_graph(2))

    test_graph = nx.DiGraph()
    test_root = frozenset({1, 2, 3, 4, 5})
    nodes_dict = {}
    nodes_dict[frozenset(test_root)] = ntd.Nice_Tree_Node(test_root)
    nodes_dict[frozenset({1, 2})] = ntd.Nice_Tree_Node({1, 2})
    nodes_dict[frozenset({3})] = ntd.Nice_Tree_Node({3})
    nodes_dict[frozenset({1, 3})] = ntd.Nice_Tree_Node({1, 3})
    nodes_dict[frozenset({2, 3})] = ntd.Nice_Tree_Node({2, 3})
    nodes_dict[frozenset({1, 2, 3})] = ntd.Nice_Tree_Node({1, 2, 3})
    nodes_dict[frozenset({4, 5})] = ntd.Nice_Tree_Node({4, 5})

    # test 1
    # checks if the function creates the correct forget nodes for
    # 1 child and more than 1 vertex in parent that is not he child
    test_graph.clear()

    test_graph.add_edge(nodes_dict[frozenset({1, 2, 3})],
                        nodes_dict[frozenset(test_root)])

    test_td.graph = test_graph
    test_td.graph_root = nodes_dict[frozenset({1, 2, 3})]

    test_td.create_forget_nodes(nodes_dict[frozenset({1, 2, 3})])

    child = list(test_td.graph.successors(nodes_dict[frozenset({1, 2, 3})]))[0]
    assert not child == nodes_dict[frozenset(
        test_root)], "this child should be removed"
    assert (child.bag == {1, 2, 3, 4}
            or child.bag == {1, 2, 3, 5}), "child has not specified bag"

    child_child = list(test_td.graph.successors(child))[0]
    assert child_child == nodes_dict[frozenset(
        test_root)], "last node should be child"
    assert child_child.bag == {1, 2, 3, 4,
                               5}, "child_child has not specified bag"

    for node_deg in list(nx.degree(test_td.graph)):
        assert not node_deg[1] == 0, "does create isolated node(s)"

    assert nx.number_of_selfloops(test_td.graph) == 0, "creates self loop(s)"
    assert nx.is_weakly_connected(test_td.graph), "not weakly connected"
Esempio n. 47
0
def is_dependency_subgraph(graph, subgraph_candidate,
                           node_attrib='label', edge_attrib='label'):
    """
    returns True, if the graph contains all of the subgraph candidate's
    dependency rules. The subgraph must also be (weakly) connected and contain
    at least two nodes.

    NOTE: The criteria used here might not be strong enough, i.e. it would
    be possible to construct a subgraph candidate that contains only rules
    from the graph but is not a true subgraph of the graph.
    """
    if len(subgraph_candidate) > 1:
        if nx.is_weakly_connected(subgraph_candidate):
            if includes_all_subgraph_rules(graph, subgraph_candidate,
                                           node_attrib=node_attrib,
                                           edge_attrib=edge_attrib):
                return True
    return False
Esempio n. 48
0
    def rooted_core_interface_pairs(self, root, thickness=None, **args):
        '''

        Args:
            root: int
            thickness:  
            **args:

        Returns:

        '''

        ciplist = super(self.__class__, self).rooted_core_interface_pairs(root, thickness, **args)


        #numbering shards if cip graphs not connected
        for cip in ciplist:
            if not nx.is_weakly_connected(cip.graph):
                comps = [list(node_list) for node_list in nx.weakly_connected_components(cip.graph)]
                comps.sort()

                for i, nodes in enumerate(comps):

                    for node in nodes:
                        cip.graph.node[node]['shard'] = i

        '''
        solve problem of single-ede-nodes in the core
        this may replace the need for fix_structure thing
        this is a little hard.. may fix later

        it isnt hard if i write this code in merge_core in ubergraphlearn

        for cip in ciplist:
            for n,d in cip.graph.nodes(data=True):
                if 'edge' in d and 'interface' not in d:
                    if 'interface' in cip.graph.node[ cip.graph.successors(n)[0]]:
                        #problem found
        '''

        return ciplist
Esempio n. 49
0
    def rooted_core_interface_pairs(self, root,
                                    thickness_list=None,
                                    for_base=False,
                                    radius_list=[],
                                    base_thickness_list=False):

        """
        Parameters
        ----------
        root:
        thickness:
        args:

        Returns
        -------
        """

        ciplist = super(self.__class__, self).rooted_core_interface_pairs(root,
                                        thickness_list=thickness_list,
                                        for_base=for_base,
                                        radius_list=radius_list,
                                        base_thickness_list=base_thickness_list)



        if not for_base:
            # numbering shards if cip graphs not connected
            for cip in ciplist:
                if not nx.is_weakly_connected(cip.graph):
                    comps = [list(node_list) for node_list in nx.weakly_connected_components(cip.graph)]
                    comps.sort()
                    for i, nodes in enumerate(comps):
                        for node in nodes:
                            cip.graph.node[node]['shard'] = i


        return ciplist
Esempio n. 50
0
def edge_connectivity(G, s=None, t=None):
    r"""Returns the edge connectivity of the graph or digraph G.

    The edge connectivity is equal to the minimum number of edges that
    must be removed to disconnect G or render it trivial. If source
    and target nodes are provided, this function returns the local edge
    connectivity: the minimum number of edges that must be removed to
    break all paths from source to target in G.

    This is a flow based implementation. The algorithm is based in solving
    a number of max-flow problems (ie local st-edge connectivity, see
    local_edge_connectivity) to determine the capacity of the minimum
    cut on an auxiliary directed network that corresponds to the minimum
    edge cut of G. It handles both directed and undirected graphs.

    Parameters
    ----------
    G : NetworkX graph
        Undirected or directed graph

    s : node
        Source node. Optional (default=None)

    t : node
        Target node. Optional (default=None)

    Returns
    -------
    K : integer
        Edge connectivity for G, or local edge connectivity if source
        and target were provided

    Examples
    --------
    >>> # Platonic icosahedral graph is 5-edge-connected
    >>> G = nx.icosahedral_graph()
    >>> nx.edge_connectivity(G)
    5

    Notes
    -----
    This is a flow based implementation of global edge connectivity. For
    undirected graphs the algorithm works by finding a 'small' dominating
    set of nodes of G (see algorithm 7 in [1]_ ) and computing local max flow
    (see local_edge_connectivity) between an arbitrary node in the dominating
    set and the rest of nodes in it. This is an implementation of
    algorithm 6 in [1]_ .

    For directed graphs, the algorithm does n calls to the max flow function.
    This is an implementation of algorithm 8 in [1]_ . We use the Ford and
    Fulkerson algorithm to compute max flow (see ford_fulkerson).

    See also
    --------
    local_node_connectivity
    node_connectivity
    local_edge_connectivity
    max_flow
    ford_fulkerson

    References
    ----------
    .. [1] Abdol-Hossein Esfahanian. Connectivity Algorithms.
        http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf
    """
    # Local edge connectivity
    if s is not None and t is not None:
        if s not in G:
            raise nx.NetworkXError("node %s not in graph" % s)
        if t not in G:
            raise nx.NetworkXError("node %s not in graph" % t)
        return local_edge_connectivity(G, s, t)
    # Global edge connectivity
    if G.is_directed():
        # Algorithm 8 in [1]
        if not nx.is_weakly_connected(G):
            return 0
        # initial value for lambda is min degree (\delta(G))
        L = min(G.degree().values())
        # reuse auxiliary digraph
        H = _aux_digraph_edge_connectivity(G)
        nodes = G.nodes()
        n = len(nodes)
        for i in range(n):
            try:
                L = min(L, local_edge_connectivity(G, nodes[i], nodes[i + 1], aux_digraph=H))
            except IndexError:  # last node!
                L = min(L, local_edge_connectivity(G, nodes[i], nodes[0], aux_digraph=H))
        return L
    else:  # undirected
        # Algorithm 6 in [1]
        if not nx.is_connected(G):
            return 0
        # initial value for lambda is min degree (\delta(G))
        L = min(G.degree().values())
        # reuse auxiliary digraph
        H = _aux_digraph_edge_connectivity(G)
        # A dominating set is \lambda-covering
        # We need a dominating set with at least two nodes
        for node in G:
            D = nx.dominating_set(G, start_with=node)
            v = D.pop()
            if D:
                break
        else:
            # in complete graphs the dominating sets will always be of one node
            # thus we return min degree
            return L
        for w in D:
            L = min(L, local_edge_connectivity(G, v, w, aux_digraph=H))
        return L
Esempio n. 51
0
def node_connectivity(G, s=None, t=None, flow_func=None):
    r"""Returns node connectivity for a graph or digraph G.

    Node connectivity is equal to the minimum number of nodes that
    must be removed to disconnect G or render it trivial. If source
    and target nodes are provided, this function returns the local node
    connectivity: the minimum number of nodes that must be removed to break
    all paths from source to target in G.

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

    s : node
        Source node. Optional. Default value: None.

    t : node
        Target node. Optional. Default value: None.

    flow_func : function
        A function for computing the maximum flow among a pair of nodes.
        The function has to accept at least three parameters: a Digraph,
        a source node, and a target node. And return a residual network
        that follows NetworkX conventions (see :meth:`maximum_flow` for
        details). If flow_func is None, the default maximum flow function
        (:meth:`edmonds_karp`) is used. See below for details. The
        choice of the default function may change from version
        to version and should not be relied on. Default value: None.

    Returns
    -------
    K : integer
        Node connectivity of G, or local node connectivity if source
        and target are provided.

    Examples
    --------
    >>> # Platonic icosahedral graph is 5-node-connected
    >>> G = nx.icosahedral_graph()
    >>> nx.node_connectivity(G)
    5

    You can use alternative flow algorithms for the underlying maximum
    flow computation. In dense networks the algorithm
    :meth:`shortest_augmenting_path` will usually perform better
    than the default :meth:`edmonds_karp`, which is faster for
    sparse networks with highly skewed degree distributions. Alternative
    flow functions have to be explicitly imported from the flow package.

    >>> from networkx.algorithms.flow import shortest_augmenting_path
    >>> nx.node_connectivity(G, flow_func=shortest_augmenting_path)
    5

    If you specify a pair of nodes (source and target) as parameters,
    this function returns the value of local node connectivity.

    >>> nx.node_connectivity(G, 3, 7)
    5

    If you need to perform several local computations among different
    pairs of nodes on the same graph, it is recommended that you reuse
    the data structures used in the maximum flow computations. See
    :meth:`local_node_connectivity` for details.

    Notes
    -----
    This is a flow based implementation of node connectivity. The
    algorithm works by solving `O((n-\delta-1+\delta(\delta-1)/2))`
    maximum flow problems on an auxiliary digraph. Where `\delta`
    is the minimum degree of G. For details about the auxiliary
    digraph and the computation of local node connectivity see
    :meth:`local_node_connectivity`. This implementation is based
    on algorithm 11 in [1]_.

    See also
    --------
    :meth:`local_node_connectivity`
    :meth:`edge_connectivity`
    :meth:`maximum_flow`
    :meth:`edmonds_karp`
    :meth:`preflow_push`
    :meth:`shortest_augmenting_path`

    References
    ----------
    .. [1] Abdol-Hossein Esfahanian. Connectivity Algorithms.
        http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf

    """
    if (s is not None and t is None) or (s is None and t is not None):
        raise nx.NetworkXError('Both source and target must be specified.')

    # Local node connectivity
    if s is not None and t is not None:
        if s not in G:
            raise nx.NetworkXError('node %s not in graph' % s)
        if t not in G:
            raise nx.NetworkXError('node %s not in graph' % t)
        return local_node_connectivity(G, s, t, flow_func=flow_func)

    # Global node connectivity
    if G.is_directed():
        if not nx.is_weakly_connected(G):
            return 0
        iter_func = itertools.permutations
        # It is necessary to consider both predecessors
        # and successors for directed graphs
        def neighbors(v):
            return itertools.chain.from_iterable([G.predecessors_iter(v),
                                                  G.successors_iter(v)])
    else:
        if not nx.is_connected(G):
            return 0
        iter_func = itertools.combinations
        neighbors = G.neighbors_iter

    # Reuse the auxiliary digraph and the residual network
    H = build_auxiliary_node_connectivity(G)
    R = build_residual_network(H, 'capacity')
    kwargs = dict(flow_func=flow_func, auxiliary=H, residual=R)

    # Pick a node with minimum degree
    degree = G.degree()
    minimum_degree = min(degree.values())
    v = next(n for n, d in degree.items() if d == minimum_degree)
    # Node connectivity is bounded by degree.
    K = minimum_degree
    # compute local node connectivity with all its non-neighbors nodes
    for w in set(G) - set(neighbors(v)) - set([v]):
        kwargs['cutoff'] = K
        K = min(K, local_node_connectivity(G, v, w, **kwargs))
    # Also for non adjacent pairs of neighbors of v
    for x, y in iter_func(neighbors(v), 2):
        if y in G[x]:
            continue
        kwargs['cutoff'] = K
        K = min(K, local_node_connectivity(G, x, y, **kwargs))

    return K
Esempio n. 52
0
pos=nx.spring_layout(G,k=0.15,iterations=10)
# pos=nx.graphviz_layout(G)
# pos=layout(G)

G.remove_nodes_from(nx.isolates(G))

print str(" ")
print 'WEAK CONNECTEDNESS OF DIRECTED GRAPHS'
print str(" ")

print str(" ")
print G.name
print str(" ")

print 'Is graph G weakly connected?', nx.is_weakly_connected(G)
print 'The number of weakly connected components of G is:', nx.number_weakly_connected_components(G)
print str(" ")

lc=sorted(nx.weakly_connected_components(G), key = len, reverse=True)
print 'List of weakly connected components:'
# print sorted(nx.weakly_connected_components(G), key = len, reverse=True)
print lc
print str(" ")


deg=G.degree()
deg_dic=[]
for nd in deg:
    if deg[nd]>0:
        deg_dic.append(nd)
 def test_is_not_consistent_dag_weakly_connected(self):
     g = self._createBaseGraph([(1,2),(1,3)])
     self.assertTrue(nx.is_weakly_connected(g))
 def test_is_dag_connected(self):
     g = self._createBaseGraph([(1,2),(2,3),(1,3),(4,5)])
     self.assertFalse(nx.is_weakly_connected(g))
Esempio n. 55
0
def average_shortest_path_length(G, weight=None):
    r"""Return the average shortest path length.

    The average shortest path length is

    .. math::

       a =\sum_{s,t \in V} \frac{d(s, t)}{n(n-1)}

    where `V` is the set of nodes in `G`,
    `d(s, t)` is the shortest path from `s` to `t`,
    and `n` is the number of nodes in `G`.

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

    weight : None or string, optional (default = None)
       If None, every edge has weight/distance/cost 1.
       If a string, use this edge attribute as the edge weight.
       Any edge attribute not present defaults to 1.

    Raises
    ------
    NetworkXPointlessConcept
        If `G` is the null graph (that is, the graph on zero nodes).

    NetworkXError
        If `G` is not connected (or not weakly connected, in the case
        of a directed graph).

    Examples
    --------
    >>> G = nx.path_graph(5)
    >>> nx.average_shortest_path_length(G)
    2.0

    For disconnected graphs, you can compute the average shortest path
    length for each component

    >>> G = nx.Graph([(1, 2), (3, 4)])
    >>> for C in nx.connected_component_subgraphs(G):
    ...     print(nx.average_shortest_path_length(C))
    1.0
    1.0

    """
    n = len(G)
    # For the special case of the null graph, raise an exception, since
    # there are no paths in the null graph.
    if n == 0:
        msg = ('the null graph has no paths, thus there is no average'
               'shortest path length')
        raise nx.NetworkXPointlessConcept(msg)
    # For the special case of the trivial graph, return zero immediately.
    if n == 1:
        return 0
    # Shortest path length is undefined if the graph is disconnected.
    if G.is_directed() and not nx.is_weakly_connected(G):
        raise nx.NetworkXError("Graph is not weakly connected.")
    if not G.is_directed() and not nx.is_connected(G):
        raise nx.NetworkXError("Graph is not connected.")
    # Compute all-pairs shortest paths.
    if weight is None:
        path_length = lambda v: nx.single_source_shortest_path_length(G, v)
    else:
        ssdpl = nx.single_source_dijkstra_path_length
        path_length = lambda v: ssdpl(G, v, weight=weight)
    # Sum the distances for each (ordered) pair of source and target node.
    s = sum(l for u in G for v, l in path_length(u))
    return s / (n * (n - 1))
Esempio n. 56
0
def node_connectivity(G, s=None, t=None):
    r"""Returns node connectivity for a graph or digraph G.

    Node connectivity is equal to the minimum number of nodes that
    must be removed to disconnect G or render it trivial. If source
    and target nodes are provided, this function returns the local node
    connectivity: the minimum number of nodes that must be removed to break
    all paths from source to target in G.

    This is a flow based implementation. The algorithm is based in
    solving a number of max-flow problems (ie local st-node connectivity,
    see local_node_connectivity) to determine the capacity of the
    minimum cut on an auxiliary directed network that corresponds to the
    minimum node cut of G. It handles both directed and undirected graphs.

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

    s : node
        Source node. Optional (default=None)

    t : node
        Target node. Optional (default=None)

    Returns
    -------
    K : integer
        Node connectivity of G, or local node connectivity if source
        and target were provided

    Examples
    --------
    >>> # Platonic icosahedral graph is 5-node-connected
    >>> G = nx.icosahedral_graph()
    >>> nx.node_connectivity(G)
    5
    >>> nx.node_connectivity(G, 3, 7)
    5

    Notes
    -----
    This is a flow based implementation of node connectivity. The
    algorithm works by solving `O((n-\delta-1+\delta(\delta-1)/2)` max-flow
    problems on an auxiliary digraph. Where `\delta` is the minimum degree
    of G. For details about the auxiliary digraph and the computation of
    local node connectivity see local_node_connectivity.

    This implementation is based on algorithm 11 in [1]_. We use the Ford
    and Fulkerson algorithm to compute max flow (see ford_fulkerson).

    See also
    --------
    local_node_connectivity
    all_pairs_node_connectivity_matrix
    local_edge_connectivity
    edge_connectivity
    max_flow
    ford_fulkerson

    References
    ----------
    .. [1] Abdol-Hossein Esfahanian. Connectivity Algorithms.
        http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf
    """
    # Local node connectivity
    if s is not None and t is not None:
        if s not in G:
            raise nx.NetworkXError("node %s not in graph" % s)
        if t not in G:
            raise nx.NetworkXError("node %s not in graph" % t)
        return local_node_connectivity(G, s, t)
    # Global node connectivity
    if G.is_directed():
        if not nx.is_weakly_connected(G):
            return 0
        iter_func = itertools.permutations
        # I think that it is necessary to consider both predecessors
        # and successors for directed graphs
        def neighbors(v):
            return itertools.chain.from_iterable([G.predecessors_iter(v), G.successors_iter(v)])

    else:
        if not nx.is_connected(G):
            return 0
        iter_func = itertools.combinations
        neighbors = G.neighbors_iter
    # Initial guess \kappa = n - 1
    K = G.order() - 1
    deg = G.degree()
    min_deg = min(deg.values())
    v = next(n for n, d in deg.items() if d == min_deg)
    # Reuse the auxiliary digraph
    H, mapping = _aux_digraph_node_connectivity(G)
    # compute local node connectivity with all non-neighbors nodes
    for w in set(G) - set(neighbors(v)) - set([v]):
        K = min(K, local_node_connectivity(G, v, w, aux_digraph=H, mapping=mapping))
    # Same for non adjacent pairs of neighbors of v
    for x, y in iter_func(neighbors(v), 2):
        if y in G[x]:
            continue
        K = min(K, local_node_connectivity(G, x, y, aux_digraph=H, mapping=mapping))
    return K
Esempio n. 57
0
def minimum_edge_cut(G, s=None, t=None, flow_func=None):
    r"""Returns a set of edges of minimum cardinality that disconnects G.

    If source and target nodes are provided, this function returns the
    set of edges of minimum cardinality that, if removed, would break
    all paths among source and target in G. If not, it returns a set of
    edges of minimum cardinality that disconnects G.

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

    s : node
        Source node. Optional. Default value: None.

    t : node
        Target node. Optional. Default value: None.

    flow_func : function
        A function for computing the maximum flow among a pair of nodes.
        The function has to accept at least three parameters: a Digraph, 
        a source node, and a target node. And return a residual network 
        that follows NetworkX conventions (see :meth:`maximum_flow` for 
        details). If flow_func is None, the default maximum flow function 
        (:meth:`edmonds_karp`) is used. See below for details. The
        choice of the default function may change from version
        to version and should not be relied on. Default value: None.

    Returns
    -------
    cutset : set
        Set of edges that, if removed, would disconnect G. If source
        and target nodes are provided, the set contians the edges that
        if removed, would destroy all paths between source and target.

    Examples
    --------
    >>> # Platonic icosahedral graph has edge connectivity 5
    >>> G = nx.icosahedral_graph()
    >>> len(nx.minimum_edge_cut(G))
    5

    You can use alternative flow algorithms for the underlying 
    maximum flow computation. In dense networks the algorithm 
    :meth:`shortest_augmenting_path` will usually perform better 
    than the default :meth:`edmonds_karp`, which is faster for 
    sparse networks with highly skewed degree distributions.
    Alternative flow functions have to be explicitly imported
    from the flow package.

    >>> from networkx.algorithms.flow import shortest_augmenting_path
    >>> len(nx.minimum_edge_cut(G, flow_func=shortest_augmenting_path))
    5

    If you specify a pair of nodes (source and target) as parameters,
    this function returns the value of local edge connectivity.

    >>> nx.edge_connectivity(G, 3, 7)
    5

    If you need to perform several local computations among different
    pairs of nodes on the same graph, it is recommended that you reuse
    the data structures used in the maximum flow computations. See 
    :meth:`local_edge_connectivity` for details.

    Notes
    -----
    This is a flow based implementation of minimum edge cut. For
    undirected graphs the algorithm works by finding a 'small' dominating
    set of nodes of G (see algorithm 7 in [1]_) and computing the maximum
    flow between an arbitrary node in the dominating set and the rest of
    nodes in it. This is an implementation of algorithm 6 in [1]_. For 
    directed graphs, the algorithm does n calls to the max flow function.
    The function raises an error if the directed graph is not weakly
    connected and returns an empty set if it is weakly connected.
    It is an implementation of algorithm 8 in [1]_.

    See also
    --------
    :meth:`minimum_st_edge_cut`
    :meth:`minimum_node_cut`
    :meth:`stoer_wagner`
    :meth:`node_connectivity`
    :meth:`edge_connectivity`
    :meth:`maximum_flow`
    :meth:`edmonds_karp`
    :meth:`preflow_push`
    :meth:`shortest_augmenting_path`

    References
    ----------
    .. [1] Abdol-Hossein Esfahanian. Connectivity Algorithms.
        http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf

    """
    if (s is not None and t is None) or (s is None and t is not None):
        raise nx.NetworkXError("Both source and target must be specified.")

    # reuse auxiliary digraph and residual network
    H = build_auxiliary_edge_connectivity(G)
    R = build_residual_network(H, "capacity")
    kwargs = dict(flow_func=flow_func, residual=R, auxiliary=H)

    # Local minimum edge cut if s and t are not None
    if s is not None and t is not None:
        if s not in G:
            raise nx.NetworkXError("node %s not in graph" % s)
        if t not in G:
            raise nx.NetworkXError("node %s not in graph" % t)
        return minimum_st_edge_cut(H, s, t, **kwargs)

    # Global minimum edge cut
    # Analog to the algoritm for global edge connectivity
    if G.is_directed():
        # Based on algorithm 8 in [1]
        if not nx.is_weakly_connected(G):
            raise nx.NetworkXError("Input graph is not connected")

        # Initial cutset is all edges of a node with minimum degree
        node = min(G, key=G.degree)
        min_cut = set(G.edges(node))
        nodes = list(G)
        n = len(nodes)
        for i in range(n):
            try:
                this_cut = minimum_st_edge_cut(H, nodes[i], nodes[i + 1], **kwargs)
                if len(this_cut) <= len(min_cut):
                    min_cut = this_cut
            except IndexError:  # Last node!
                this_cut = minimum_st_edge_cut(H, nodes[i], nodes[0], **kwargs)
                if len(this_cut) <= len(min_cut):
                    min_cut = this_cut

        return min_cut

    else:  # undirected
        # Based on algorithm 6 in [1]
        if not nx.is_connected(G):
            raise nx.NetworkXError("Input graph is not connected")

        # Initial cutset is all edges of a node with minimum degree
        node = min(G, key=G.degree)
        min_cut = set(G.edges(node))
        # A dominating set is \lambda-covering
        # We need a dominating set with at least two nodes
        for node in G:
            D = nx.dominating_set(G, start_with=node)
            v = D.pop()
            if D:
                break
        else:
            # in complete graphs the dominating set will always be of one node
            # thus we return min_cut, which now contains the edges of a node
            # with minimum degree
            return min_cut
        for w in D:
            this_cut = minimum_st_edge_cut(H, v, w, **kwargs)
            if len(this_cut) <= len(min_cut):
                min_cut = this_cut

        return min_cut
Esempio n. 58
0
def minimum_node_cut(G, s=None, t=None, flow_func=None):
    r"""Returns a set of nodes of minimum cardinality that disconnects G.

    If source and target nodes are provided, this function returns the
    set of nodes of minimum cardinality that, if removed, would destroy
    all paths among source and target in G. If not, it returns a set
    of nodes of minimum cardinality that disconnects G.

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

    s : node
        Source node. Optional. Default value: None.

    t : node
        Target node. Optional. Default value: None.

    flow_func : function
        A function for computing the maximum flow among a pair of nodes.
        The function has to accept at least three parameters: a Digraph, 
        a source node, and a target node. And return a residual network 
        that follows NetworkX conventions (see :meth:`maximum_flow` for 
        details). If flow_func is None, the default maximum flow function 
        (:meth:`edmonds_karp`) is used. See below for details. The
        choice of the default function may change from version
        to version and should not be relied on. Default value: None.

    Returns
    -------
    cutset : set
        Set of nodes that, if removed, would disconnect G. If source
        and target nodes are provided, the set contians the nodes that
        if removed, would destroy all paths between source and target.

    Examples
    --------
    >>> # Platonic icosahedral graph has node connectivity 5
    >>> G = nx.icosahedral_graph()
    >>> node_cut = nx.minimum_node_cut(G)
    >>> len(node_cut)
    5

    You can use alternative flow algorithms for the underlying maximum
    flow computation. In dense networks the algorithm
    :meth:`shortest_augmenting_path` will usually perform better
    than the default :meth:`edmonds_karp`, which is faster for
    sparse networks with highly skewed degree distributions. Alternative
    flow functions have to be explicitly imported from the flow package.

    >>> from networkx.algorithms.flow import shortest_augmenting_path
    >>> node_cut == nx.minimum_node_cut(G, flow_func=shortest_augmenting_path)
    True

    If you specify a pair of nodes (source and target) as parameters,
    this function returns a local st node cut.

    >>> len(nx.minimum_node_cut(G, 3, 7))
    5

    If you need to perform several local st cuts among different
    pairs of nodes on the same graph, it is recommended that you reuse
    the data structures used in the maximum flow computations. See 
    :meth:`minimum_st_node_cut` for details.

    Notes
    -----
    This is a flow based implementation of minimum node cut. The algorithm
    is based in solving a number of maximum flow computations to determine
    the capacity of the minimum cut on an auxiliary directed network that
    corresponds to the minimum node cut of G. It handles both directed
    and undirected graphs. This implementation is based on algorithm 11 
    in [1]_.

    See also
    --------
    :meth:`minimum_st_node_cut`
    :meth:`minimum_cut`
    :meth:`minimum_edge_cut`
    :meth:`stoer_wagner`
    :meth:`node_connectivity`
    :meth:`edge_connectivity`
    :meth:`maximum_flow`
    :meth:`edmonds_karp`
    :meth:`preflow_push`
    :meth:`shortest_augmenting_path`

    References
    ----------
    .. [1] Abdol-Hossein Esfahanian. Connectivity Algorithms.
        http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf

    """
    if (s is not None and t is None) or (s is None and t is not None):
        raise nx.NetworkXError("Both source and target must be specified.")

    # Local minimum node cut.
    if s is not None and t is not None:
        if s not in G:
            raise nx.NetworkXError("node %s not in graph" % s)
        if t not in G:
            raise nx.NetworkXError("node %s not in graph" % t)
        return minimum_st_node_cut(G, s, t, flow_func=flow_func)

    # Global minimum node cut.
    # Analog to the algoritm 11 for global node connectivity in [1].
    if G.is_directed():
        if not nx.is_weakly_connected(G):
            raise nx.NetworkXError("Input graph is not connected")
        iter_func = itertools.permutations

        def neighbors(v):
            return itertools.chain.from_iterable([G.predecessors(v), G.successors(v)])

    else:
        if not nx.is_connected(G):
            raise nx.NetworkXError("Input graph is not connected")
        iter_func = itertools.combinations
        neighbors = G.neighbors

    # Reuse the auxiliary digraph and the residual network.
    H = build_auxiliary_node_connectivity(G)
    R = build_residual_network(H, "capacity")
    kwargs = dict(flow_func=flow_func, auxiliary=H, residual=R)

    # Choose a node with minimum degree.
    v = min(G, key=G.degree)
    # Initial node cutset is all neighbors of the node with minimum degree.
    min_cut = set(G[v])
    # Compute st node cuts between v and all its non-neighbors nodes in G.
    for w in set(G) - set(neighbors(v)) - set([v]):
        this_cut = minimum_st_node_cut(G, v, w, **kwargs)
        if len(min_cut) >= len(this_cut):
            min_cut = this_cut
    # Also for non adjacent pairs of neighbors of v.
    for x, y in iter_func(neighbors(v), 2):
        if y in G[x]:
            continue
        this_cut = minimum_st_node_cut(G, x, y, **kwargs)
        if len(min_cut) >= len(this_cut):
            min_cut = this_cut

    return min_cut
Esempio n. 59
0
def edge_connectivity(G, s=None, t=None, flow_func=None):
    r"""Returns the edge connectivity of the graph or digraph G.

    The edge connectivity is equal to the minimum number of edges that
    must be removed to disconnect G or render it trivial. If source
    and target nodes are provided, this function returns the local edge
    connectivity: the minimum number of edges that must be removed to
    break all paths from source to target in G.

    Parameters
    ----------
    G : NetworkX graph
        Undirected or directed graph

    s : node
        Source node. Optional. Default value: None.

    t : node
        Target node. Optional. Default value: None.

    flow_func : function
        A function for computing the maximum flow among a pair of nodes.
        The function has to accept at least three parameters: a Digraph,
        a source node, and a target node. And return a residual network
        that follows NetworkX conventions (see :meth:`maximum_flow` for
        details). If flow_func is None, the default maximum flow function
        (:meth:`edmonds_karp`) is used. See below for details. The
        choice of the default function may change from version
        to version and should not be relied on. Default value: None.

    Returns
    -------
    K : integer
        Edge connectivity for G, or local edge connectivity if source
        and target were provided

    Examples
    --------
    >>> # Platonic icosahedral graph is 5-edge-connected
    >>> G = nx.icosahedral_graph()
    >>> nx.edge_connectivity(G)
    5

    You can use alternative flow algorithms for the underlying
    maximum flow computation. In dense networks the algorithm
    :meth:`shortest_augmenting_path` will usually perform better
    than the default :meth:`edmonds_karp`, which is faster for
    sparse networks with highly skewed degree distributions.
    Alternative flow functions have to be explicitly imported
    from the flow package.

    >>> from networkx.algorithms.flow import shortest_augmenting_path
    >>> nx.edge_connectivity(G, flow_func=shortest_augmenting_path)
    5

    If you specify a pair of nodes (source and target) as parameters,
    this function returns the value of local edge connectivity.

    >>> nx.edge_connectivity(G, 3, 7)
    5

    If you need to perform several local computations among different
    pairs of nodes on the same graph, it is recommended that you reuse
    the data structures used in the maximum flow computations. See
    :meth:`local_edge_connectivity` for details.

    Notes
    -----
    This is a flow based implementation of global edge connectivity.
    For undirected graphs the algorithm works by finding a 'small'
    dominating set of nodes of G (see algorithm 7 in [1]_ ) and
    computing local maximum flow (see :meth:`local_edge_connectivity`)
    between an arbitrary node in the dominating set and the rest of
    nodes in it. This is an implementation of algorithm 6 in [1]_ .
    For directed graphs, the algorithm does n calls to the maximum
    flow function. This is an implementation of algorithm 8 in [1]_ .

    See also
    --------
    :meth:`local_edge_connectivity`
    :meth:`local_node_connectivity`
    :meth:`node_connectivity`
    :meth:`maximum_flow`
    :meth:`edmonds_karp`
    :meth:`preflow_push`
    :meth:`shortest_augmenting_path`

    References
    ----------
    .. [1] Abdol-Hossein Esfahanian. Connectivity Algorithms.
        http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf

    """
    if (s is not None and t is None) or (s is None and t is not None):
        raise nx.NetworkXError('Both source and target must be specified.')

    # Local edge connectivity
    if s is not None and t is not None:
        if s not in G:
            raise nx.NetworkXError('node %s not in graph' % s)
        if t not in G:
            raise nx.NetworkXError('node %s not in graph' % t)
        return local_edge_connectivity(G, s, t, flow_func=flow_func)

    # Global edge connectivity
    # reuse auxiliary digraph and residual network
    H = build_auxiliary_edge_connectivity(G)
    R = build_residual_network(H, 'capacity')
    kwargs = dict(flow_func=flow_func, auxiliary=H, residual=R)

    if G.is_directed():
        # Algorithm 8 in [1]
        if not nx.is_weakly_connected(G):
            return 0

        # initial value for \lambda is minimum degree
        L = min(G.degree().values())
        nodes = G.nodes()
        n = len(nodes)
        for i in range(n):
            kwargs['cutoff'] = L
            try:
                L = min(L, local_edge_connectivity(G, nodes[i], nodes[i+1],
                                                   **kwargs))
            except IndexError: # last node!
                L = min(L, local_edge_connectivity(G, nodes[i], nodes[0],
                                                   **kwargs))
        return L
    else: # undirected
        # Algorithm 6 in [1]
        if not nx.is_connected(G):
            return 0

        # initial value for \lambda is minimum degree
        L = min(G.degree().values())
        # A dominating set is \lambda-covering
        # We need a dominating set with at least two nodes
        for node in G:
            D = nx.dominating_set(G, start_with=node)
            v = D.pop()
            if D:
                break
        else:
            # in complete graphs the dominating sets will always be of one node
            # thus we return min degree
            return L

        for w in D:
            kwargs['cutoff'] = L
            L = min(L, local_edge_connectivity(G, v, w, **kwargs))

        return L
Esempio n. 60
0
 def test_is_weakly_connected(self):
     for G, C in self.gc:
         U = G.to_undirected()
         assert_equal(nx.is_weakly_connected(G), nx.is_connected(U))