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)
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
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
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)
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
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 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
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
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
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
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
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
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
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)
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
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
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
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
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]))
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))
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
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))
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
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]
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
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)
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)
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)
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)
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
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
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
def get_min_cut(self, s, t): # get min cut between two nodes return nx.minimum_cut(self.base_digraph, s, t)
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())
def mincut(self): logging.info("Calculate mincut.") value, cut = networkx.minimum_cut(self.g, self.source, self.sink) return value, cut
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])
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
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
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])