示例#1
0
def get_single_mask(imgA_t,
                    imgB_t,
                    imgA_t_1=None,
                    imgB_t_1=None,
                    smask_old=None):
    h, w = imgA_t.shape[:2]
    L2_NORM_t = np.linalg.norm(imgA_t - imgB_t, axis=2)
    if smask_old is None:
        G = build_graph(h, w, [L2_NORM_t])
        cut_value, partition = nx.minimum_cut(G, str(h * w), str(h * w + 1))
    else:
        L2_NORM_AA = np.linalg.norm(imgA_t - imgA_t_1, axis=2)
        L2_NORM_BB = np.linalg.norm(imgB_t - imgB_t_1, axis=2)
        L2_NORM_AB = np.linalg.norm(imgA_t - imgB_t_1, axis=2)
        L2_NORM_BA = np.linalg.norm(imgB_t - imgA_t_1, axis=2)
        G = build_graph(
            h, w,
            [L2_NORM_t, L2_NORM_AA + L2_NORM_BB + L2_NORM_AB + L2_NORM_BA],
            smask_old)
        cut_value, partition = nx.minimum_cut(G, str(2 * h * w),
                                              str(2 * h * w + 1))

    reachable, non_reachable = partition
    mask = np.zeros((h * w, ))
    reachable = np.int32(list(reachable))
    mask[reachable[reachable < h * w]] = 1
    mask = mask.reshape((h, w))
    mask_color = np.zeros((h, w, 3))
    mask_color[:, :, 0] = mask
    mask_color[:, :, 1] = mask
    mask_color[:, :, 2] = mask

    return mask_color
def compare_flows_and_cuts(G, s, t, solnFlows, solnValue, capacity='capacity'):
    for flow_func in flow_funcs:
        R = flow_func(G, s, t, capacity)
        # Test both legacy and new implementations.
        legacy = R.graph.get('algorithm') == "ford_fulkerson_legacy"
        flow_value = R.graph['flow_value']
        if legacy:
            flow_dict = R.graph['flow_dict']
        else:
            flow_dict = build_flow_dict(G, R)
        assert_equal(flow_value, solnValue, msg=msg.format(flow_func.__name__))
        if legacy:
            assert_equal(flow_dict,
                         solnFlows,
                         msg=msg.format(flow_func.__name__))
        else:
            validate_flows(G, s, t, flow_dict, solnValue, capacity, flow_func)
        # Minimum cut
        if legacy:
            cut_value, partition = nx.minimum_cut(G,
                                                  s,
                                                  t,
                                                  capacity=capacity,
                                                  flow_func=ford_fulkerson)
        else:
            cut_value, partition = nx.minimum_cut(G,
                                                  s,
                                                  t,
                                                  capacity=capacity,
                                                  flow_func=flow_func)
        validate_cuts(G, s, t, solnValue, partition, capacity, flow_func)
示例#3
0
 def upper_bound(self, g, pairs):
     assigned_paths = list(self.paths.values())
     assigned_pairs = set(self.paths.keys())
     unassigned_pairs = set(pairs) - assigned_pairs
     part1 = len(assigned_pairs)  #first part of lower bound
     rog = nx.DiGraph()
     path_edges = set()
     path_vertices = set()
     for p in assigned_paths:
         for i in range(len(p) - 1):
             path_edges.add((p[i], p[i + 1]))
             path_vertices.add(p[i])
             path_vertices.add(p[i + 1])
     for u in range(g.n):
         for v in g.adj[u]:
             if u not in path_vertices and v not in path_vertices:
                 rog.add_edge(u, v, capacity=1)
     for p in unassigned_pairs:
         u, v = p[0], p[1]
         rog.add_edge('s', u, capacity=len(g.adj[u] - path_vertices))
         deg = 0
         for u in range(g.n):
             if v in g.adj[u] and (u, v) not in path_edges:
                 deg += 1
         rog.add_edge(v, 't', capacity=deg)
     cut_value, _ = nx.minimum_cut(rog, 's',
                                   't')  #second part of lower bound
     # nx.draw(rog, with_labels = True, pos = nx.spring_layout(rog))
     # plt.savefig('sample1.png')
     return part1 + cut_value
示例#4
0
def mincut_fanout(g, s, T, tau, k, num_samples):
    '''
    Generates warm starts for the SNARES algorithm (a list of strategies for
    the defender and attacker)
    '''
    import random
    g = nx.DiGraph(g)
    for u,v in g.edges():
        g[u][v]['capacity'] = 1
    for v in g.successors(s):
        g[s][v]['capacity'] = np.inf
    best_t = T[np.argmax([tau[t] for t in T])]
#    min_cut = nx.minimum_edge_cut(g, s, best_t)
    part1, part2 = nx.minimum_cut(g, s, best_t)[1]
    if s in part1:
        min_cut = nx.edge_boundary(g, part1)
    else:
        min_cut = nx.edge_boundary(g, part2)
    defender_strats = []
    attacker_strats = []
    if len(min_cut) < k:
        defender_strats.append(min_cut)
        attacker_strats.append(attacker_br_pure(g, min_cut, s, T, tau))
        return defender_strats, attacker_strats
    for i in range(num_samples):
        defender_strats.append(random.sample(min_cut, k))
        attacker_strats.append(attacker_br_pure(g, defender_strats[-1], s, T, tau))
    return defender_strats, attacker_strats
示例#5
0
    def check_network_connections(self):
        graph = self.graph.copy()
        for edge in graph.edges():
            if self.get_edge_attribute(edge, 'capacity') == 0:
                graph.remove_edge(edge[0], edge[1])

        cut_links = []
        for edge in list(self.od_graph.edges()):
            s = edge[0]  # source
            t = edge[1]  # target
            if not nx.has_path(graph, s, t):
                self.lost_trips[(s, t)] = self.od_graph[s][t]['demand']
                self.od_graph.remove_edge(s, t)

                cut_value, partition = nx.minimum_cut(self.graph, s, t)
                reachable, non_reachable = partition

                cutset = set()
                for u, nbrs in ((n, self.graph[n]) for n in reachable):
                    cutset.update((u, v) for v in nbrs if v in non_reachable)
                cut_links.extend(list(cutset))

        for edge in list(set(cut_links)):
            if self.graph[edge[0]][edge[1]]['capacity'] == 0:
                self.cut_links.append(edge)
示例#6
0
def _remove_improbable_points(xy,edges,im, beta):
    
    mu = 1
    sigma=0.15

    # Return intensities under the points
    val = imtools.image_interp(im,xy)
       
    # Setup terminal and edge weights
    source, terminal = _terminalweights(val,mu,sigma)
    
    # Setup graph 
    D = _create_graph(source,terminal, edges, beta, is_edges=True)
    
    # Remove points with no neighbors (i.e., only connected to source and sink)
    deg = D.degree()
    to_remove = [p for p in deg if deg[p]==2 and p>=0]
    D.remove_nodes_from(to_remove)
    
    cut_value, partition = nx.minimum_cut(D,-1,-2)
    reachable, non_reachable = partition
    reachable.discard(-1)   # Remove source
    
    # Return resulting points
    xy = xy[list(reachable),:]
    
    return xy
def mincut_strategy(W, L):
    start = time.time()
    for i in range(W.shape[0]):
        if L[i][0] == 1:
            g.add_edge(i, 's', weight=upper_bound)
        elif L[i][1] == 1:
            g.add_edge('t', i, weight=upper_bound)
        else:
            if g.has_edge(i, 's'):
                g.remove_edge(i, 's')
            if g.has_edge('t', i):
                g.remove_edge('t', i)
    mid = time.time()
    print(mid - start)

    cut_value, (zero_class, positive_class) = nx.minimum_cut(g,
                                                             's',
                                                             't',
                                                             capacity='weight')
    print("--> " + str(cut_value))
    cut_time = time.time()
    print(cut_time - mid)

    prediction = np.zeros(W.shape[0])
    for i in zero_class:
        if (i != 's'):
            prediction[i] = 0
    for i in positive_class:
        if (i != 't'):
            prediction[i] = 1
    print(time.time() - cut_time)
    return prediction
示例#8
0
    def get_cut(self):
        """Performs the min cut.
           Returns cut_value, s nodes, t nodes"""
        cut_value, partition = nx.minimum_cut(self.DG, "S", "T")
        s_nodes, t_nodes = partition

        return cut_value, set(s_nodes), set(t_nodes)
示例#9
0
    def generate_constrs(self, model: Model):

        xf, V_, cp, G = model.translate(
            self.x), self.V, CutPool(), nx.DiGraph()

        # valid edges
        for (u, v) in self.graph.edges():
            try:
                edge = xf[u][v]
                G.add_edge(u, v, capacity=xf[u][v].x)
            except:
                pass

        for (u, v) in self.F:
            try:
                val, (S, NS) = nx.minimum_cut(G, u, v)
                if val <= 0.99:
                    aInS = [(xf[i][j], xf[i][j].x)
                            for (i, j) in product(V_, V_)
                            if i != j and xf[i][j] and i in S and j in S]
                    if sum(f for v, f in aInS) >= (len(S) - 1) + 1e-4:
                        cut = xsum(1.0 * v for v, fm in aInS) <= len(S) - 1
                        cp.add(cut)
                        if len(cp.cuts) > 256:
                            for cut in cp.cuts:
                                model += cut
                            return
            except nx.NetworkXError:
                pass
        for cut in cp.cuts:
            model += cut
示例#10
0
def RemoveCut(F, k):
    G = copy.deepcopy(F)
    k_set = list()
    counter = 0

    # Find min cut
    cut_value, partition = nx.minimum_cut(G, 's', 't')
    reachable, non_reachable = partition

    # Finding min st-cut set
    cut_set = list()
    for u, v in G.edges_iter():
        if u in reachable and v in non_reachable:
            cut_set.append((u, v, G[u][v]['capacity']))

    # Sort cut set by descending capacities
    cut_set.sort(key=lambda cut_set: cut_set[2], reverse=True)
    #print('Cut set : ',cut_set)
    #print('\n')

    # Removing edges from G and adding them to k-set
    for u, v, c in cut_set:
        if counter < k:
            k_set.append((u, v, c, 0))
            G.remove_edge(u, v)
        counter += 1
    # If there 	are less than k edges in the cut set remove the last eges randomly
    cs = len(cut_set)
    if cs < k:
        for u, v in random.sample(G.edges(), (k - cs)):
            k_set.append((u, v, G[u][v]['capacity'], 0))
            G.remove_edge(u, v)

    return G, k_set, cut_set
示例#11
0
 def generate_constrs(self, model: Model):
     G = nx.DiGraph()
     r = [(v, v.x) for v in model.vars if v.name.startswith("x(")]
     U = [v.name.split("(")[1].split(",")[0] for v, f in r]
     V = [v.name.split(")")[0].split(",")[1] for v, f in r]
     N = list(set(U + V))
     cp = CutPool()
     for i in range(len(U)):
         G.add_edge(U[i], V[i], capacity=r[i][1])
     for (u, v) in product(N, N):
         if u == v:
             continue
         val, (S, NS) = nx.minimum_cut(G, u, v)
         if val <= 0.99:
             arcsInS = [(v, f) for i, (v, f) in enumerate(r)
                        if U[i] in S and V[i] in S]
             if sum(f for v, f in arcsInS) >= (len(S) - 1) + 1e-4:
                 cut = xsum(1.0 * v for v, fm in arcsInS) <= len(S) - 1
                 cp.add(cut)
                 if len(cp.cuts) > 256:
                     for cut in cp.cuts:
                         model.add_cut(cut)
                     return
     for cut in cp.cuts:
         model.add_cut(cut)
    def compute_segmentation(self, g, image):
        cut_value, [Vs, Vt] = nx.minimum_cut(g, 's', 't', capacity='capacity')
        x_dim = image.shape[0]
        y_dim = image.shape[1]

        labels = np.zeros(image.shape)

        label_dict = {'00': 2, '01': 3, '10': 0, '11': 1}

        for xidx in range(0, x_dim):
            for yidx in range(0, y_dim):
                vp1_str = "(" + str(xidx) + "," + str(yidx) + "),1"
                vp2_str = "(" + str(xidx) + "," + str(yidx) + "),2"

                if (vp1_str in Vs):
                    phi1 = 1
                else:
                    phi1 = 0

                if (vp2_str in Vs):
                    phi2 = 1
                else:
                    phi2 = 0

                label_key = str(phi1) + str(phi2)
                labels[xidx, yidx] = label_dict[label_key]

        return labels
示例#13
0
 def generate_constrs(self, model: Model):
     G = nx.DiGraph()
     r = [(v, v.x) for v in model.vars if v.name.startswith('x(')]
     U = [int(v.name.split('(')[1].split(',')[0]) for v, f in r]
     V = [int(v.name.split(')')[0].split(',')[1]) for v, f in r]
     cp = CutPool()
     for i in range(len(U)):
         G.add_edge(U[i], V[i], capacity=r[i][1])
     for (u, v) in F:
         if u not in U or v not in V:
             continue
         val, (S, NS) = nx.minimum_cut(G, u, v)
         if val <= 0.99:
             arcsInS = [(v, f) for i, (v, f) in enumerate(r)
                        if U[i] in S and V[i] in S]
             if sum(f for v, f in arcsInS) >= (len(S) - 1) + 1e-4:
                 cut = xsum(1.0 * v for v, fm in arcsInS) <= len(S) - 1
                 cp.add(cut)
                 if len(cp.cuts) > 256:
                     for cut in cp.cuts:
                         model.add_cut(cut)
                     return
     for cut in cp.cuts:
         model.add_cut(cut)
     return
示例#14
0
def get_disconnected_component_mincut(graph, nodes, recourse):
    '''
        This function computes disconnected components of a given solution, solving a MinCut problem

        Args: DiGraph, list of nodes, recourse

        Return: list of component(s)
    '''

    capacity = recourse['x']
    gamma = recourse['gamma']
    depot = nodes[0]

    # Para todo j != depot, se hace min-cut. Sobre todos, se elige el subtour mas violado, junto al peso respectivo (gamma)
    graph.remove_edges_from(list(graph.edges))
    graph.add_edges_from(capacity)
    for (i, j) in capacity:
        graph[i][j]['capacity'] = capacity[i, j]
    components_list = list()
    component = None
    for i in nodes:
        if i != depot:
            (cap, (_, S)) = minimum_cut(graph, depot, i)
            if cap - gamma[j] < -1e-8:
                components_list.append((cap - gamma[i], i, S))
    
    if components_list: component = min(components_list, key=lambda x: x[0])

    return component     
示例#15
0
    def generate_constrs(self, model: Model):
        xf, V_, cp, G = model.translate(
            self.x), self.V, CutPool(), nx.DiGraph()
        for i in xf:
            for j in i:
                print(j, ' ', end='')
            print()
        print('V', V_)
        print('F', self.F)
        for (u, v) in [(k, l) for (k, l) in product(V_, V_)
                       if k != l and xf[k][l]]:
            G.add_edge(u, v, capacity=xf[u][v].x)
        print(list(G.nodes(data=True)))
        print(list(G.edges))

        for (u, v) in F:
            val, (S, NS) = nx.minimum_cut(G, u, v)
            if val <= 0.99:
                aInS = [(xf[i][j], xf[i][j].x) for (i, j) in product(V_, V_)
                        if i != j and xf[i][j] and i in S and j in S]
                if sum(f for v, f in aInS) >= (len(S) - 1) + 1e-4:
                    cut = xsum(1.0 * v for v, fm in aInS) <= len(S) - 1
                    cp.add(cut)
                    if len(cp.cuts) > 256:
                        for cut in cp.cuts:
                            model += cut
                        return
        for cut in cp.cuts:
            model += cut
示例#16
0
def get_mixed_patch(img, true_x, true_y, true_r, patch_x, patch_y, psi, cut_edges, 
	true_patch=None, blur=True):
    """
    Create a graph to find the best patch to apply
    """
    if true_patch is None:
    	true_patch = get_patch(img, true_x, true_y, psi, true_r)

    enlarged_true_patch = get_patch(img, true_x, true_y, psi + 2, true_r)

    G = create_graph(img, (patch_x, patch_y), enlarged_true_patch, cut_edges, psi)
    sets = (nx.minimum_cut(G, 'old', 'new', capacity="weight"))

    if 'old' in sets[1][0]:
        set_old = sets[1][0]
        set_new = sets[1][1]
    else:
        set_old = sets[1][1]
        set_new = sets[1][0]

    cut_edges, just_cut_edges = find_cut_edges(G, set_old, set_new, cut_edges)

    if blur:
    	applied_patch = blur_mix(img, true_patch, enlarged_true_patch, set_old, just_cut_edges, patch_x, patch_y, psi)
    else:
    	applied_patch = clean_mix(patch, true_patch, set_old, patch_x, patch_y, psi)

    return applied_patch
 def compute_flow(self):
     """
     Computes max flow for the node set
     """
     self.build_network()
     min_cut = nx.minimum_cut(self.network, 'source', 'sink')
     return min_cut
示例#18
0
def segment(weighted_graph, image_shape):
    """Peforms a segmentation

    Uses the minimum cut algorithm in NetworkX.

    Parameters
    ----------
    weighted_graph : NetworkX graph
    image_shape : tuple

    Returns
    -------
    segmentation : np.array
        The segmented image, which has 0's for pixels belonging to the
        bg class and 1's for the fg class.
    cut_cost : int
        The cost of the segmentation.
    bg_nodes, fg_nodes : list
        The nodes that have been assigned to the bg, fg classes.
    """
    cut_cost, cut_nodes = nx.minimum_cut(weighted_graph, "s", "t", capacity='weight')
    bg_nodes, fg_nodes = cut_nodes

    segmentation = np.ones(image_shape)
    for node in bg_nodes:
        if node not in ['s','t']:
            segmentation[node] = 0

    return (segmentation, cut_cost, bg_nodes, fg_nodes)
示例#19
0
def max_flow_cut(graph, constraints, k):
    if k != 2: raise Exception('Max flow only applicable for 2 partitions')
    if len(constraints.keys()) != 2:
        raise Exception('Max flow only applicable with 2 constraints')

    graph_copy = graph.copy()
    keys = list(constraints.keys())
    cut_value, partial = nx.minimum_cut(graph_copy,
                                        keys[0],
                                        keys[1],
                                        capacity='weight')
    reachable, non_reachable = partial
    cutset = set()
    for u, nbrs in ((n, graph_copy[n]) for n in reachable):
        cutset.update((u, v) for v in nbrs if v in non_reachable)

    partition = {}
    graph_copy.remove_edges_from(cutset)
    for con in constraints:
        for node in nx.algorithms.components.node_connected_component(
                graph_copy, con):
            partition[node] = constraints[con]

    # cutweight = cut_weight(graph, {v for v,k in partition.iteritems() if k==0}, data='invweight')
    # print 'max flow weight : {}'.format(evaluate(graph, partition, 2))
    return partition
示例#20
0
    def solve(self):
        """Solve for the TSP, using row generation for subtour elimination constraints."""
        def createConstForS(m, S):
            return sum(m.x[e] for e in m.edge_set if ((e[0] in S) and (e[1] in S))) <= len(S) - 1

        if not hasattr(self, 'solver'):
            solver = pyomo.opt.SolverFactory('gurobi')

        done = False
        while not done:
            # Solve once and add subtour elimination constraints if necessary
            # Finish when there are no more subtours
            results = solver.solve(self.m, tee=False, keepfiles=False,
                                   options_string="mip_tolerances_integrality=1e-9 mip_tolerances_mipgap=0")
            # Construct a graph from the answer, and look for subtours
            done = True
            graph = self.convertXsToNetworkx()
            targets = (k for k in self.m.node_set if k != 0)
            for k in targets:
                cut_value, partition = networkx.minimum_cut(graph, 0, k)
                reachable, non_reachable = partition
                if cut_value < 2:
                    print('Adding constraint for subtour elimination:')
                    print(reachable)
                    print(createConstForS(self.m, reachable))
                    print('--------------\n')
                    self.m.subtour_elimination_cc.add(createConstForS(self.m, reachable))
                    done = False
示例#21
0
def get_single_mask(i_l, i_r):
    h, w = i_l.shape[:2]

    abs_diff = np.absolute(i_l - i_r)
    color_diff = np.zeros((h, w), np.int32)
    color_diff = np.int32(abs_diff[:, :, 0]) + np.int32(
        abs_diff[:, :, 1]) + np.int32(abs_diff[:, :, 2])

    grad_l = cv2.Canny(i_l, 100, 200)
    grad_r = cv2.Canny(i_r, 100, 200)
    grad_abs_sum = np.int32(np.absolute(grad_l)) + np.int32(
        np.absolute(grad_r))

    G1 = build_graph(i_l, i_r, color_diff, grad_abs_sum)

    cut_value, partition = nx.minimum_cut(G1, str(h * w), str(h * w + 1))
    reachable, non_reachable = partition

    mask = np.zeros((1, h * w))
    reachable_l = list(map(int, reachable))
    reachable_l.remove(h * w)
    mask[0][reachable_l] = 1
    mask = mask.reshape((h, w))
    mask_color = np.zeros((h, w, 3))
    mask_color[:, :, 0] = mask
    mask_color[:, :, 1] = mask
    mask_color[:, :, 2] = mask

    return mask_color
示例#22
0
    def get_cut(self):
        """Performs the min cut.
           Returns cut_value, s nodes, t nodes"""
        cut_value, partition = nx.minimum_cut(self.DG, "S", "T")
        s_nodes, t_nodes = partition

        return cut_value, set(s_nodes), set(t_nodes)
def subtours(n, dist, model, x):
    # construindo grafo auxiliar (apenas uma vez)
    global F
    if not F:
        F = []
        G = nx.DiGraph()
        for ((i, j), val) in dist.items():
            G.add_edge(i, j, weight=val)
        for i in range(n):
            P, D = nx.dijkstra_predecessor_and_distance(G, source=i)
            DS = list(D.items())
            DS.sort(key=lambda x: x[1])
            F.append((i, DS[-1][0]))

    G = nx.DiGraph()
    for (i, j) in x.keys():
        if x[(i,j)].x > EPS:
            G.add_edge(i, j, capacity=x[i,j].x)

    cycles = set()
    for (u, v) in F:
        val, (S, NS) = nx.minimum_cut(G, u, v)
        if len(S) > 1 and len(S) < n and val <= 0.99:
            arcs_S = [(i,j) for (i,j) in dist if i in S and j in S]
            if sum(x[arc].x for arc in arcs_S) >= len(S) - 1 + EPS:
                cycles.add(tuple(S))

    return cycles
示例#24
0
def construction(g, s, N):
    if N == {s}:
        return
    t = choice(list(N - {s}))
    x, S = nx.minimum_cut(g, s, t)
    A.add_edge(s, t, capacity=x)
    construction(g, s, N.intersection(S[0]))
    construction(g, t, N.intersection(S[1]))
示例#25
0
def max_ind_set(G, C1, C2, weight):
    G.add_nodes_from(['s', 't'])
    for pi in C1 - C2:
        G.add_edge('s', pi, capacity=weight[pi])
    for pi in C2 - C1:
        G.add_edge(pi, 't', capacity=weight[pi])
    cut_value, cut_partition = nx.minimum_cut(G, 's', 't')
    return (cut_partition[0] & (C1 - C2)) | (cut_partition[1] & (C2 - C1))
示例#26
0
def _multicut_partitions(G, nrn):
    _, partition = nx.minimum_cut(G, 'source', 'target', capacity='weight')

    part0 = list(partition[0].difference({'source', 'target'}))
    part1 = list(partition[1].difference({'source', 'target'}))

    return nrn.MeshIndex(part0).to_mesh_mask_base, nrn.MeshIndex(
        part1).to_mesh_mask_base
示例#27
0
 def _recursive_build(H, A, source, avail):
     # Terminate once the flow has been compute to every node.
     if {source} == avail:
         return
     # pick an arbitrary node as the sink
     sink = arbitrary_element(avail - {source})
     # find the minimum cut and its weight
     value, (S, T) = nx.minimum_cut(H, source, sink)
     if H.is_directed():
         # check if the reverse direction has a smaller cut
         value_, (T_, S_) = nx.minimum_cut(H, sink, source)
         if value_ < value:
             value, S, T = value_, S_, T_
     # add edge with weight of cut to the aux graph
     A.add_edge(source, sink, weight=value)
     # recursively call until all but one node is used
     _recursive_build(H, A, source, avail.intersection(S))
     _recursive_build(H, A, sink, avail.intersection(T))
示例#28
0
def minflow_part1(graph, pop_col, pop_target, epsilon):  #doesn't work yet

    while 1 == 1:

        w = graph.copy()
        for ed in w.edges():
            w.add_edge(ed[0], ed[1], capacity=random.random())

        start = random.choice(list(w.nodes()))
        end = random.choice(list(w.nodes()))
        ##print(len(list(graph.neighbors(start))))
        ##print(len(list(graph.neighbors(end))))
        for n in list(graph.neighbors(start)):
            w.add_edge(start, n, capacity=100)
            for k in list(graph.neighbors(n)):
                w.add_edge(n, k, capacity=100)
                for j in list(graph.neighbors(k)):
                    w.add_edge(j, k, capacity=100)
                    for l in list(graph.neighbors(j)):
                        w.add_edge(j, l, capacity=100)
                        for f in list(graph.neighbors(l)):
                            w.add_edge(f, l, capacity=100)
                            for g in list(graph.neighbors(f)):
                                w.add_edge(f, g, capacity=100)

        for n in list(graph.neighbors(end)):
            w.add_edge(end, n, capacity=100)
            for k in list(graph.neighbors(n)):
                w.add_edge(n, k, capacity=100)
                for j in list(graph.neighbors(k)):
                    w.add_edge(j, k, capacity=100)
                    for l in list(graph.neighbors(j)):
                        w.add_edge(j, l, capacity=100)
                        for f in list(graph.neighbors(l)):
                            w.add_edge(f, l, capacity=100)
                            for g in list(graph.neighbors(f)):
                                w.add_edge(f, g, capacity=100)

        val, P = nx.minimum_cut(w, start, end, capacity='capacity')
        path = list(nx.shortest_path(graph, source=start, target=end))

        clusters = {}
        clusters[1] = P[0]
        clusters[-1] = P[1]
        clusters[2] = [start]
        clusters[3] = [end]
        path.remove(start)
        path.remove(end)
        clusters[4] = path
        tsum = 0
        for n in P[0]:
            tsum += graph.nodes[n][pop_col]
        #print(tsum/pop_target)
        if abs(tsum - pop_target) < epsilon * pop_target:
            return clusters
示例#29
0
def find_handle(F, G, candidate_dom, total_surplus, vio_upper_bd):
    start = timer()

    LHS_list = []
    for node in candidate_dom:
        A = G.node[node]['A']
        B = G.node[node]['B']

        from ABcut import edges_cross
        E_A_B = edges_cross(F, A, B)
        xE_A_B = sum(F[u][v]['weight'] for (u, v) in E_A_B)
        #        print('x*(E(A,B))=%.5f' % xE_A_B)

        LHS = 0.5 * G.node[node]['surplus'] - xE_A_B
        LHS_list.append(LHS)
    #print('LHS= %.5f' % LHS)

    sumLHS = sum(x for x in LHS_list)

    all_patterns = list(product([0, 1], repeat=len(candidate_dom)))
    for pattern in all_patterns:
        shrink = shrink_dom_graph(F, G, candidate_dom, pattern)
        Fshrink = shrink[0]
        s = shrink[1]
        t = shrink[2]
        inHandle = shrink[3]
        notinHandle = shrink[4]

        xdeltaH, partitions = nx.minimum_cut(Fshrink, s, t, capacity='weight')
        print('xdeltaH: %.5f' % xdeltaH)
        comb_surplus = xdeltaH + sumLHS

        if comb_surplus < vio_upper_bd:
            end = timer()
            print('success!!!!!!!!!!!!!!')
            print(partitions[0])
            print('comb surplus: %.5f' % comb_surplus)
            return None
            '''
           edge_cut_list=[]
            for p1_node in partitions[0]:
                for p2_node in partitions[1]:
                    if Fshrink.has_edge(p1_node,p2_node):
                        edge_cut_list.append((p1_node,p2_node))
            '''
            '''
            print('cut weight = %.5f' % cutweight)
            print('total surplus = %.5f' % total_surplus)
            print('cut weight + total surplus = %.5f' % cutweight+total_surplus)
            
            print('running time = %.5f seconds \n'% (end-start))
            '''
    print('Fails :(')
    return None  #[cutweight, cutweight+total_surplus, edge_cut_list]
示例#30
0
    def calc_cut(self, img, source_rect=None, sink_rect=None):
        """
        Calcualte Graph cut of img based on a source and sink rectangle
        :param img: Image to split
        :param source_rect: Pixels in this rect count as source (x,y,x+w,y+w)
        :param sink_rect: Pixels in this rect count as sink (x,y,x+w,y+w)
        :return: List of two lists containing pixel indices of the resulting cut images
        """
        G = nx.DiGraph()
        width, height = img.shape

        if source_rect == None:
            source_rect = [0, width / 3, 0, height]

        if sink_rect == None:
            sink_rect = [2 * width / 3, width, 0, height]

        img_gaus = ndimage.filters.gaussian_filter(img,
                                                   self.sigma,
                                                   mode='nearest')

        for x in range(width):
            for y in range(height):

                if x > source_rect[0] and x < source_rect[
                        1] and y > source_rect[2] and y < source_rect[3]:
                    G.add_edge("source", (x, y))

                if x > sink_rect[0] and x < sink_rect[1] and y > sink_rect[
                        2] and y < sink_rect[3]:
                    G.add_edge((x, y), "sink")

                for i in range(-1, 2):
                    for j in range(-1, 2):
                        if (
                                i != 0 or j != 0
                        ) and x + i > 0 and x + i < width and y + j > 0 and y + j < height and img_gaus[
                                x + i, y + j] != 1:
                            G.add_edge(
                                (x, y), (x + i, y + j), {
                                    'weight':
                                    min(1 - img_gaus[x, y],
                                        1 - img_gaus[x + i, y + j])
                                })

        cut_value, partition = nx.minimum_cut(G,
                                              'source',
                                              'sink',
                                              capacity='weight')

        xs = np.array([p[0] for p in partition[0]])
        ys = np.array([p[1] for p in partition[0]])

        return partition
示例#31
0
def calculate_maximum_flow(list_of_candidate_genes,phenome_interactome,iterations,path_to_save):
	'''
	the maximum flow value is equal to the min no of edges that have to be removed 
	to ensure that no flow is present in the network
	networkx uses the preflow_push algorithm to calculate the maximum flow
	'''

	final_network=add_candidates_to_network(list_of_candidate_genes,phenome_interactome)
	flow_value,flow_dict=nx.maximum_flow(final_network,155600,'t')
	cut_value,partition=nx.minimum_cut(final_network,155600,'t')
	write_flows(list_of_candidate_genes,flow_dict,phenome_interactome,iterations,path_to_save)
示例#32
0
def compare_flows_and_cuts(G, s, t, solnFlows, solnValue, capacity='capacity'):
    for flow_func in flow_funcs:
        R = flow_func(G, s, t, capacity)
        # Test both legacy and new implementations.
        flow_value = R.graph['flow_value']
        flow_dict = build_flow_dict(G, R)
        assert_equal(flow_value, solnValue, msg=msg.format(flow_func.__name__))
        validate_flows(G, s, t, flow_dict, solnValue, capacity, flow_func)
        # Minimum cut
        cut_value, partition = nx.minimum_cut(G, s, t, capacity=capacity,
                                              flow_func=flow_func)
        validate_cuts(G, s, t, solnValue, partition, capacity, flow_func)
示例#33
0
def compare_flows_and_cuts(G, s, t, solnFlows, solnValue, capacity='capacity'):
    for flow_func in flow_funcs:
        R = flow_func(G, s, t, capacity)
        # Test both legacy and new implementations.
        flow_value = R.graph['flow_value']
        flow_dict = build_flow_dict(G, R)
        assert flow_value == solnValue, msg.format(flow_func.__name__)
        validate_flows(G, s, t, flow_dict, solnValue, capacity, flow_func)
        # Minimum cut
        cut_value, partition = nx.minimum_cut(G, s, t, capacity=capacity,
                                              flow_func=flow_func)
        validate_cuts(G, s, t, solnValue, partition, capacity, flow_func)
示例#34
0
def improve_segmentation_with_depth(img_prob,dep_img):
    norm_dep_img=(dep_img-np.min(dep_img))/(np.max(dep_img)-np.min(dep_img))
    img_dep_inv=1/(norm_dep_img+1e-9)
    img_prob_inv=1-img_prob
    depth_diff,depth_sd,depth_mean,magic,G=create_markov_field(img_prob_inv,img_dep_inv)
    (cost, (set1, set2)) = nx.minimum_cut(G, 's', 't', capacity='weight')
    min_i,min_j,max_i,max_j = find_window(img_prob_inv)
    if len(set1)/(len(set2)+len(set1)) >  0.98 or len(set1)/(len(set2)+len(set1))  < 0.02:
        p=np.copy(img_prob)
        p[p>0.5]=255
        p[p<=5]=0
        return p
    return get_segmented_image(set1,set2,img_prob,min_i,min_j)
示例#35
0
def compare_flows_and_cuts(G, s, t, solnFlows, solnValue, capacity='capacity'):
    for flow_func in flow_funcs:
        R = flow_func(G, s, t, capacity)
        # Test both legacy and new implementations.
        legacy = R.graph.get('algorithm') == "ford_fulkerson_legacy"
        flow_value = R.graph['flow_value']
        if legacy:
            flow_dict = R.graph['flow_dict']
        else:
            flow_dict = build_flow_dict(G, R)
        assert_equal(flow_value, solnValue, msg=msg.format(flow_func.__name__))
        if legacy:
            assert_equal(flow_dict, solnFlows, msg=msg.format(flow_func.__name__))
        else:
            validate_flows(G, s, t, flow_dict, solnValue, capacity, flow_func)
        # Minimum cut
        if legacy:
            cut_value, partition = nx.minimum_cut(G, s, t,  capacity=capacity,
                                                  flow_func=ford_fulkerson)
        else:
            cut_value, partition = nx.minimum_cut(G, s, t, capacity=capacity,
                                                  flow_func=flow_func)
        validate_cuts(G, s, t, solnValue, partition, capacity, flow_func)
示例#36
0
def cut_and_label(graphList):
    size = graphList[0].number_of_nodes() - 2
    result = np.zeros(size,dtype=np.int8)
    source = size
    target = size + 1
    
    for i,g in enumerate(graphList):
        cutValue,partition = nx.minimum_cut(g,source,target,capacity="weight")
        _,trueIndex = partition
        
        if target in trueIndex:
            trueIndex.remove(target)
        
        result[list(trueIndex)] = i + 1
        
    return result
示例#37
0
def cutAndLabel(faces,features,proba):
    graphList,size = buildDiGraph(faces,features,proba)    
    
    source = size -2
    sink = size - 1
    
    result = np.zeros(size-2)    
    
    for i in range(len(graphList)):
        cutValue,partition = nx.minimum_cut(graphList[i],source,sink,capacity="weight")
        falseIndex,trueIndex = partition
        
        if sink in trueIndex:
            trueIndex.remove(sink)
        
        result[list(trueIndex)] = i+1
    
    return result
示例#38
0
def _remove_improbable_triangles(xy,tri,nbhood,alpha):
    
    mu = 60
    sigma = 0.85
    
    # Get minimum angle of triangles
    angles = np.rad2deg([minimum_angle(xy[T,:]) for T in tri])

    # Setup Terminal weights and edge weights
    source, terminal = _terminalweights(angles,mu,sigma)
    
    # Cut graph
    D = _create_graph(source,terminal, nbhood, alpha)   
    cut_value, partition = nx.minimum_cut(D,-1,-2)
    reachable, non_reachable = partition
    reachable.discard(-1)   # Remove source
    
    # Keep only the nodes connected to the source    
    tri = tri[list(reachable),:]
    
    return tri
示例#39
0
文件: tuzc.py 项目: weifei/tuzc
 def get_min_cut(self, s, t):
     # get min cut between two nodes
     return nx.minimum_cut(self.base_digraph, s, t)
示例#40
0
import networkx as nx
from exmodule import CythonMaxflowGraph, digraph_to_edge_list

G = nx.DiGraph()
G.add_edge('x','a', capacity=3.0)
G.add_edge('x','b', capacity=1.0)
G.add_edge('a','c', capacity=3.0)
G.add_edge('b','c', capacity=5.0)
G.add_edge('b','d', capacity=4.0)
G.add_edge('d','e', capacity=2.0)
G.add_edge('c','y', capacity=2.0)
G.add_edge('e','y', capacity=3.0)

G = nx.convert_node_labels_to_integers(G)
n = len(G)
s = 0
t = n - 1

cy_graph = CythonMaxflowGraph(max_node_num=n**2)
cy_graph.from_py_object(digraph_to_edge_list(G), s, t)

print(G.edges.data('capacity'))

print('NetworxX:')
print(nx.minimum_cut(G, s, t))

print('Cython:')
print(cy_graph.min_cut())
示例#41
0
 def mincut(self):
     logging.info("Calculate mincut.")
     value, cut = networkx.minimum_cut(self.g, self.source, self.sink)
     return value, cut
示例#42
0
def lazy_constraint(model, where):
    MAXCUTS = 20    
    if((where == GRB.callback.MIPNODE and GRB.status.OPTIMAL == model.cbGet(GRB.callback.MIPNODE_STATUS) ) or where == GRB.callback.MIPSOL):
        X_W = {}
        V_VAL = {}
        G = model._G
        bs = model._bs
        X = model._X
        Y = model._Y
        edges = model._edges

        for edge in edges:
            if(where == GRB.callback.MIPNODE):
                x = model.cbGetNodeRel(X[(edge[0],edge[1])])
            else:
                x = model.cbGetSolution(X[(edge[0],edge[1])])
                #print "VAL " + str(x)
            X_W[(edge[0],edge[1])] = x

        #retrive the Y val
        y_val = {}
        for i in range(G.shape[0]):
            if i == bs: continue
            if(where == GRB.callback.MIPNODE):
                y_val[i] = model.cbGetNodeRel(Y[i])
            else:
                y_val[i] = model.cbGetSolution(Y[i])
                        
        for i in range(G.shape[0]):
            if i == bs or y_val[i] == 0: continue
            cut_number = 0
            added_constraint = True
            
            while cut_number < MAXCUTS and added_constraint:
                added_constraint = False

                #print "ESAMINO NODO " + str(i)
                #print Y[i]
            

                G_W = nx.DiGraph()
                for v1 in range(G.shape[0]):
                    G_W.add_node(v1)

                for edge in edges:
                    G_W.add_edge(edge[0],edge[1], capacity = X_W[(edge[0],edge[1])])

                cut_value, partition = nx.minimum_cut(G_W, bs, i)

                #print "CUT VAL " + str(cut_value)
                #print "Y VAL " + str(y_val[i])
                #print partition

                partition_root = partition[0]
                if cut_value < y_val[i]:
                    added_constraint = True
                    cut_number += 1
                    cut_set = set()

                    for node in partition_root:
                        for j in range(G.shape[0]):
                            if(j not in partition_root and G[node,j] == 1):
                                cut_set.add((node,j))

                    expr = 0.0
                    #print "CUT SET"
                    #print cut_set

                    for edge in cut_set:
                        X_W[(edge[0], edge[1])] == 1.0
                        expr += X[edge[0], edge[1]]

                    model.cbLazy(expr >= Y[i])                   
示例#43
0
def minimum_st_edge_cut(G, s, t, flow_func=None, auxiliary=None, residual=None):
    """Returns the edges of the cut-set of a minimum (s, t)-cut.

    This function returns the set of edges of minimum cardinality that,
    if removed, would destroy all paths among source and target in G.
    Edge weights are not considered

    Parameters
    ----------
    G : NetworkX graph
        Edges of the graph are expected to have an attribute called
        'capacity'. If this attribute is not present, the edge is
        considered to have infinite capacity.

    s : node
        Source node for the flow.

    t : node
        Sink node for the flow.

    auxiliary : NetworkX DiGraph
        Auxiliary digraph to compute flow based node connectivity. It has
        to have a graph attribute called mapping with a dictionary mapping
        node names in G and in the auxiliary digraph. If provided
        it will be reused instead of recreated. 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 :meth:`node_connectivity` for
        details. The choice of the default function may change from version
        to version and should not be relied on. Default value: None.

    residual : NetworkX DiGraph
        Residual network to compute maximum flow. If provided it will be
        reused instead of recreated. Default value: None.

    Returns
    -------
    cutset : set
        Set of edges that, if removed from the graph, will disconnect it.

    See also
    --------
    :meth:`minimum_cut`
    :meth:`minimum_node_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`

    Examples
    --------
    This function is not imported in the base NetworkX namespace, so you
    have to explicitly import it from the connectivity package:

    >>> from networkx.algorithms.connectivity import minimum_st_edge_cut

    We use in this example the platonic icosahedral graph, which has edge
    connectivity 5.

    >>> G = nx.icosahedral_graph()
    >>> len(minimum_st_edge_cut(G, 0, 6))
    5

    If you need to compute local edge cuts on several pairs of
    nodes in the same graph, it is recommended that you reuse the
    data structures that NetworkX uses in the computation: the 
    auxiliary digraph for edge connectivity, and the residual
    network for the underlying maximum flow computation.

    Example of how to compute local edge cuts among all pairs of
    nodes of the platonic icosahedral graph reusing the data 
    structures.

    >>> import itertools
    >>> # You also have to explicitly import the function for 
    >>> # building the auxiliary digraph from the connectivity package
    >>> from networkx.algorithms.connectivity import (
    ...     build_auxiliary_edge_connectivity)
    >>> H = build_auxiliary_edge_connectivity(G)
    >>> # And the function for building the residual network from the
    >>> # flow package
    >>> from networkx.algorithms.flow import build_residual_network
    >>> # Note that the auxiliary digraph has an edge attribute named capacity
    >>> R = build_residual_network(H, 'capacity')
    >>> result = dict.fromkeys(G, dict())
    >>> # Reuse the auxiliary digraph and the residual network by passing them
    >>> # as parameters
    >>> for u, v in itertools.combinations(G, 2):
    ...     k = len(minimum_st_edge_cut(G, u, v, auxiliary=H, residual=R))
    ...     result[u][v] = k
    >>> all(result[u][v] == 5 for u, v in itertools.combinations(G, 2))
    True

    You can also use alternative flow algorithms for computing edge
    cuts. For instance, 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(minimum_st_edge_cut(G, 0, 6, flow_func=shortest_augmenting_path))
    5

    """
    if flow_func is None:
        flow_func = default_flow_func

    if auxiliary is None:
        H = build_auxiliary_edge_connectivity(G)
    else:
        H = auxiliary

    kwargs = dict(capacity="capacity", flow_func=flow_func, residual=residual)

    cut_value, partition = nx.minimum_cut(H, s, t, **kwargs)
    reachable, non_reachable = partition
    # Any edge in the original graph linking the two sets in the
    # partition is part of the edge cutset
    cutset = set()
    for u, nbrs in ((n, G[n]) for n in reachable):
        cutset.update((u, v) for v in nbrs if v in non_reachable)

    return cutset
示例#44
0
def gomory_hu_tree(G, capacity='capacity', flow_func=None):
    r"""Returns the Gomory-Hu tree of an undirected graph G.

    A Gomory-Hu tree of an undirected graph with capacities is a
    weighted tree that represents the minimum s-t cuts for all s-t
    pairs in the graph.
    
    It only requires `n-1` minimum cut computations instead of the
    obvious `n(n-1)/2`. The tree represents all s-t cuts as the
    minimum cut value among any pair of nodes is the minimum edge
    weight in the shortest path between the two nodes in the
    Gomory-Hu tree.

    The Gomory-Hu tree also has the property that removing the
    edge with the minimum weight in the shortest path between
    any two nodes leaves two connected components that form
    a partition of the nodes in G that defines the minimum s-t
    cut.

    See Examples section below for details.
   
    Parameters
    ----------
    G : NetworkX graph
        Undirected graph

    capacity : string
        Edges of the graph G are expected to have an attribute capacity
        that indicates how much flow the edge can support. If this
        attribute is not present, the edge is considered to have
        infinite capacity. Default value: 'capacity'.

    flow_func : function
        Function to perform the underlying flow computations. Default value
        :func:`edmonds_karp`. This function performs better in sparse graphs
        with right tailed degree distributions.
        :func:`shortest_augmenting_path` will perform better in denser
        graphs.

    Returns
    -------
    Tree : NetworkX graph
        A NetworkX graph representing the Gomory-Hu tree of the input graph.

    Raises
    ------
    NetworkXNotImplemented : Exception
        Raised if the input graph is directed.

    NetworkXError: Exception
        Raised if the input graph is an empty Graph.

    Examples
    --------
    >>> G = nx.karate_club_graph()
    >>> nx.set_edge_attributes(G, 'capacity', 1)
    >>> T = nx.gomory_hu_tree(G)
    >>> # The value of the minimum cut between any pair
    ... # of nodes in G is the minimum edge weight in the
    ... # shortest path between the two nodes in the
    ... # Gomory-Hu tree.
    ... def minimum_edge_weight_in_shortest_path(T, u, v):
    ...     path = nx.shortest_path(T, u, v, weight='weight')
    ...     return min((T[u][v]['weight'], (u,v)) for (u, v) in zip(path, path[1:]))
    >>> u, v = 0, 33
    >>> cut_value, edge = minimum_edge_weight_in_shortest_path(T, u, v)
    >>> cut_value
    10
    >>> nx.minimum_cut_value(G, u, v)
    10
    >>> # The Comory-Hu tree also has the property that removing the
    ... # edge with the minimum weight in the shortest path between
    ... # any two nodes leaves two connected components that form
    ... # a partition of the nodes in G that defines the minimum s-t
    ... # cut.
    ... cut_value, edge = minimum_edge_weight_in_shortest_path(T, u, v)
    >>> T.remove_edge(*edge)
    >>> U, V = list(nx.connected_components(T))
    >>> # Thus U and V form a partition that defines a minimum cut
    ... # between u and v in G. You can compute the edge cut set,
    ... # that is, the set of edges that if removed from G will 
    ... # disconnect u from v in G, with this information:
    ... cutset = set()
    >>> for x, nbrs in ((n, G[n]) for n in U):
    ...     cutset.update((x, y) for y in nbrs if y in V)
    >>> # Because we have set the capacities of all edges to 1
    ... # the cutset contains ten edges
    ... len(cutset)
    10
    >>> # You can use any maximum flow algorithm for the underlying
    ... # flow computations using the argument flow_func
    ... from networkx.algorithms import flow
    >>> T = nx.gomory_hu_tree(G, flow_func=flow.boykov_kolmogorov)
    >>> cut_value, edge = minimum_edge_weight_in_shortest_path(T, u, v)
    >>> cut_value
    10
    >>> nx.minimum_cut_value(G, u, v, flow_func=flow.boykov_kolmogorov)
    10

    Notes
    -----
    This implementation is based on Gusfield approach [1]_ to compute
    Comory-Hu trees, which does not require node contractions and has
    the same computational complexity than the original method.

    See also
    --------
    :func:`minimum_cut`
    :func:`maximum_flow`

    References
    ----------
    .. [1] Gusfield D: Very simple methods for all pairs network flow analysis.
           SIAM J Comput 19(1):143-155, 1990.

    """
    if flow_func is None:
        flow_func = default_flow_func

    if len(G) == 0: # empty graph
        msg = 'Empty Graph does not have a Gomory-Hu tree representation'
        raise nx.NetworkXError(msg)

    # Start the tree as a star graph with an arbitrary node at the center
    tree = {}
    labels = {}
    iter_nodes = iter(G)
    root = next(iter_nodes)
    for n in iter_nodes:
        tree[n] = root

    # Reuse residual network
    R = build_residual_network(G, capacity)

    # For all the leaves in the star graph tree (that is n-1 nodes).
    for source in tree:
        # Find neighbor in the tree
        target = tree[source]
        # compute minimum cut
        cut_value, partition = nx.minimum_cut(G, source, target,
                                capacity=capacity, flow_func=flow_func,
                                residual=R)
        labels[(source, target)] = cut_value
        # Update the tree
        # Source will always be in partition[0] and target in partition[1]
        for node in partition[0]:
            if node != source and node in tree and tree[node] == target:
                tree[node] = source
                labels[(node, source)] = labels.get((node, target), cut_value)
    # Build the tree
    T = nx.Graph()
    T.add_nodes_from(G)
    T.add_weighted_edges_from(((u, v, labels[(u, v)]) for u, v in tree.items()))
    return T
示例#45
0
def lazy_constraint(model, where):
    MAXCUTS = 1
    if((where == GRB.callback.MIPNODE and GRB.status.OPTIMAL == model.cbGet(GRB.callback.MIPNODE_STATUS) ) or where == GRB.callback.MIPSOL):
        X_W = {}
        V_VAL = {}
        G = model._G
        CUR_LOC = model._CUR_LOC
        X = model._X
        Y = model._Y
        edges = model._edges
        G_W = model._G_W

        for edge in edges:
            if(where == GRB.callback.MIPNODE):
                x = model.cbGetNodeRel(X[(edge[0],edge[1])])
            else:
                x = model.cbGetSolution(X[(edge[0],edge[1])])
                #print "VAL " + str(x)
            X_W[(edge[0],edge[1])] = x

        #retrive the Y val
        y_val = {}
        for i in range(G.shape[0]):
            if i == CUR_LOC[0]: continue
            if(where == GRB.callback.MIPNODE):
                y_val[i] = model.cbGetNodeRel(Y[i])
            else:
                y_val[i] = model.cbGetSolution(Y[i])

        #Only if X_W is not updated
        for edge in edges:
            G_W[edge[0]][edge[1]]['capacity'] = X_W[(edge[0],edge[1])]        

        for i in range(G.shape[0]):
            if i == CUR_LOC[0]: continue
            cut_number = 0
            added_constraint = True
            #Altrimenti qui
            
            while cut_number < MAXCUTS and added_constraint:
                added_constraint = False

                #print "ESAMINO NODO " + str(i)
                #print Y[i]

                cut_value, partition = nx.minimum_cut(G_W, CUR_LOC[0], i)

                #print "CUT VAL " + str(cut_value)
                #print "Y VAL " + str(y_val[i])
                #print partition

                partition_root = partition[0]
                if cut_value < y_val[i]:
                    added_constraint = True
                    cut_number += 1
                    cut_set = set()

                    for node in partition_root:
                        for j in range(G.shape[0]):
                            if(j not in partition_root and G[node,j] == 1):
                                cut_set.add((node,j))

                    expr = 0.0
                    #print "CUT SET"
                    #print cut_set

                    for edge in cut_set:
                        #G_W[edge[0]][edge[1]]['capacity'] = 1.0
                        expr += X[edge[0], edge[1]]

                    model.cbLazy(expr >= Y[i])