def get_max_flow_values(G, use_node_capacities=True, use_node_demands=False): ''' This runs a ford-fulkerson maximum flow algrothim over the provided network and assigns the resulting flows to each edge. The flows for each node are also calcualted and assigned. ''' print G.edges() #print G.edges() if use_node_capacities == True: G = convert_topo(G) print G.edges() exit() #check for supply and demand nodes. Needs to be at least one of each. #if more than one need to create a super source/sink(demand) nodes. G, supply_nodes, demand_nodes, added_nodes, added_edges = check_for_demand_supply_nodes( G) #get supply node and demand node supply_nd, demand_nd = get_check_supply_demand_nodes( G, supply_nodes, demand_nodes, added_nodes) if use_node_capacities == True and use_node_demands == False: #this returns the maximum flow and the flow on each edge by node #first check a path is possible - ford-fulkerson would just return 0 otherwise path = nx.has_path(G, supply_nd, demand_nd) if path == False: raise error_classes.GeneralError( 'No path exists between the supply node (node %s) and the demand node (node %s).' % (supply_nd, demand_nd)) max_flow, edge_flows = nx.ford_fulkerson(G, supply_nd, demand_nd, 'flow_capacity') elif use_node_capacities == True and use_node_demands == True: #returns the flow on each edge given capacities and demands #the sum of the demand needs to equal the sum of the supply (indicated by a negative demand value) edge_flows = nx.min_cost_flow(G, 'demand', 'flow_capacity', 'weight') elif use_node_capacities == False and use_node_demands == True: #returns the flow on each edge given demands (capacities should be set at 9999999 (a very high number)) edge_flows = nx.min_cost_flow(G, 'demand', 'flow_capacity', 'weight') #assign flows to nodes and edges G = assign_edge_node_flows(G, edge_flows) #before running any analysis, need to remove the added nodes and edges - the super source/demand if used G = remove_added_nodes_edges(G, added_edges, added_nodes) node_flow_max, edge_flow_max = get_max_flows(G) return G, { 'max_flow': max_flow, 'max_node_flow': node_flow_max, 'max_edge_flow': edge_flow_max }
def test_digon(self): """Check if digons are handled properly. Taken from ticket #618 by arv.""" nodes = [(1, {}), (2, {'demand': -4}), (3, {'demand': 4}), ] edges = [(1, 2, {'capacity': 3, 'weight': 600000}), (2, 1, {'capacity': 2, 'weight': 0}), (2, 3, {'capacity': 5, 'weight': 714285}), (3, 2, {'capacity': 2, 'weight': 0}), ] G = nx.DiGraph(edges) G.add_nodes_from(nodes) flowCost, H = nx.network_simplex(G) soln = {1: {2: 0}, 2: {1: 0, 3: 4}, 3: {2: 0}} assert_equal(flowCost, 2857140) assert_equal(nx.min_cost_flow_cost(G), 2857140) assert_equal(H, soln) assert_equal(nx.min_cost_flow(G), soln) assert_equal(nx.cost_of_flow(G, H), 2857140) flowCost, H = nx.capacity_scaling(G) assert_equal(flowCost, 2857140) assert_equal(H, soln) assert_equal(nx.cost_of_flow(G, H), 2857140)
def test_digraph1(self): # From Bradley, S. P., Hax, A. C. and Magnanti, T. L. Applied # Mathematical Programming. Addison-Wesley, 1977. G = nx.DiGraph() G.add_node(1, demand=-20) G.add_node(4, demand=5) G.add_node(5, demand=15) G.add_edges_from([(1, 2, { 'capacity': 15, 'weight': 4 }), (1, 3, { 'capacity': 8, 'weight': 4 }), (2, 3, { 'weight': 2 }), (2, 4, { 'capacity': 4, 'weight': 2 }), (2, 5, { 'capacity': 10, 'weight': 6 }), (3, 4, { 'capacity': 15, 'weight': 1 }), (3, 5, { 'capacity': 5, 'weight': 3 }), (4, 5, { 'weight': 2 }), (5, 3, { 'capacity': 4, 'weight': 1 })]) flowCost, H = nx.network_simplex(G) soln = { 1: { 2: 12, 3: 8 }, 2: { 3: 8, 4: 4, 5: 0 }, 3: { 4: 11, 5: 5 }, 4: { 5: 10 }, 5: { 3: 0 } } assert_equal(flowCost, 150) assert_equal(nx.min_cost_flow_cost(G), 150) assert_equal(H, soln) assert_equal(nx.min_cost_flow(G), soln) assert_equal(nx.cost_of_flow(G, H), 150)
def test_digon(self): """Check if digons are handled properly. Taken from ticket #618 by arv.""" nodes = [(1, {}), (2, {'demand': -4}), (3, {'demand': 4}), ] edges = [(1, 2, {'capacity': 3, 'weight': 600000}), (2, 1, {'capacity': 2, 'weight': 0}), (2, 3, {'capacity': 5, 'weight': 714285}), (3, 2, {'capacity': 2, 'weight': 0}), ] G = nx.DiGraph(edges) G.add_nodes_from(nodes) flowCost, H = nx.network_simplex(G) soln = {1: {2: 0}, 2: {1: 0, 3: 4}, 3: {2: 0}} assert flowCost == 2857140 assert nx.min_cost_flow_cost(G) == 2857140 assert H == soln assert nx.min_cost_flow(G) == soln assert nx.cost_of_flow(G, H) == 2857140 flowCost, H = nx.capacity_scaling(G) assert flowCost == 2857140 assert H == soln assert nx.cost_of_flow(G, H) == 2857140
def checkFeasible(self): G = nx.DiGraph() totalQuantity = 0 totalPrice = 0 for bid in self.winningBids: bidName = 'b' + str(bid[1]) G.add_edge('s', bidName) totalPrice += self.cab.bidList[bid[1]].priceOfBid for s in range(len(self.cab.bidList[bid[1]].listOfSubBids)): subbidName = bidName + 's' + str(s) quantity = self.cab.bidList[bid[1]].listOfSubBids[s].quantity totalQuantity += quantity G.add_edge(bidName, subbidName, capacity=quantity) for i in self.cab.bidList[bid[1]].listOfSubBids[s].listOfItems: itemName = 'r' + str(i) unitOfItem = self.cab.itemList[i].numberOfUnits G.add_edge(subbidName, itemName) G.add_edge(itemName, 't', capacity=unitOfItem) G.add_node('s', demand=-totalQuantity) G.add_node('t', demand=totalQuantity) try: flowDict = nx.min_cost_flow(G) self.maxValue = [self.maxValue, totalPrice][self.maxValue < totalPrice] return flowDict except: return False
def test_zero_capacity_edges(self): """Address issue raised in ticket #617 by arv.""" G = nx.DiGraph() G.add_edges_from([(1, 2, {'capacity': 1, 'weight': 1}), (1, 5, {'capacity': 1, 'weight': 1}), (2, 3, {'capacity': 0, 'weight': 1}), (2, 5, {'capacity': 1, 'weight': 1}), (5, 3, {'capacity': 2, 'weight': 1}), (5, 4, {'capacity': 0, 'weight': 1}), (3, 4, {'capacity': 2, 'weight': 1})]) G.nodes[1]['demand'] = -1 G.nodes[2]['demand'] = -1 G.nodes[4]['demand'] = 2 flowCost, H = nx.network_simplex(G) soln = {1: {2: 0, 5: 1}, 2: {3: 0, 5: 1}, 3: {4: 2}, 4: {}, 5: {3: 2, 4: 0}} assert flowCost == 6 assert nx.min_cost_flow_cost(G) == 6 assert H == soln assert nx.min_cost_flow(G) == soln assert nx.cost_of_flow(G, H) == 6 flowCost, H = nx.capacity_scaling(G) assert flowCost == 6 assert H == soln assert nx.cost_of_flow(G, H) == 6
def minCostFlow(src,dst,bw,edges,all=False,factor=1): #print "Find flow %s->%s: %s"%(src,dst,bw) #for e in edges: # print str(e) G = nx.DiGraph() G.add_node(src, demand = bw) G.add_node(dst, demand = -bw) vtoe={} res=[] for e in edges: if(e.getAVLBW(all)>0): # print "v1: %s v2: %s bw: %s cost: %s" %(e.v1,e.v2, e.getAVLBW(all),int((e.cost+e.beta)/factor)) # sys.stdout.flush() G.add_edge(e.v1, e.v2, weight = int((e.cost+e.beta)/factor), capacity = e.getAVLBW(all)) G.add_edge(e.v2, e.v1, weight = int((e.cost+e.beta)/factor), capacity = e.getAVLBW(all)) vtoe[(e.v1,e.v2)]=e vtoe[(e.v2,e.v1)]=e try: # print G.edges flowDict = nx.min_cost_flow(G) for k in flowDict: for j in flowDict[k]: if flowDict[k][j]>0: res.append([vtoe[(k,j)],flowDict[k][j]]) except nx.exception.NetworkXUnfeasible: print "No feasible Flow" return res
def min_cost_flow(self): def get_demand(flow_dict, node): in_flow = sum(flow_dict[u][v][key] for u, v, key in self.in_edges(node, keys=True)) out_flow = sum(flow_dict[u][v][key] for u, v, key in self.out_edges(node, keys=True)) return in_flow - out_flow def split(multi_flowG): base_dict = coll.defaultdict(lambda: coll.defaultdict(dict)) new_mdg = nx.MultiDiGraph() for u, v, key in multi_flowG.edges: lowerbound = multi_flowG[u][v][key]['lowerbound'] base_dict[u][v][key] = lowerbound new_mdg.add_edge(u, v, key, capacity=multi_flowG[u][v][key]['capacity'] - lowerbound, weight=multi_flowG[u][v][key]['weight'], ) for node in multi_flowG: new_mdg.nodes[node]['demand'] = \ multi_flowG.nodes[node]['demand'] - \ get_demand(base_dict, node) return base_dict, new_mdg base_dict, new_mdg = split(self) flow_dict = nx.min_cost_flow(new_mdg) for u, v, key in self.edges: flow_dict[u][v][key] += base_dict[u][v][key] self.cost = self.cost_of_flow(flow_dict) return flow_dict
def test_digraph1(self): # From Bradley, S. P., Hax, A. C. and Magnanti, T. L. Applied # Mathematical Programming. Addison-Wesley, 1977. G = nx.DiGraph() G.add_node(1, demand=-20) G.add_node(4, demand=5) G.add_node(5, demand=15) G.add_edges_from([(1, 2, {'capacity': 15, 'weight': 4}), (1, 3, {'capacity': 8, 'weight': 4}), (2, 3, {'weight': 2}), (2, 4, {'capacity': 4, 'weight': 2}), (2, 5, {'capacity': 10, 'weight': 6}), (3, 4, {'capacity': 15, 'weight': 1}), (3, 5, {'capacity': 5, 'weight': 3}), (4, 5, {'weight': 2}), (5, 3, {'capacity': 4, 'weight': 1})]) flowCost, H = nx.network_simplex(G) soln = {1: {2: 12, 3: 8}, 2: {3: 8, 4: 4, 5: 0}, 3: {4: 11, 5: 5}, 4: {5: 10}, 5: {3: 0}} assert_equal(flowCost, 150) assert_equal(nx.min_cost_flow_cost(G), 150) assert_equal(H, soln) assert_equal(nx.min_cost_flow(G), soln) assert_equal(nx.cost_of_flow(G, H), 150) flowCost, H = nx.capacity_scaling(G) assert_equal(flowCost, 150) assert_equal(H, soln) assert_equal(nx.cost_of_flow(G, H), 150)
def test_zero_capacity_edges(self): """Address issue raised in ticket #617 by arv.""" G = nx.DiGraph() G.add_edges_from([(1, 2, {'capacity': 1, 'weight': 1}), (1, 5, {'capacity': 1, 'weight': 1}), (2, 3, {'capacity': 0, 'weight': 1}), (2, 5, {'capacity': 1, 'weight': 1}), (5, 3, {'capacity': 2, 'weight': 1}), (5, 4, {'capacity': 0, 'weight': 1}), (3, 4, {'capacity': 2, 'weight': 1})]) G.nodes[1]['demand'] = -1 G.nodes[2]['demand'] = -1 G.nodes[4]['demand'] = 2 flowCost, H = nx.network_simplex(G) soln = {1: {2: 0, 5: 1}, 2: {3: 0, 5: 1}, 3: {4: 2}, 4: {}, 5: {3: 2, 4: 0}} assert_equal(flowCost, 6) assert_equal(nx.min_cost_flow_cost(G), 6) assert_equal(H, soln) assert_equal(nx.min_cost_flow(G), soln) assert_equal(nx.cost_of_flow(G, H), 6) flowCost, H = nx.capacity_scaling(G) assert_equal(flowCost, 6) assert_equal(H, soln) assert_equal(nx.cost_of_flow(G, H), 6)
def assignLB ( problem ): """ Uses networkx min_cost_flow algorithm for computes the assignment lower bound. Alternatively, also networkx network simplex algorithm could be used instead. Parameters: problem : class The TSP problem object has returned by function load_problem of package tsplib95. Returns: cost : int The lower bound (objective value of the assignment problem). elist : list of int The list of edges in the assignment. """ # Solve assignment problem as a minimum-cost network flow problem n = problem.dimension G = nx.DiGraph() for i in problem.get_nodes(): G.add_node(i, demand = -1 ) for j in problem.get_nodes(): G.add_node(j+n, demand = 1 ) for i in problem.get_nodes(): for j in problem.get_nodes(): if i != j: G.add_edge(i,j+n, weight=problem.wfunc(i,j), capacity = n+1 ) flow = nx.min_cost_flow( G ) cost = nx.cost_of_flow(G,flow) # Retrieve list of edges in the assignment elist = [ (e[0],e[1]-n) for e in G.edges if flow[e[0]][e[1]] > 0 ] return cost, elist
def constrained_kmeans(data, demand, maxiter=None, fixedprec=1e9): data = np.array(data) min_ = np.min(data, axis=0) max_ = np.max(data, axis=0) c = min_ + np.random.random((len(demand), data.shape[1])) * (max_ - min_) m = np.array([-1] * len(data), dtype=np.int) itercnt = 0 while True: itercnt += 1 # memberships g = nx.DiGraph() g.add_nodes_from(xrange(0, data.shape[0]), demand=-1) # points for i in xrange(0, len(c)): g.add_node(len(data) + i, demand=demand[i]) # Calculating cost... cost = np.array([np.linalg.norm( np.tile(data.T, len(c)).T - np.tile(c, len(data)).reshape(len(c) * len(data), c.shape[1]), axis=1)]) # Preparing data_to_c_edges... data_to_c_edges = np.concatenate((np.tile([xrange(0, data.shape[0])], len(c)).T, np.tile(np.array([xrange(data.shape[0], data.shape[0] + c.shape[0])]).T, len(data)).reshape(len(c) * len(data), 1), cost.T * fixedprec), axis=1).astype(np.uint64) # Adding to graph g.add_weighted_edges_from(data_to_c_edges) a = len(data) + len(c) g.add_node(a, demand=len(data) - np.sum(demand)) c_to_a_edges = np.concatenate((np.array([xrange(len(data), len(data) + len(c))]).T, np.tile([[a]], len(c)).T), axis=1) g.add_edges_from(c_to_a_edges) # Calculating min cost flow... f = nx.min_cost_flow(g) # assign m_new = np.ones(len(data), dtype=np.int) * -1 for i in xrange(len(data)): p = sorted(f[i].iteritems(), key=lambda x: x[1])[-1][0] m_new[i] = p - len(data) # stop condition if np.all(m_new == m): # Stop return c, m, f m = m_new # compute new centers for i in xrange(len(c)): c[i, :] = np.mean(data[m == i, :], axis=0) if maxiter is not None and itercnt >= maxiter: # Max iterations reached return c, m, f
def schedule(self): ''' computes a MCNF rtype: dict of dicts ''' diff = self.necessary_supply - self.necessary_demand self.network.nodes['s']['demand'] = -self.total self.network.nodes['t']['demand'] = self.total + diff return networkx.min_cost_flow(self.network)
def constrained_kmeans(data, demand, maxiter=None, fixedprec=1e9): data = np.array(data) min_ = np.min(data, axis = 0) max_ = np.max(data, axis = 0) C = min_ + np.random.random((len(demand), data.shape[1])) * (max_ - min_) M = np.array([-1] * len(data), dtype=np.int) itercnt = 0 while True: itercnt += 1 # memberships g = nx.DiGraph() g.add_nodes_from(xrange(0, data.shape[0]), demand=-1) # points for i in xrange(0, len(C)): g.add_node(len(data) + i, demand=demand[i]) # Calculating cost... cost = np.array([np.linalg.norm(np.tile(data.T, len(C)).T - np.tile(C, len(data)).reshape(len(C) * len(data), C.shape[1]), axis=1)]) # Preparing data_to_C_edges... data_to_C_edges = np.concatenate((np.tile([xrange(0, data.shape[0])], len(C)).T, np.tile(np.array([xrange(data.shape[0], data.shape[0] + C.shape[0])]).T, len(data)).reshape(len(C) * len(data), 1), cost.T * fixedprec), axis=1).astype(np.uint64) # Adding to graph g.add_weighted_edges_from(data_to_C_edges) a = len(data) + len(C) g.add_node(a, demand=len(data)-np.sum(demand)) C_to_a_edges = np.concatenate((np.array([xrange(len(data), len(data) + len(C))]).T, np.tile([[a]], len(C)).T), axis=1) g.add_edges_from(C_to_a_edges) # Calculating min cost flow... f = nx.min_cost_flow(g) # assign M_new = np.ones(len(data), dtype=np.int) * -1 for i in xrange(len(data)): p = sorted(f[i].iteritems(), key=lambda x: x[1])[-1][0] M_new[i] = p - len(data) # stop condition if np.all(M_new == M): # Stop return (C, M, f) M = M_new # compute new centers for i in xrange(len(C)): C[i, :] = np.mean(data[M==i, :], axis=0) if maxiter is not None and itercnt >= maxiter: # Max iterations reached return (C, M, f)
def remake_to_labelorder(pred_tensor: torch.tensor, label_tensor: torch.tensor) -> dict: pred_ = pred_tensor.cuda().cpu().detach().numpy().copy() pred_ = np.array([np.argmax(i) for i in pred_]) label_ = label_tensor.cuda().cpu().detach().numpy().copy() n_of_clusters = max(label_) + 1 pred_ids, label_ids = {}, {} for vid, (pred_id, label_id) in enumerate(zip(pred_, label_)): if (pred_id in pred_ids): pred_ids[pred_id].append(vid) else: pred_ids[pred_id] = [] pred_ids[pred_id].append(vid) if (label_id in label_ids): label_ids[label_id].append(vid) else: label_ids[label_id] = [] label_ids[label_id].append(vid) pred_pairs, label_pairs = [set() for _ in range(n_of_clusters) ], [set() for _ in range(n_of_clusters)] for pred_key, label_key in zip(pred_ids.keys(), label_ids.keys()): pred_pairs[pred_key] |= set( [pair for pair in itertools.combinations(pred_ids[pred_key], 2)]) label_pairs[label_key] |= set( [pair for pair in itertools.combinations(label_ids[label_key], 2)]) table = np.array( [[len(label_pair & pred_pair) for label_pair in label_pairs] for pred_pair in pred_pairs]) G = nx.DiGraph() G.add_node('s', demand=-n_of_clusters) G.add_node('t', demand=n_of_clusters) for pred_id in range(n_of_clusters): G.add_edge('s', 'p_{}'.format(pred_id), weight=0, capacity=1) for source, weights in enumerate(table): for target, w in enumerate(weights): G.add_edge('p_{}'.format(source), 'l_{}'.format(target), weight=-w, capacity=1) for label_id in range(n_of_clusters): G.add_edge('l_{}'.format(label_id), 't', weight=0, capacity=1) clus_label_map = {} result = nx.min_cost_flow(G) for i, d in result.items(): for j, f in d.items(): if f and i[0] == 'p' and j[0] == 'l': clus_label_map[int(i[2])] = int(j[2]) w = torch.FloatTensor( [[1 if j == clus_label_map[i] else 0 for j in range(n_of_clusters)] for i in range(n_of_clusters)]).cuda() return torch.mm(pred_tensor, w)
def getConsumerDicts(self, start, stop): consumerDicts = [] for currentSlice in range(start, stop): _demands, _locations, _ids = self.getTimeSliceData(currentSlice) G = self.generateGraph(_demands, _locations, _ids) _flowDict = nx.min_cost_flow(G) _consumerDict = self.flowToConsumerDict(_flowDict, G) _consumerDict['graph'] = G _consumerDict['flowDict'] = _flowDict consumerDicts.append(_consumerDict) return consumerDicts
def get_flow_per_edge(idle_drivers, arriving_drivers, expected_orders, superworld): ''' :param idle_drivers: a vector of idle drivers per supernode in the current time step :param arriving_drivers: a vector of drivers that arrive due to customers in the next time step :param expected_orders: a vector of number of orders expected in the next time step :param superworld: a superworld :returns: a dict keyed by [node1][node2] with number of cars to be travelled ''' directed_superworld = nx.DiGraph(superworld) idle_drivers = np.array(idle_drivers) arriving_drivers = np.array(arriving_drivers) expected_orders = np.array(expected_orders) assert np.sum(idle_drivers) > 0 if np.sum(expected_orders) == 0: expected_orders = np.ones( expected_orders.shape) # aim for a uniform driver distribution expected_orders = expected_orders / np.sum(expected_orders) total_drivers_with_arriving = np.sum(idle_drivers + arriving_drivers) # distribute drivers according to customers required_drivers = np.array([ int(n * total_drivers_with_arriving) for n in expected_orders ]) # rounds down required_drivers -= arriving_drivers # substract those we can not control # we might end up with negative values, because too many are arriving at the same place, for example # or with positive, becauce of rounding up/down # randomly assign or substract excess drivers required_drivers[required_drivers < 0] = 0 total_idle_drivers = np.sum(idle_drivers) s = np.sum(required_drivers) while total_idle_drivers - s != 0: ind = np.nonzero(required_drivers) a = np.random.choice(ind[0]) required_drivers[a] += (total_idle_drivers - s) / np.abs(total_idle_drivers - s) s = np.sum(required_drivers) # set demand property on superworld graph and solve mincostflow nx.set_edge_attributes( directed_superworld, 1, name='weight') # assume approximately equal distances demand = required_drivers - idle_drivers # positive demand = inflow assert np.sum(demand) == 0 nx.set_node_attributes(directed_superworld, {i: demand[i] for i in range(len(demand))}, "demand") flow_per_edge_dict = nx.min_cost_flow(directed_superworld, demand='demand', weight='weight') return flow_per_edge_dict
def assign(photos, pois): """Assign photos to POIs with minimum cost""" #REF: en.wikipedia.org/wiki/Minimum-cost_flow_problem #assert(len(photos) == len(pois)) dists = np.zeros((len(photos), len(pois)), dtype=np.float64) for i, d in enumerate(photos): for j, p in enumerate(pois): dists[i, j] = round(math.sqrt( (d[0] - p[0])**2 + (d[1] - p[1])**2 )) #print(dists) G = nx.DiGraph() # complete bipartite graph: photo -> POI # infinity capacity for i in range(len(photos)): for j in range(len(pois)): u = 'd' + str(i) v = 'p' + str(j) G.add_edge(u, v, weight=dists[i, j]) # source -> photo # capacity = 1 for i in range(len(photos)): u = 's' v = 'd' + str(i) G.add_edge(u, v, capacity=1, weight=0) # POI -> sink # infinity capacity for j in range(len(pois)): u = 'p' + str(j) v = 't' G.add_edge(u, v, weight=0) # demand for source and sink G.add_node('s', demand=-len(photos)) G.add_node('t', demand=len(photos)) #print(G.nodes()) #print(G.edges()) flowDict = nx.min_cost_flow(G) assignment = dict() for e in G.edges(): u = e[0] v = e[1] if u != 's' and v != 't' and flowDict[u][v] > 0: #print(e, flowDict[u][v]) assignment[u] = v return assignment
def make_pred_label_map(pred_: list, label_: list) -> dict: pred_ids, label_ids = {}, {} for vid, (pred_id, label_id) in enumerate(zip(pred_, label_)): if (pred_id in pred_ids): pred_ids[pred_id].append(vid) else: pred_ids[pred_id] = [] pred_ids[pred_id].append(vid) if (label_id in label_ids): label_ids[label_id].append(vid) else: label_ids[label_id] = [] label_ids[label_id].append(vid) pred_pairs, label_pairs = [None for _ in range(3)], [None for _ in range(3)] for pred_key, label_key in zip(pred_ids.keys(), label_ids.keys()): pred_pairs[pred_key] = set( [pair for pair in itertools.combinations(pred_ids[pred_key], 2)]) label_pairs[label_key] = set( [pair for pair in itertools.combinations(label_ids[label_key], 2)]) table = np.array( [[len(label_pair & pred_pair) for label_pair in label_pairs] for pred_pair in pred_pairs]) G = nx.DiGraph() with open('./test.csv', 'r') as r: n_preds, n_labels = table.shape[0], table.shape[1] G.add_node('s', demand=-n_preds) G.add_node('t', demand=n_labels) for pred_id in range(n_preds): G.add_edge('s', 'p_{}'.format(pred_id), weight=0, capacity=1) for source, weights in enumerate(table): for target, w in enumerate(weights): G.add_edge('p_{}'.format(source), 'l_{}'.format(target), weight=-w, capacity=1) for label_id in range(n_labels): G.add_edge('l_{}'.format(label_id), 't', weight=0, capacity=1) clus_label_map = {} result = nx.min_cost_flow(G) for i, d in result.items(): for j, f in d.items(): if f and i[0] == 'p' and j[0] == 'l': clus_label_map[int(i[2])] = int(j[2]) return clus_label_map
def test_simple_digraph(self): G = nx.DiGraph() G.add_node('a', demand=-5) G.add_node('d', demand=5) G.add_edge('a', 'b', weight=3, capacity=4) G.add_edge('a', 'c', weight=6, capacity=10) G.add_edge('b', 'd', weight=1, capacity=9) G.add_edge('c', 'd', weight=2, capacity=5) flowCost, H = nx.network_simplex(G) soln = {'a': {'b': 4, 'c': 1}, 'b': {'d': 4}, 'c': {'d': 1}, 'd': {}} assert_equal(flowCost, 24) assert_equal(nx.min_cost_flow_cost(G), 24) assert_equal(H, soln) assert_equal(nx.min_cost_flow(G), soln) assert_equal(nx.cost_of_flow(G, H), 24)
def get_path(self): new_G = self._add_end_node() flow_dict = nx.min_cost_flow(new_G) path = [] before_node_name = "s" while True: edges = flow_dict[before_node_name] for node_name, flow in edges.items(): if flow == 1: if node_name == "e": return path node = self.nodes_dict[node_name] path.append(node.data["bbox"]) before_node_name = node_name break
def test_transshipment(self): G = nx.DiGraph() G.add_node("a", demand=1) G.add_node("b", demand=-2) G.add_node("c", demand=-2) G.add_node("d", demand=3) G.add_node("e", demand=-4) G.add_node("f", demand=-4) G.add_node("g", demand=3) G.add_node("h", demand=2) G.add_node("r", demand=3) G.add_edge("a", "c", weight=3) G.add_edge("r", "a", weight=2) G.add_edge("b", "a", weight=9) G.add_edge("r", "c", weight=0) G.add_edge("b", "r", weight=-6) G.add_edge("c", "d", weight=5) G.add_edge("e", "r", weight=4) G.add_edge("e", "f", weight=3) G.add_edge("h", "b", weight=4) G.add_edge("f", "d", weight=7) G.add_edge("f", "h", weight=12) G.add_edge("g", "d", weight=12) G.add_edge("f", "g", weight=-1) G.add_edge("h", "g", weight=-10) flowCost, H = nx.network_simplex(G) soln = { "a": {"c": 0}, "b": {"a": 0, "r": 2}, "c": {"d": 3}, "d": {}, "e": {"r": 3, "f": 1}, "f": {"d": 0, "g": 3, "h": 2}, "g": {"d": 0}, "h": {"b": 0, "g": 0}, "r": {"a": 1, "c": 1}, } assert flowCost == 41 assert nx.min_cost_flow_cost(G) == 41 assert H == soln assert nx.min_cost_flow(G) == soln assert nx.cost_of_flow(G, H) == 41 flowCost, H = nx.capacity_scaling(G) assert flowCost == 41 assert nx.cost_of_flow(G, H) == 41 assert H == soln
def nxGraph(self, data): bs = data.shape[0] G = nx.DiGraph() G.add_node('s', demand=-int(bs ** 2 / 2)) G.add_node('t', demand=int(bs ** 2 / 2)) names = [] for i in range(bs): G.add_edge('s', 'row' + str(i), capacity=self.topk, weight=0) G.add_edge('col' + str(i), 't', capacity=self.topk, weight=0) for j in range(bs): G.add_edge('row' + str(i), 'col' + str(j), capacity=1, weight=data[i, j].numpy()) names.append('row' + str(i)) dictMinFLow = nx.min_cost_flow(G) mask = [] for w in names: mask.append(list(dictMinFLow[w].values())) return np.array(mask)
def execute(self): solution = nx.min_cost_flow(self.network) print("----------------- networkx o-d | original event | cost ------------------") for node_origen in solution.keys(): for node_destination in solution[node_origen].keys(): print(node_origen, node_destination, "|", self.network[node_origen][node_destination]['original_events'], "|", solution[node_origen][node_destination]) print("-------------- solution arcs -----------------") for node_origen in solution.keys(): for node_destination in solution[node_origen].keys(): if solution[node_origen][node_destination] > 0 or self.network[node_origen][node_destination]['capacity'] == 0: print(node_origen, node_destination, "|", self.network[node_origen][node_destination]['original_events'], "|", solution[node_origen][node_destination]) self.network[node_origen][node_destination]['color'] = 'red' if solution[node_origen][node_destination] > 0 else 'green' print("---------------------------------------------")
def test_transshipment(self): G = nx.DiGraph() G.add_node('a', demand=1) G.add_node('b', demand=-2) G.add_node('c', demand=-2) G.add_node('d', demand=3) G.add_node('e', demand=-4) G.add_node('f', demand=-4) G.add_node('g', demand=3) G.add_node('h', demand=2) G.add_node('r', demand=3) G.add_edge('a', 'c', weight=3) G.add_edge('r', 'a', weight=2) G.add_edge('b', 'a', weight=9) G.add_edge('r', 'c', weight=0) G.add_edge('b', 'r', weight=-6) G.add_edge('c', 'd', weight=5) G.add_edge('e', 'r', weight=4) G.add_edge('e', 'f', weight=3) G.add_edge('h', 'b', weight=4) G.add_edge('f', 'd', weight=7) G.add_edge('f', 'h', weight=12) G.add_edge('g', 'd', weight=12) G.add_edge('f', 'g', weight=-1) G.add_edge('h', 'g', weight=-10) flowCost, H = nx.network_simplex(G) soln = {'a': {'c': 0}, 'b': {'a': 0, 'r': 2}, 'c': {'d': 3}, 'd': {}, 'e': {'r': 3, 'f': 1}, 'f': {'d': 0, 'g': 3, 'h': 2}, 'g': {'d': 0}, 'h': {'b': 0, 'g': 0}, 'r': {'a': 1, 'c': 1}} assert flowCost == 41 assert nx.min_cost_flow_cost(G) == 41 assert H == soln assert nx.min_cost_flow(G) == soln assert nx.cost_of_flow(G, H) == 41 flowCost, H = nx.capacity_scaling(G) assert flowCost == 41 assert nx.cost_of_flow(G, H) == 41 assert H == soln
def test_transshipment(self): G = nx.DiGraph() G.add_node('a', demand=1) G.add_node('b', demand=-2) G.add_node('c', demand=-2) G.add_node('d', demand=3) G.add_node('e', demand=-4) G.add_node('f', demand=-4) G.add_node('g', demand=3) G.add_node('h', demand=2) G.add_node('r', demand=3) G.add_edge('a', 'c', weight=3) G.add_edge('r', 'a', weight=2) G.add_edge('b', 'a', weight=9) G.add_edge('r', 'c', weight=0) G.add_edge('b', 'r', weight=-6) G.add_edge('c', 'd', weight=5) G.add_edge('e', 'r', weight=4) G.add_edge('e', 'f', weight=3) G.add_edge('h', 'b', weight=4) G.add_edge('f', 'd', weight=7) G.add_edge('f', 'h', weight=12) G.add_edge('g', 'd', weight=12) G.add_edge('f', 'g', weight=-1) G.add_edge('h', 'g', weight=-10) flowCost, H = nx.network_simplex(G) soln = {'a': {'c': 0}, 'b': {'a': 0, 'r': 2}, 'c': {'d': 3}, 'd': {}, 'e': {'r': 3, 'f': 1}, 'f': {'d': 0, 'g': 3, 'h': 2}, 'g': {'d': 0}, 'h': {'b': 0, 'g': 0}, 'r': {'a': 1, 'c': 1}} assert_equal(flowCost, 41) assert_equal(nx.min_cost_flow_cost(G), 41) assert_equal(H, soln) assert_equal(nx.min_cost_flow(G), soln) assert_equal(nx.cost_of_flow(G, H), 41) flowCost, H = nx.capacity_scaling(G) assert_equal(flowCost, 41) assert_equal(nx.cost_of_flow(G, H), 41) assert_equal(H, soln)
def MinCostFlow( dfnd, dfed, node_label="id", demand_label="demand", from_label="node1", to_label="node2", weight_label="weight", capacity_label="capacity", flow_label="flow", **kwargs, ): """ 最小費用流問題 入力 dfnd: 点のDataFrameもしくはCSVファイル名 dfed: 辺のDataFrameもしくはCSVファイル名(有向) node_label: 点IDの属性文字 demand_label: 需要の属性文字 from_label: 元点の属性文字 to_label: 先点の属性文字 weight_label: 辺の重みの属性文字 capacity_label: 辺の容量の属性文字 flow_label: 辺の流量の属性文字(結果) 出力 辺のDataFrame """ g, dfnd, dfed = graph_from_table( dfnd, dfed, True, node_label=node_label, from_label=from_label, to_label=to_label, **kwargs, ) t = nx.min_cost_flow(g, demand=demand_label, capacity=capacity_label, weight=weight_label) dftmp = pd.DataFrame( [(i, j, f) for i, d in t.items() for j, f in d.items() if f], columns=[from_label, to_label, flow_label], ) return pd.merge(dfed, dftmp)
def resolver_pfmc(abastecimiento, encuentro, transporte, inventario) : abastecimientos = abrir(f"Instancias/{abastecimiento}") encuentros = abrir(f"Instancias/{encuentro}") transporte = abrir (f"Instancias/{transporte}") inventario = abrir (f"Instancias/{inventario}") #crea un grafo con los datos de las intancias G = crear_grafo(abastecimientos,encuentros,transporte,inventario) flowDict = nx.min_cost_flow(G) """BONUS: grafica con solo los nodos""" grafico = Graficar(G,solo_nodos=True) grafico.title("Representacion Completa Solo Nodos") grafico.savefig("representacion_completa_solo_nodos.png") grafico.show() flow_to_xlsx(flowDict,"Resultado.xlsx") #guarda el resultado en el archivo resultado.txt with open('resultado.txt', 'w') as outfile: json.dump(flowDict, outfile) return flowDict
def test_simple_digraph(self): G = nx.DiGraph() G.add_node('a', demand = -5) G.add_node('d', demand = 5) G.add_edge('a', 'b', weight = 3, capacity = 4) G.add_edge('a', 'c', weight = 6, capacity = 10) G.add_edge('b', 'd', weight = 1, capacity = 9) G.add_edge('c', 'd', weight = 2, capacity = 5) flowCost, H = nx.network_simplex(G) soln = {'a': {'b': 4, 'c': 1}, 'b': {'d': 4}, 'c': {'d': 1}, 'd': {}} assert_equal(flowCost, 24) assert_equal(nx.min_cost_flow_cost(G), 24) assert_equal(H, soln) assert_equal(nx.min_cost_flow(G), soln) assert_equal(nx.cost_of_flow(G, H), 24)
def bend(self): """ Computes a minimal size set of edge bends that allows the link diagram to be embedded orthogonally. This follows directly Tamassia's first paper. """ N = self.face_network flow = networkx.min_cost_flow(N) for a, flows in flow.iteritems(): for b, w_a in flows.iteritems(): if w_a and set(['s', 't']).isdisjoint(set([a, b])): w_b = flow[b][a] A, B = self[a], self[b] e_a, e_b = A.edge_of_intersection(B) turns_a = w_a*[1] + w_b*[-1] turns_b = w_b*[1] + w_a*[-1] subdivide_edge(e_a, len(turns_a)) A.bend(e_a, turns_a) B.bend(e_b, turns_b)
def test_simple_digraph(self): G = nx.DiGraph() G.add_node('a', demand=-5) G.add_node('d', demand=5) G.add_edge('a', 'b', weight=3, capacity=4) G.add_edge('a', 'c', weight=6, capacity=10) G.add_edge('b', 'd', weight=1, capacity=9) G.add_edge('c', 'd', weight=2, capacity=5) flowCost, H = nx.network_simplex(G) soln = {'a': {'b': 4, 'c': 1}, 'b': {'d': 4}, 'c': {'d': 1}, 'd': {}} assert flowCost == 24 assert nx.min_cost_flow_cost(G) == 24 assert H == soln assert nx.min_cost_flow(G) == soln assert nx.cost_of_flow(G, H) == 24 flowCost, H = nx.capacity_scaling(G) assert flowCost == 24 assert nx.cost_of_flow(G, H) == 24 assert H == soln
def test_simple_digraph(self): G = nx.DiGraph() G.add_node("a", demand=-5) G.add_node("d", demand=5) G.add_edge("a", "b", weight=3, capacity=4) G.add_edge("a", "c", weight=6, capacity=10) G.add_edge("b", "d", weight=1, capacity=9) G.add_edge("c", "d", weight=2, capacity=5) flowCost, H = nx.network_simplex(G) soln = {"a": {"b": 4, "c": 1}, "b": {"d": 4}, "c": {"d": 1}, "d": {}} assert flowCost == 24 assert nx.min_cost_flow_cost(G) == 24 assert H == soln assert nx.min_cost_flow(G) == soln assert nx.cost_of_flow(G, H) == 24 flowCost, H = nx.capacity_scaling(G) assert flowCost == 24 assert nx.cost_of_flow(G, H) == 24 assert H == soln
def print_stats(G): try: calculate_demand(G) print("min_cost_flow") # https://networkx.github.io/documentation/stable/reference/algorithms/generated/networkx.algorithms.flow.min_cost_flow.html#networkx.algorithms.flow.min_cost_flow # demand maybe from strongly_connected_components print(nx.min_cost_flow(G, capacity="inverse_weight", weight="weight")) print("pagerank") print(nx.pagerank(G)) print("average_node_connectivity") print(nx.average_node_connectivity(G)) print("dominating_set") print(nx.dominating_set(G)) print("strongly_connected_components") print(list(nx.strongly_connected_components(G))) except Exception: pass
def test_transshipment(self): G = nx.DiGraph() G.add_node('a', demand = 1) G.add_node('b', demand = -2) G.add_node('c', demand = -2) G.add_node('d', demand = 3) G.add_node('e', demand = -4) G.add_node('f', demand = -4) G.add_node('g', demand = 3) G.add_node('h', demand = 2) G.add_node('r', demand = 3) G.add_edge('a', 'c', weight = 3) G.add_edge('r', 'a', weight = 2) G.add_edge('b', 'a', weight = 9) G.add_edge('r', 'c', weight = 0) G.add_edge('b', 'r', weight = -6) G.add_edge('c', 'd', weight = 5) G.add_edge('e', 'r', weight = 4) G.add_edge('e', 'f', weight = 3) G.add_edge('h', 'b', weight = 4) G.add_edge('f', 'd', weight = 7) G.add_edge('f', 'h', weight = 12) G.add_edge('g', 'd', weight = 12) G.add_edge('f', 'g', weight = -1) G.add_edge('h', 'g', weight = -10) flowCost, H = nx.network_simplex(G) soln = {'a': {'c': 0}, 'b': {'a': 0, 'r': 2}, 'c': {'d': 3}, 'd': {}, 'e': {'r': 3, 'f': 1}, 'f': {'d': 0, 'g': 3, 'h': 2}, 'g': {'d': 0}, 'h': {'b': 0, 'g': 0}, 'r': {'a': 1, 'c': 1}} assert_equal(flowCost, 41) assert_equal(nx.min_cost_flow_cost(G), 41) assert_equal(H, soln) assert_equal(nx.min_cost_flow(G), soln) assert_equal(nx.cost_of_flow(G, H), 41)
def grafico_pfmc(): #le cambie los valores para que tuviera solucion encuentros = {'e0': {'t0': 22, 't1': 16}, 'e1': {'t0': 34, 't1': 26}} abastecimientos = {'a0': {'t0': 720, 't1': 586}, 'a1': {'t0': 561, 't1': 985}} transporte = {'a0': {'e0': (5, 32), 'e1': (6, 43)},'a1': {'e0': (7, 67), 'e1': (8, 36)}} inventario = {'a0': (0, 427), 'a1': (0, 445)} G = crear_grafo(abastecimientos,encuentros,transporte,inventario) grafico = Graficar(G) grafico.title("Representacion Simple") grafico.savefig("representacion_simple.png") grafico.show() """ Bonus: Esto resuleve el PFMC del ejemplo chico y lo grafica, podria mostrar las cantidades de flujo en el grafico pero no nos dan puntaje por eso""" flowDict = nx.min_cost_flow(G) flow_to_xlsx(flowDict,"Resultado Simple.xlsx") #lo paso a excel with open('resultado_simple.txt', 'w') as outfile: # y a txt pot si acaso json.dump(flowDict, outfile) grafico = Graficar(G,flowDict) grafico.title("Solucion Simple") grafico.savefig("solucion_simple.png") grafico.show()
def test_digraph1(self): # From Bradley, S. P., Hax, A. C. and Magnanti, T. L. Applied # Mathematical Programming. Addison-Wesley, 1977. G = nx.DiGraph() G.add_node(1, demand=-20) G.add_node(4, demand=5) G.add_node(5, demand=15) G.add_edges_from( [ (1, 2, {"capacity": 15, "weight": 4}), (1, 3, {"capacity": 8, "weight": 4}), (2, 3, {"weight": 2}), (2, 4, {"capacity": 4, "weight": 2}), (2, 5, {"capacity": 10, "weight": 6}), (3, 4, {"capacity": 15, "weight": 1}), (3, 5, {"capacity": 5, "weight": 3}), (4, 5, {"weight": 2}), (5, 3, {"capacity": 4, "weight": 1}), ] ) flowCost, H = nx.network_simplex(G) soln = { 1: {2: 12, 3: 8}, 2: {3: 8, 4: 4, 5: 0}, 3: {4: 11, 5: 5}, 4: {5: 10}, 5: {3: 0}, } assert flowCost == 150 assert nx.min_cost_flow_cost(G) == 150 assert H == soln assert nx.min_cost_flow(G) == soln assert nx.cost_of_flow(G, H) == 150 flowCost, H = nx.capacity_scaling(G) assert flowCost == 150 assert H == soln assert nx.cost_of_flow(G, H) == 150
def is_flow_feasible(m, ResMastery, SkillReq, SkillSet): Resources = range(m) # initialise directed graph to run flow algorithm on G = nx.DiGraph() G.add_node('s', demand=-np.sum(SkillReq)) # source G.add_node('t', demand= np.sum(SkillReq)) # sink # pdb.set_trace() UsefulRes = find_useful_resources(Resources, ResMastery, SkillSet) # define resource nodes and edges from the source to resources for res in UsefulRes: G.add_node(res, demand=0) G.add_edge('s', res, weight=0, capacity=1) # define required skill nodes and edges from skills to sink node for skill in SkillSet: # offset the index by the # of res G.add_node(skill+m, demand=0) G.add_edge(skill+m, 't', weight=0, capacity=SkillReq[skill]) # define the edges between the resource and the skill nodes for res in Resources: for skill in SkillSet: if ResMastery[res][skill] == 1: G.add_edge(res, skill+m, weight=0, capacity=1) # pdb.set_trace() try: flowDict = nx.min_cost_flow(G) except nx.exception.NetworkXUnfeasible: return False return True
def constrcut_flow_graph(reach_graph,sorted_bbox,flow_graph=None,scores=None): def to_left_node(index): return 2*index+1 def to_right_node(index): return 2*index+2 def scale_to_int(score): MAX_VALUE = 10000 return int(score*MAX_VALUE) def compute_box_center(box): center_y = (box[3]+box[1])/2 center_x = (box[2]+box[0])/2 return center_x,center_y def get_data_cost(score): return scale_to_int(score) def get_smoothness_cost(box1, box2): alpha=0.0 h1=box1[3]-box1[1]+1 h2=box2[3]-box2[1]+1 x1, y1=compute_box_center(box1) x2, y2=compute_box_center(box2) d=((x1-x2)**2+(y1-y2)**2)**0.5/min(h1,h2) s=float(abs(h1-h2))/min(h1, h2) return scale_to_int(alpha*d+(1-alpha)*s) def get_entry_cost(index,reach_graph,scores): reach_node_costs = [scores[left] for left, right in reach_graph.edges() if right == index] sorted_costs = sorted(reach_node_costs) if len(sorted_costs) > 0: cost = scale_to_int(-sorted_costs[-1]) else: cost = 0 return cost def get_exit_cost(index,reach_graph,scores): reach_node_costs = [scores[right] for left, right in reach_graph.edges() if left == index] sorted_costs = sorted(reach_node_costs) if len(sorted_costs) > 0: cost = scale_to_int(-sorted_costs[-1]) else: cost = 0 return cost def overlaps(box1,box2): h1=box1[3]-box1[1]+1 h2=box2[3]-box2[1]+1 overlaps=min(box2[3], box1[3])-max(box1[1], box2[1]) overlaps=overlaps if overlaps>0 else 0 return float(overlaps)/h2 length = len(sorted_bbox) scores = [-1 for i in range(length)] if flow_graph == None: #box print 'construct graph' flow_graph = nx.DiGraph() ENTRY_NODE = -1 flow_graph.add_node(ENTRY_NODE,demand = -1) EXIT_NODE = -2 flow_graph.add_node(EXIT_NODE,demand = 1) # data cost for index in range(length): left_node = to_left_node(index) right_node = to_right_node(index) flow_graph.add_node(left_node) flow_graph.add_node(right_node) data_cost = get_data_cost(scores[index]) flow_graph.add_edge(left_node,right_node,weight=data_cost,capacity = 1) # smoothness cost for left,right in reach_graph.edges(): left_node = to_right_node(left) right_node = to_left_node(right) smoothness_cost = get_smoothness_cost(sorted_bbox[left],sorted_bbox[right]) flow_graph.add_edge(left_node,right_node,weight=smoothness_cost,capacity = 1) # entry cost for index in range(length): entry_cost = get_entry_cost(index,reach_graph,scores) left_node = to_left_node(index) flow_graph.add_edge(ENTRY_NODE,left_node,weight=entry_cost,capacity = 1) # exit cost for index in range(length): exit_cost = get_exit_cost(index,reach_graph,scores) right_node = to_right_node(index) flow_graph.add_edge(right_node,EXIT_NODE,weight=exit_cost,capacity = 1) box_inds=[] flowDict = nx.min_cost_flow(flow_graph) flowCost = nx.min_cost_flow_cost(flow_graph) for index in range(length): left_node=to_left_node(index) right_node=to_right_node(index) try: find = [node for node, value in flowDict[left_node].iteritems() if value == 1] except: find = [] if len(find)>0: box_inds.append(index) # find node overlaps over 0.5 remove_inds = box_inds ''' for index in box_inds: print index node_neighbor_right = [right for left, right in reach_graph.edges() if left == index] node_neighbor_left = [left for left, right in reach_graph.edges() if right == index] for node_index in node_neighbor_right: if overlaps(sorted_bbox[node_index],sorted_bbox[index]) > 0.5: remove_inds.append(node_index) for node_index in node_neighbor_left: if overlaps(sorted_bbox[node_index],sorted_bbox[index]) > 0.5: remove_inds.append(node_index) ''' # remove node for next iteration for index in remove_inds: left_node = to_right_node(index) right_node = to_left_node(index) if left_node > 0: flow_graph.remove_node(left_node) if right_node > 0: flow_graph.remove_node(right_node) return box_inds,flowCost,flow_graph
total += int(exits) - int(entries) for n in G.nodes(): if "demand" not in G.node[n]: G.remove_node(n) turnstile_stations = [record.strip().split(',')[2] for record in noondata] gtfs_stations = G.nodes() #print set(turnstile_stations) - set(gtfs_stations) extra_nodes = set(gtfs_stations) - set(turnstile_stations) nx.draw_spring(G, with_labels=True, node_color='w', node_size=350, font_size=7) #plt.show() flow = nx.min_cost_flow(G) inflowstation=[] inflow=[] for x in G.nodes(): total = 0 inflowstation.append(x) for p in G.predecessors(x): total = total+ flow[p][x] inflow.append(total) rows = zip(inflowstation,inflow) length= range(0,len(inflowstation))
y = [ func(xx) for xx in x ] plt.figure() plt.plot(x,y) plt.show() def FLOWCOST( flow, cost ) : res = [ cc( flow.get( e, 0. ) ) for e, cc in cost.iteritems() ] # big difference! #res = [ cost.get( e, line(0.) )( flow[e] ) for e in flow ] return sum( res ) def FEAS( flow, capacity, network ) : for e in network.edges() : if flow.get(e, 0. ) > capacity.get(e, np.Inf ) : return False return True flow = MinConvexCostFlow( g, u, supply, cf, epsilon=.001 ) print ( flow, FLOWCOST( flow, cf ), FEAS( flow, u, g ) ) flowstar = { 'b' : 10., 'd' : 10. } print ( flowstar, FLOWCOST( flowstar, cf ), FEAS( flowstar, u, g ) ) digraph = mincostflow_nx( g, u, supply, c ) compare = nx.min_cost_flow( digraph )
# Let's now solve for the min-cost flow of the example we had in class. We have already added capacities and demands to our network. We finally need to introduce edge costs (weights). # In[10]: G.edge['s']['u']['weight'] = 1 G.edge['s']['v']['weight'] = 1 G.edge['u']['v']['weight'] = 1 G.edge['u']['t']['weight'] = 1 G.edge['v']['t']['weight'] = 2 # Now we can just call the min-cost flow function. Note that we could have used this to solve the flow-with-demands problem, just by setting all the costs (weights) to 0. # In[11]: minimum_cost_flow = nx.min_cost_flow(G) print_flow(minimum_cost_flow) # This is the same as the maximum flow found in class. For this example, the maximum flow is unique. # ## Exercises # # 1. Construct the bipartite graph from the example application in the slides and find a matching using max flow. # # 2. Write a function to compute a conformal decomposition of a flow with demands, and run it on the flows found in the "Min-Cost Flow" section above. # ### Solution 1 # # For the first problem, we form the network by hand then solve max flow using new source and sink vertices, imposing a capacity of 1 on all edges.