def rest_minimum_st_node_cut(self,
                                 G,
                                 A,
                                 B,
                                 s,
                                 t,
                                 auxiliary=None,
                                 residual=None,
                                 flow_func=edmonds_karp):

        if auxiliary is None:
            H = self.rest_build_auxiliary_node_connectivity(G, A, B)
        else:
            H = auxiliary

        if G.has_edge(s, t) or G.has_edge(t, s):
            return []
        kwargs = dict(flow_func=flow_func, residual=residual, auxiliary=H)

        for node in [x for x in A if x not in [s, t]]:
            edge = ('%sA' % node, '%sB' % node)
            num_in_edges = len(H.in_edges(edge[0]))
            H[edge[0]][edge[1]]['capacity'] = num_in_edges

        edge_cut = minimum_st_edge_cut(H, '%sB' % s, '%sA' % t, **kwargs)

        node_cut = set([
            n for n in
            [H.nodes[node]['id'] for edge in edge_cut for node in edge]
            if n not in A
        ])

        return node_cut - set([s, t])
Ejemplo n.º 2
0
    def min_nodes_to_remove(self, graph, source_node, target_node):

        cv = check_graph_validity.Graphs()
        ret = cv.is_valid_min_nodes_graph(graph, source_node, target_node)
        if (not ret[0]):
            ret.append({})
            print(ret)
            return ret

        try:
            # construct networkx graph from given graph
            G = nx.Graph()
            G.add_nodes_from(graph['nodes'])
            G.add_edges_from(graph['edges'])

        except Exception as e:
            return [False, str(e), {}]

        output = {}

        # get the minimum set of nodes/edges to disconnect source_node and targert_node
        nodes = list(minimum_st_node_cut(G, source_node, target_node))
        edges = list(minimum_st_edge_cut(G, source_node, target_node))
        edges = [list(e) for e in edges]

        output["nodes"] = nodes
        output["edges"] = edges

        return [True, 'success', output]
Ejemplo n.º 3
0
def sample_cuts(graph, max_steps=1000, max_cuts=1):
    """ Function to help find critical links in the given graph.
    Critical links here are links which -once removed- would disconnect considerable
    parts of the network. Those links are searched for by counting minimum cuts between
    a large number of node pairs (up to max_steps pairs will be explored).
    If more pairs exist than max_steps allows to explore, pick max_steps random pairs.

    Args:
    -------
    graph: networkx graph
        Graph of individual cluster (created using networkx).
    max_steps
        Up to max_steps pairs will be explored to search for cuts. Default = 1000.
    max_cuts
        Maximum numbers of links allowed to be cut. Default = 1.
    """

    num_nodes = graph.number_of_nodes()
    # num_edges = graph.number_of_edges()

    # Make list of all pairs within graph
    nodes = np.array(graph.nodes)
    pairs = np.array(np.meshgrid(nodes, nodes)).T
    remove_diagonal = np.array([(i * num_nodes + i) for i in range(num_nodes)])
    pairs = np.delete(pairs.reshape(-1, 2), remove_diagonal, axis=0)

    sampled_cuts = []
    if pairs.shape[0] <= max_steps:
        max_steps = pairs.shape[0]
    else:
        # If more pairs exist than max_steps allows to explore, pick max_steps random pairs.
        choices = np.random.choice(np.arange(pairs.shape[0]),
                                   max_steps,
                                   replace=False)
        pairs = pairs[choices, :]

    for pair in pairs:
        cuts = minimum_st_edge_cut(graph,
                                   pair[0],
                                   pair[1],
                                   flow_func=shortest_augmenting_path)
        # nx.node_connectivity(graphs[4], 592, 376)
        # cuts = nx.minimum_st_edge_cut(graph, pair[0], pair[1])
        # cuts = nx.minimum_edge_cut(graph, pair[0], pair[1])#, flow_func=shortest_augmenting_path)
        if len(cuts) <= max_cuts:
            sampled_cuts.append(cuts)

    return sampled_cuts
Ejemplo n.º 4
0
    def run(self):
        """Use networkx min cut algorithm to find a set of edges."""

        from networkx.algorithms.connectivity import minimum_st_edge_cut

        # The min cut algorithm will get the min cut nearest the end
        # of the direction of the graph, so we we use the reverse graph
        # so that we get a cut nearest our from_node, or the first cut we
        # would encounter on a given path from the from_node to the to_node.
        min_cut_edges = list(
            minimum_st_edge_cut(G=self._dependents_graph.
                                get_direct_nonprivate_graph().get_node_tree(
                                    self._to_node),
                                s=self._to_node,
                                t=self._from_node))
        return [(edge[1], edge[0]) for edge in min_cut_edges]
Ejemplo n.º 5
0
def test_raw():
    edges, weights = ex_graph()

    weighted_graph = nx.from_edgelist(edges)
    for i_edge, edge in enumerate(edges):
        weighted_graph[edge[0]][edge[1]]['capacity'] = weights[i_edge]

    r_flow = edmonds_karp(weighted_graph, 0, 11)
    cutset = minimum_st_edge_cut(weighted_graph, 0, 11, residual=r_flow)

    weighted_graph.remove_edges_from(cutset)
    ccs = list(nx.connected_components(weighted_graph))

    print("NETWORKX:", cutset)
    print("NETWORKX:", ccs)

    g = graph_tool.all.Graph(directed=True)
    g.add_edge_list(edge_list=np.concatenate([edges, edges[:, [1, 0]]]),
                    hashed=False)
    cap = g.new_edge_property("float", vals=np.concatenate([weights, weights]))
    src, tgt = g.vertex(0), g.vertex(11)

    res = graph_tool.flow.boykov_kolmogorov_max_flow(g, src, tgt, cap)

    part = graph_tool.all.min_st_cut(g, src, cap, res)
    rm_edges = [e for e in g.edges() if part[e.source()] != part[e.target()]]

    print("GRAPHTOOL:",
          [(rm_edge.source().__str__(), rm_edge.target().__str__())
           for rm_edge in rm_edges])

    ccs = []
    for i_cc in np.unique(part.a):
        ccs.append(np.where(part.a == i_cc)[0])

    print("GRAPHTOOL:", ccs)

    return edges, weights
Ejemplo n.º 6
0
def test_unbounded():
    G = nx.complete_graph(5)
    for flow_func in flow_funcs:
        assert_equal(4, len(minimum_st_edge_cut(G, 1, 4, flow_func=flow_func)))
Ejemplo n.º 7
0
def test_unbounded():
    G = nx.complete_graph(5)
    for flow_func in flow_funcs:
        assert_equal(4, len(minimum_st_edge_cut(G, 1, 4, flow_func=flow_func)))
Ejemplo n.º 8
0
def mincut_nx(edges: Iterable[Sequence[np.uint64]],
              affs: Sequence[np.uint64],
              sources: Sequence[np.uint64],
              sinks: Sequence[np.uint64],
              logger: Optional[logging.Logger] = None) -> np.ndarray:
    """ Computes the min cut on a local graph
    :param edges: n x 2 array of uint64s
    :param affs: float array of length n
    :param sources: uint64
    :param sinks: uint64
    :return: m x 2 array of uint64s
        edges that should be removed
    """

    time_start = time.time()

    original_edges = edges.copy()

    edges, affs, mapping, remapping = merge_cross_chunk_edges(
        edges.copy(), affs.copy())
    mapping_vec = np.vectorize(lambda a: mapping[a] if a in mapping else a)

    if len(edges) == 0:
        return []

    if len(mapping) > 0:
        assert np.unique(list(mapping.keys()),
                         return_counts=True)[1].max() == 1

    remapped_sinks = mapping_vec(sinks)
    remapped_sources = mapping_vec(sources)

    sinks = remapped_sinks
    sources = remapped_sources

    sink_connections = np.array(list(itertools.product(sinks, sinks)))
    source_connections = np.array(list(itertools.product(sources, sources)))

    weighted_graph = nx.Graph()
    weighted_graph.add_edges_from(edges)
    weighted_graph.add_edges_from(sink_connections)
    weighted_graph.add_edges_from(source_connections)

    for i_edge, edge in enumerate(edges):
        weighted_graph[edge[0]][edge[1]]['capacity'] = affs[i_edge]
        weighted_graph[edge[1]][edge[0]]['capacity'] = affs[i_edge]

    # Add infinity edges for multicut
    for sink_i in sinks:
        for sink_j in sinks:
            weighted_graph[sink_i][sink_j]['capacity'] = float_max

    for source_i in sources:
        for source_j in sources:
            weighted_graph[source_i][source_j]['capacity'] = float_max

    dt = time.time() - time_start
    if logger is not None:
        logger.debug("Graph creation: %.2fms" % (dt * 1000))
    time_start = time.time()

    ccs = list(nx.connected_components(weighted_graph))
    for cc in ccs:
        cc_list = list(cc)

        # If connected component contains no sources and/or no sinks,
        # remove its nodes from the mincut computation
        if not np.any(np.in1d(sources, cc_list)) or \
                not np.any(np.in1d(sinks, cc_list)):
            weighted_graph.remove_nodes_from(cc)

    r_flow = edmonds_karp(weighted_graph, sinks[0], sources[0])
    cutset = minimum_st_edge_cut(weighted_graph,
                                 sources[0],
                                 sinks[0],
                                 residual=r_flow)

    # cutset = nx.minimum_edge_cut(weighted_graph, sources[0], sinks[0], flow_func=edmonds_karp)

    dt = time.time() - time_start
    if logger is not None:
        logger.debug("Mincut comp: %.2fms" % (dt * 1000))

    if cutset is None:
        return []

    time_start = time.time()

    edge_cut = list(list(cutset))

    weighted_graph.remove_edges_from(edge_cut)
    ccs = list(nx.connected_components(weighted_graph))

    # assert len(ccs) == 2

    for cc in ccs:
        cc_list = list(cc)
        if logger is not None:
            logger.debug("CC size = %d" % len(cc_list))

        if np.any(np.in1d(sources, cc_list)):
            assert np.all(np.in1d(sources, cc_list))
            assert ~np.any(np.in1d(sinks, cc_list))

        if np.any(np.in1d(sinks, cc_list)):
            assert np.all(np.in1d(sinks, cc_list))
            assert ~np.any(np.in1d(sources, cc_list))

    dt = time.time() - time_start
    if logger is not None:
        logger.debug("Splitting local graph: %.2fms" % (dt * 1000))

    remapped_cutset = []
    for cut in cutset:
        if cut[0] in remapping:
            pre_cut = remapping[cut[0]]
        else:
            pre_cut = [cut[0]]

        if cut[1] in remapping:
            post_cut = remapping[cut[1]]
        else:
            post_cut = [cut[1]]

        remapped_cutset.extend(list(itertools.product(pre_cut, post_cut)))
        remapped_cutset.extend(list(itertools.product(post_cut, pre_cut)))

    remapped_cutset = np.array(remapped_cutset, dtype=np.uint64)

    remapped_cutset_flattened_view = remapped_cutset.view(dtype='u8,u8')
    edges_flattened_view = original_edges.view(dtype='u8,u8')

    cutset_mask = np.in1d(remapped_cutset_flattened_view, edges_flattened_view)

    return remapped_cutset[cutset_mask]
Ejemplo n.º 9
0
nx.diameter(G_internet)

nx.density(G_karate)

nx.density(G_electric)

nx.density(G_internet)

import networkx.algorithms.connectivity as nxcon

nxcon.minimum_st_node_cut(
    G_karate, mr_hi, john_a
)  # Returns a set of nodes of minimum cardinality that disconnect source from target in G

nxcon.minimum_st_edge_cut(G_karate, mr_hi, john_a)

nx.node_connectivity(
    G_karate, mr_hi, john_a
)  # Returns an approximation for node connectivity for a graph or digraph G

nx.edge_connectivity(G_karate, mr_hi, john_a)

nxcon.minimum_node_cut(
    G_karate
)  # Returns a set of nodes of minimum cardinality that disconnects G

nxcon.minimum_edge_cut(G_karate)

nx.node_connectivity(
    G_karate