def assign_IP(scores, K=None, advs_rank=None): num_paper, num_reviewer, input_dir, max_pc_quota, hashed_ratio = get_global_variable() a = 1e-6 (num_paper, num_reviewer) = scores.shape scores = scores.copy() min_cost_flow = pywrapgraph.SimpleMinCostFlow() if K is None: for i in range(num_paper): for j in range(num_reviewer): min_cost_flow.AddArcWithCapacityAndUnitCost(i, j + num_paper, 1, -int(scores[i, j] / a)) else: for i in range(num_paper): top_K_rev = np.argsort(-scores[i])[:K] for rank, j in enumerate(top_K_rev): if advs_rank is not None: if advs_rank[i, rank] >= K: continue min_cost_flow.AddArcWithCapacityAndUnitCost(i, j.item() + num_paper, 1, -int(scores[i, j] / a)) for j in range(num_reviewer): min_cost_flow.AddArcWithCapacityAndUnitCost(j + num_paper, num_paper + num_reviewer, max_pc_quota, 0) for i in range(num_paper): min_cost_flow.SetNodeSupply(i, 3) min_cost_flow.SetNodeSupply(num_paper + num_reviewer, - 3 * num_paper) min_cost_flow.Solve() assignment = np.zeros([num_paper, num_reviewer]) for i in range(0, min_cost_flow.NumArcs()): if min_cost_flow.Head(i) == num_paper + num_reviewer: continue if min_cost_flow.Flow(i) > 0: assignment[min_cost_flow.Tail(i), min_cost_flow.Head(i) - num_paper] = 1 return assignment
def _refresh_internal_vars(self): """Set start, end, caps, costs to be empty.""" self.min_cost_flow = pywrapgraph.SimpleMinCostFlow() self.start_inds = [] self.end_inds = [] self.caps = [] self.costs = []
def __init__(self, left, right, filter_class=mapnames.string.SuffixArray): """ :param left: left set of elements :param right: right set of elements :param filter_class: a callable class to build filters for left and right sets (so the constructor will be called with them). Upon called with a string, must return a list of indexes of candidates to compare to that string. """ super().__init__() self.n = len(left) self.flow = ortg.SimpleMinCostFlow() self.solve_status = None self.source, self.sink = 0, 2 * self.n + 1 # numbering shift required by Google's library self.l_idx_shift, self.r_idx_shift = 1, self.n + 1 if filter_class is not None: self.filter_on_left = filter_class(left) self.filter_on_right = filter_class(right) self.left = np.array( [Vertex(left[l], l + self.l_idx_shift) for l in range(len(left))]) self.right = np.array([ Vertex(right[r], r + self.r_idx_shift) for r in range(len(right)) ])
def _construct_graph_and_solve(self, n_rev, n_pap, _caps, _covs, ws, flow): """Flow graph""" start_inds = [] end_inds = [] caps = [] costs = [] source = n_rev + n_pap sink = n_rev + n_pap + 1 # edges from source to revs. for i in range(n_rev): start_inds.append(source) end_inds.append(i) caps.append(int(_caps[i])) costs.append(0) # edges from rev to pap. for i in range(n_rev): for j in range(n_pap): start_inds.append(i) end_inds.append(n_rev + j) if self.solution[i, j] == 1: caps.append(0) else: caps.append(1) # Costs must be integers. Also, we have affinities so make # the "costs" negative affinities. costs.append(int(-1.0 - 10000 * ws[i, j])) # edges from pap to sink. for j in range(n_pap): start_inds.append(n_rev + j) end_inds.append(sink) caps.append(int(_covs[j])) costs.append(0) supplies = np.zeros(n_rev + n_pap + 2) supplies[source] = int(flow) supplies[sink] = int(-flow) # Add arcs. mcf = pywrapgraph.SimpleMinCostFlow() for i in range(len(start_inds)): mcf.AddArcWithCapacityAndUnitCost(start_inds[i], end_inds[i], caps[i], costs[i]) for i in range(len(supplies)): mcf.SetNodeSupply(i, int(supplies[i])) # Solve. if mcf.Solve() == mcf.OPTIMAL: for arc in range(mcf.NumArcs()): # Can ignore arcs leading out of source or into sink. if mcf.Tail(arc) != source and mcf.Head(arc) != sink: if mcf.Flow(arc) > 0: rev = mcf.Tail(arc) pap = mcf.Head(arc) - n_rev self.solution[rev, pap] = 1.0 self.solved = True else: print('There was an issue with the min cost flow input.')
def main(): # The network consists of edges (s, t) with capacity c and unit costs u. s = [ 0, 0, 1, 1, 1, 2, 2, 3, 4] t = [ 1, 2, 2, 3, 4, 3, 4, 4, 2] c = [15, 8, 20, 4, 10, 15, 4, 20, 5] u = [ 4, 4, 2, 2, 6, 1, 3, 2, 3] # Each node can be either a supply node or a demand node. A demand is # depicted by a negative supply. supplies = [20, 0, 0, -5, -15] solver = pywrapgraph.SimpleMinCostFlow() for i in range(len(s)): solver.AddArcWithCapacityAndUnitCost(s[i], t[i], c[i], u[i]) for i in range(len(supplies)): solver.SetNodeSupply(i, supplies[i]) status = solver.Solve() if status == solver.OPTIMAL: print(f'Min cost: {solver.OptimalCost()}') print() print(' Arc Flow / Capacity Cost') for i in range(solver.NumArcs()): cost = solver.Flow(i) * solver.UnitCost(i) print(f'{solver.Tail(i)} -> {solver.Head(i)} {solver.Flow(i)} / {solver.Capacity(i)} {cost}') else: print('The solver could not find a min cost flow.') print(f'status = {solver.StatusName(status)}')
def build_network(self, images={}, f2i_factor=10000): self.mcf = pywrapgraph.SimpleMinCostFlow() for image_name, rects in sorted(self._detections.items()): for i, rect in enumerate(rects): self.mcf.AddArcWithCapacityAndUnitCost( self._node2id["source"], self._node2id[(image_name, i, "u")], 1, int(self._calc_cost_enter() * f2i_factor)) self.mcf.AddArcWithCapacityAndUnitCost( self._node2id[(image_name, i, "u")], self._node2id[(image_name, i, "v")], 1, int(self._calc_cost_detection(rect[4]) * f2i_factor)) self.mcf.AddArcWithCapacityAndUnitCost( self._node2id[(image_name, i, "v")], self._node2id["sink"], 1, int(self._calc_cost_exit() * f2i_factor)) frame_id = self._name2id[image_name] if frame_id == 0: continue prev_image_name = self._id2name[frame_id - 1] if prev_image_name not in self._detections: continue for i, i_rect in enumerate(self._detections[prev_image_name]): for j, j_rect in enumerate(rects): self.mcf.AddArcWithCapacityAndUnitCost( self._node2id[(prev_image_name, i, "v")], self._node2id[(image_name, j, "u")], 1, int( self._calc_cost_link(images[prev_image_name], i_rect, images[image_name], j_rect) * 1000))
def post(self): data = request.get_json() starts = data['starts'] ends = data['ends'] costs = data['costs'] supplies = data['supplies'] capacities = data['capacities'] min_cost_flow = pywrapgraph.SimpleMinCostFlow() for i in range(len(starts)): min_cost_flow.AddArcWithCapacityAndUnitCost( starts[i], ends[i], capacities[i], costs[i]) for i in range(len(supplies)): min_cost_flow.SetNodeSupply(i, supplies[i]) if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: response = {'total': min_cost_flow.OptimalCost(), 'arcs': []} for arc in range(min_cost_flow.NumArcs()): if min_cost_flow.Flow(arc) > 0: response['arcs'].append({ 'arc': arc, 'tail': min_cost_flow.Tail(arc), 'head': min_cost_flow.Head(arc), 'cost': min_cost_flow.UnitCost(arc) }) return jsonify(response) else: raise ExceptionHandler(message="No solution found", status_code=400)
def MinCostFlow(): """MinCostFlow simple interface example. Note that this example is actually a linear sum assignment example and will be more efficiently solved with the pywrapgraph.LinearSumAssignement class. """ print('MinCostFlow on 4x4 matrix.') num_sources = 4 num_targets = 4 costs = [[90, 75, 75, 80], [35, 85, 55, 65], [125, 95, 90, 105], [45, 110, 95, 115]] expected_cost = 275 min_cost_flow = pywrapgraph.SimpleMinCostFlow() for source in range(0, num_sources): for target in range(0, num_targets): min_cost_flow.AddArcWithCapacityAndUnitCost( source, num_sources + target, 1, costs[source][target]) for node in range(0, num_sources): min_cost_flow.SetNodeSupply(node, 1) min_cost_flow.SetNodeSupply(num_sources + node, -1) status = min_cost_flow.Solve() if status == min_cost_flow.OPTIMAL: print('Total flow', min_cost_flow.OptimalCost(), '/', expected_cost) for i in range(0, min_cost_flow.NumArcs()): if min_cost_flow.Flow(i) > 0: print('From source %d to target %d: cost %d' % (min_cost_flow.Tail(i), min_cost_flow.Head(i) - num_sources, min_cost_flow.UnitCost(i))) else: print('There was an issue with the min cost flow input.')
def exo5(): #start_nodes = [1,1,1,2,2,3,3,4,4,5,5,5,6,7,7,8,9,10,11,11] #end_nodes = [3,5,6,5,6,4,5,8,9,8,9,10,7,9,10,12,12,12,1,2] #capacities = [17,14,0,6,15,7,10,7,0,10,5,15,15,5,10,17,15,20,31,21] #unit_costs = [20,15,12,6,22,15,10,7,10,10,15,15,22,10,10,18,15,20,35,25] #supplies = [1,2,3,4,5,6,7,8,9,10,11,12] start_nodes = [ 0, 0, 1, 1, 1, 2, 2, 3, 4] end_nodes = [ 1, 2, 2, 3, 4, 3, 4, 4, 2] capacities = [15, 8, 20, 4, 10, 15, 4, 20, 5] unit_costs = [ 4, 4, 2, 2, 6, 1, 3, 2, 3] supplies = [20, 0, 0, -5, -15] min_cost_flow = pywrapgraph.SimpleMinCostFlow() for i in range(0, len(start_nodes)): min_cost_flow.AddArcWithCapacityAndUnitCost(start_nodes[i], end_nodes[i], capacities[i], unit_costs[i]) for i in range(0, len(supplies)): min_cost_flow.SetNodeSupply(i, supplies[i]) if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: print('Minimum cost:', min_cost_flow.OptimalCost()) print('') print(' Arc Flow / Capacity Cost') for i in range(min_cost_flow.NumArcs()): cost = min_cost_flow.Flow(i) * min_cost_flow.UnitCost(i) print('%1s -> %1s %3s / %3s %3s' % ( min_cost_flow.Tail(i), min_cost_flow.Head(i), min_cost_flow.Flow(i), min_cost_flow.Capacity(i), cost)) else: print("Il y a eu un problème avec l'entrée du flot minimal.")
def get_matched_by_flow_clusters(first_arch, second_arch): first_clusters_labels = dict() second_clusters_labels = dict() lenA = len(first_arch.clusters) lenB = len(second_arch.clusters) while lenA > lenB: second_arch.add_dummy_cluster() lenB += 1 while lenA < lenB: first_arch.add_dummy_cluster() lenA += 1 i = 1 for clusterA in first_arch.clusters: first_clusters_labels[i] = clusterA i = i + 1 for clusterB in second_arch.clusters: second_clusters_labels[i] = clusterB i = i + 1 min_cost_flow = pywrapgraph.SimpleMinCostFlow() for start, c1 in first_clusters_labels.items(): for end, c2 in second_clusters_labels.items(): c1_set = set(c1.classes) c2_set = set(c2.classes) cost = len(c1_set.union(c2_set) - c1_set.intersection(c2_set)) min_cost_flow.AddArcWithCapacityAndUnitCost(start, end, 1, cost) for start in first_clusters_labels: min_cost_flow.AddArcWithCapacityAndUnitCost(0, start, 1, 0) for start in second_clusters_labels: min_cost_flow.AddArcWithCapacityAndUnitCost(start, i + 1, 1, 0) min_cost_flow.SetNodeSupply(0, len(first_clusters_labels)) min_cost_flow.SetNodeSupply(i + 1, -len(second_clusters_labels)) matched_clusters = [] if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: print('Minimum cost:', min_cost_flow.OptimalCost()) print('') # print(' Edge Flow / Capacity Cost') for i in range(min_cost_flow.NumArcs()): cost = min_cost_flow.Flow(i) * min_cost_flow.UnitCost(i) if cost != 0: # print('%1s -> %1s %3s / %3s %3s' % ( # min_cost_flow.Tail(i), # min_cost_flow.Head(i), # min_cost_flow.Flow(i), # min_cost_flow.Capacity(i), # cost)) head_index = min_cost_flow.Head(i) tail_index = min_cost_flow.Tail(i) matched_clusters.append((first_clusters_labels[tail_index], second_clusters_labels[head_index])) else: print('There was an issue with the min cost flow input.') return matched_clusters
def optimize(): min_cost_flow = pywrapgraph.SimpleMinCostFlow() for i in range(0, len(START_NODES)): min_cost_flow.AddArcWithCapacityAndUnitCost(START_NODES[i], END_NODES[i], CAPACITIES[i], UNIT_COSTS[i]) min_cost_flow.SetNodeSupply(SOURCE_NODE_INDEX, 100) min_cost_flow.SetNodeSupply(SINK_NODE_INDEX, -100) s = min_cost_flow.SolveMaxFlowWithMinCost() if s == min_cost_flow.OPTIMAL: for i in range(min_cost_flow.NumArcs()): schoolNode = min_cost_flow.Tail(i) dateNode = min_cost_flow.Head(i) flow = min_cost_flow.Flow(i) if (schoolNode != SOURCE_NODE_INDEX and dateNode != SINK_CONSTRAINT_INDEX and flow == 1): schoolName = nodeSchoolMapping[schoolNode] date = nodeDateMapping[dateNode] print("%7s | %s" % (date, schoolName)) else: print('There was an issue with the min cost flow input.') print(s)
def construct_digraph(edges_file, cap): ''' Parse a list of weighted undirected edges. Construct a weighted directed graph in which an undirected edge is represented with a pair of directed edges. Use the specified weight as the edge weight and a default capacity of 1. ''' G = pywrapgraph.SimpleMinCostFlow() idDict = dict() #Hold names to number ids curID = 0 default_capacity = int(cap) with open(edges_file) as edges_f: for line in edges_f: tokens = line.strip().split() node1 = tokens[0] if not node1 in idDict: idDict[node1] = curID curID += 1 node2 = tokens[1] if not node2 in idDict: idDict[node2] = curID curID += 1 # Google's solver can only handle int weights w = int((1-(float(tokens[2])))*100) G.AddArcWithCapacityAndUnitCost(idDict[node1],idDict[node2], default_capacity, int(w)) G.AddArcWithCapacityAndUnitCost(idDict[node2],idDict[node1], default_capacity, int(w)) idDict["maxID"] = curID return G,idDict
def main(): arc_depart = [0, 0, 1, 1, 1, 2, 2, 3, 4] arc_arrivee = [1, 2, 2, 3, 4, 3, 4, 4, 2] cout = [4, 4, 2, 2, 6, 1, 3, 2, 3] capa = [15, 8, 20, 4, 10, 15, 4, 20, 5] offre = [20, 0, 0, -5, -15] min_cost_flow = pywrapgraph.SimpleMinCostFlow() for i in range(0, len(arc_depart)): min_cost_flow.AddArcWithCapacityAndUnitCost(arc_depart[i], arc_arrivee[i], capa[i], cout[i]) for i in range(0, len(offre)): min_cost_flow.SetNodeSupply(i, offre[i]) # Find the minimum cost flow between node 0 and node 4. if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: print('Le cout optimal est :', min_cost_flow.OptimalCost()) print(' Arc Flot / Capacité Cout') for i in range(min_cost_flow.NumArcs()): debutArc = string.ascii_uppercase[min_cost_flow.Tail(i)] finArc = string.ascii_uppercase[min_cost_flow.Head(i)] flot = min_cost_flow.Flow(i) capacite = min_cost_flow.Capacity(i) cost = flot * min_cost_flow.UnitCost(i) print('%1s -> %1s %3s / %3s %3s' % ( debutArc, finArc, flot, capacite, cost)) else: print('Probleme avec le input.')
def mcf_cal(X, dict_dist): X = X / X.sum(axis=0) m = X * 1000000000 m = m.astype(np.int64) nb_rows, nb_classes = X.shape[0], X.shape[1] mcf = pywrapgraph.SimpleMinCostFlow() # Suppliers: distribution for j in range(nb_classes): mcf.SetNodeSupply(j + nb_rows, int(dict_dist[j])) # Rows for i in range(nb_rows): mcf.SetNodeSupply(i, -1) for j in range(nb_classes): mcf.AddArcWithCapacityAndUnitCost(j + nb_rows, i, 1, int(-m[i][j])) mcf.SolveMaxFlowWithMinCost() assignment = np.zeros(nb_rows, dtype=np.int32) for i in range(mcf.NumArcs()): if mcf.Flow(i) > 0: assignment[mcf.Head(i)] = mcf.Tail(i) - nb_rows return assignment
def compress_data(adj_matrix): n = np.shape(adj_matrix)[0] data = adj_matrix_to_edge_list(n,adj_matrix) min_cost_flow = pywrapgraph.SimpleMinCostFlow() cost = 1 n_nodes = max(max([x[0] for x in data]), max(x[1] for x in data)) + 1 for start_node, end_node, capacity in data: min_cost_flow.AddArcWithCapacityAndUnitCost(start_node, end_node, capacity, cost) for i in range(n_nodes): min_cost_flow.SetNodeSupply(i, get_net_position(data, i)) if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: print('Minimum cost:', min_cost_flow.OptimalCost()) else: print('There was an issue with the min cost flow input.') total_notional = sum([x[2] for x in data]) min_notional = sum(map(abs,[get_net_position(data,i) for i in range(n_nodes)]))/2 eliminated_notional = total_notional - min_cost_flow.OptimalCost() excess_percent = (total_notional - min_notional)/total_notional compressed_data = [[min_cost_flow.Tail(i), min_cost_flow.Head(i), min_cost_flow.Flow(i)] for i in range(min_cost_flow.NumArcs()) if min_cost_flow.Flow(i) >0] compressed_matrix = np.zeros((n,n)) for x in compressed_data: compressed_matrix[x[0],x[1]] = x[2] critical_matrix = adj_matrix - compressed_matrix return {"critical_matrix":critical_matrix, "eliminated_notional":eliminated_notional, "excess_percent": excess_percent}
def solve_min_cost_max_flow(start_nodes, end_nodes, capacities, unit_costs, supplies): min_cost_flow = pywrapgraph.SimpleMinCostFlow() ribs_len = len(start_nodes) nodes_len = len(supplies) for i in range(0, ribs_len): min_cost_flow.AddArcWithCapacityAndUnitCost(start_nodes[i], end_nodes[i], capacities[i], unit_costs[i]) for i in range(0, nodes_len): min_cost_flow.SetNodeSupply(i, supplies[i]) supplied_paths = [] if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: for i in range(min_cost_flow.NumArcs()): cost = min_cost_flow.Flow(i) * min_cost_flow.UnitCost(i) if min_cost_flow.Flow(i) > 0 and min_cost_flow.Tail( i) > 0 and min_cost_flow.Head(i) < nodes_len - 1: psw = ProviderSuplierWay(provider=min_cost_flow.Tail(i), suplier=min_cost_flow.Head(i), cost=cost, flow=min_cost_flow.Flow(i)) supplied_paths.append(psw) return min_cost_flow.OptimalCost(), supplied_paths else: return -1, supplied_paths
def minCostFlow(start_nodes,end_nodes,capacities,unit_costs,supplies): '''求解最小费用流问题''' # Instantiate a SimpleMinCostFlow solver. min_cost_flow = pywrapgraph.SimpleMinCostFlow() # Add each arc. for i in range(0, len(start_nodes)): min_cost_flow.AddArcWithCapacityAndUnitCost(start_nodes[i], end_nodes[i], capacities[i], unit_costs[i]) # Add node supplies. for i in range(0, len(supplies)): min_cost_flow.SetNodeSupply(i, supplies[i]) # Find the minimum cost flow between node 0 and node 4. if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: print('Minimum cost:', min_cost_flow.OptimalCost()) print('') print(' Arc Flow / Capacity Cost') for i in range(min_cost_flow.NumArcs()): cost = min_cost_flow.Flow(i) * min_cost_flow.UnitCost(i) print('%1s -> %1s %3s / %3s %3s' % ( min_cost_flow.Tail(i), min_cost_flow.Head(i), min_cost_flow.Flow(i), min_cost_flow.Capacity(i), cost)) else: print('There was an issue with the min cost flow input.')
def solve_mcf(h): start_n = [] end_n = [] capacities = [] unit_costs =[] supplies = [] for hh in h: (c, g) = hh start_n.append(int(c)) end_n.append(int(c3 + g)) # Capacities if c < c1: capacities.append(3) elif c < c1+c2: capacities.append(2) else: capacities.append(1) unit_costs.append(-h[hh]) # Supplies for i in range(c3): if i < c1: supplies.append(3) elif i < c1+c2: supplies.append(2) else: supplies.append(1) for j in range(c3, c3+g_n): supplies.append(-1000) # Instance min_cost_flow = pywrapgraph.SimpleMinCostFlow() #print(len(start_n),len(end_n),len(capacities),len(unit_costs),len(supplies)) # Add each arc. for i in range(0, len(start_nodes)): min_cost_flow.AddArcWithCapacityAndUnitCost(start_nodes[i], end_nodes[i], capacities[i], unit_costs[i]) # Add node supplies. for i in range(0, len(supplies)): min_cost_flow.SetNodeSupply(i, supplies[i]) # Find the minimum cost flow print('Start solve....') min_cost_flow.SolveMaxFlowWithMinCost() res1 = min_cost_flow.MaximumFlow() print('Maximum flow:', res1) res2 = min_cost_flow.OptimalCost() print('Optimal cost:', -res2 / 2000000000) print('Num arcs:', min_cost_flow.NumArcs())
def min_cost_max_flow(self, f): # f = self.max_flow() # debug_text("max flow part: {}".format(f)) self.__graph.reset_supplies() self.__graph.set_supply(self.__source, f) self.__graph.set_supply(self.__sink, -f) min_cost_flow = pywrapgraph.SimpleMinCostFlow() for edge in self.__graph.get_edges(): # debug_text(edge) min_cost_flow.AddArcWithCapacityAndUnitCost( edge.start_node, edge.end_node, edge.capacity, round(edge.cost * self.__precision)) for node in self.__graph.get_nodes(): min_cost_flow.SetNodeSupply(node.index, node.supply) self.__assigned_tasks = [[] for _ in range(self.k)] if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: # print('Total cost = ', min_cost_flow.OptimalCost()) # print() for arc in range(min_cost_flow.NumArcs()): # Can ignore arcs leading out of source or into sink. if min_cost_flow.Flow(arc) > 0: def better_node(cur_node): if cur_node == self.__source: return "source" if cur_node == self.__sink: return "sink" return cur_node u = min_cost_flow.Tail(arc) v = min_cost_flow.Head(arc) flow = min_cost_flow.Flow(arc) # debug_text("{}->{} f:{}".format(better_node(u), better_node(v), flow)) if min_cost_flow.Tail( arc) != self.__source and min_cost_flow.Head( arc) != self.__sink: # Arcs in the solution have a flow value of 1. Their start and end nodes # give an assignment of worker to task. self.__graph.set_flow(u, v, flow) if u < self.m: u = min_cost_flow.Tail(arc) v = min_cost_flow.Head(arc) flow = min_cost_flow.Flow(arc) # debug_text("{}->{} f:{}".format(better_node(u), better_node(v - self.m), flow)) self.__assigned_tasks[v - self.m].append(u) # print('Worker %d assigned to task %d. Cost = %d' % ( # min_cost_flow.Tail(arc), # min_cost_flow.Head(arc), # min_cost_flow.UnitCost(arc))) else: print('There was an issue with the min cost flow input.') res = min_cost_flow.OptimalCost() / self.__precision # debug_text('% O %', math.fabs(res - self.__last_cost), 1 / self.__precision) # debug_text('%', math.fabs(res - self.__last_cost) < 1 / self.__precision) if math.fabs(res - self.__last_cost) < 1. / self.__precision or res > self.__last_cost: self.__done = True self.__last_cost = res return res
def main(): """Solving an Assignment Problem with MinCostFlow""" # Instantiate a SimpleMinCostFlow solver. min_cost_flow = pywrapgraph.SimpleMinCostFlow() # Define the directed graph for the flow. start_nodes = [0, 0, 0, 0] + [ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 ] + [5, 6, 7, 8] end_nodes = [1, 2, 3, 4] + [ 5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8 ] + [9, 9, 9, 9] capacities = [1, 1, 1, 1] + [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] + [1, 1, 1, 1] costs = ( [0, 0, 0, 0] + [90, 76, 75, 70, 35, 85, 55, 65, 125, 95, 90, 105, 45, 110, 95, 115] + [0, 0, 0, 0]) # Define an array of supplies at each node. supplies = [4, 0, 0, 0, 0, 0, 0, 0, 0, -4] source = 0 sink = 9 tasks = 4 # Add each arc. for i in range(len(start_nodes)): min_cost_flow.AddArcWithCapacityAndUnitCost(start_nodes[i], end_nodes[i], capacities[i], costs[i]) # Add node supplies. for i in range(len(supplies)): min_cost_flow.SetNodeSupply(i, supplies[i]) # Find the minimum cost flow between node 0 and node 10. if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: print('Total cost = ', min_cost_flow.OptimalCost()) print() for arc in range(min_cost_flow.NumArcs()): # Can ignore arcs leading out of source or into sink. if min_cost_flow.Tail(arc) != source and min_cost_flow.Head( arc) != sink: # Arcs in the solution have a flow value of 1. Their start and end nodes # give an assignment of worker to task. if min_cost_flow.Flow(arc) > 0: print('Worker %d assigned to task %d. Cost = %d' % (min_cost_flow.Tail(arc), min_cost_flow.Head(arc), min_cost_flow.UnitCost(arc))) else: print('There was an issue with the min cost flow input.')
def main(): setupData = loadtxt("input1.txt").astype(int) days = setupData[0].item() segments = setupData[1].item() #number of intervals between costCycles nodes = setupData[2].item() startingBikes = delete(setupData, [0,1,2]) totalBikes = sum(startingBikes) bikeData = reshape(loadtxt("input2.txt").astype(int), (2*segments*days, nodes, nodes)) inBikes = sum(bikeData, axis=1) min_cost_flow = pywrapgraph.SimpleMinCostFlow() start(min_cost_flow, nodes, startingBikes) offset = nodes for i in range(0, 2*segments*days): if(i % segments == 0): costCycle(min_cost_flow, nodes, offset) offset = offset + nodes freeCycle(min_cost_flow, nodes, offset, i, bikeData, inBikes) offset = offset + 2 * nodes end(min_cost_flow, nodes, offset, totalBikes) print(min_cost_flow.NumArcs()) if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: print('Minimum cost:', min_cost_flow.OptimalCost()) print('') print(' Arc Flow / Capacity Cost') for i in range(min_cost_flow.NumArcs()): cost = min_cost_flow.Flow(i) * min_cost_flow.UnitCost(i) print('%1s -> %1s %3s / %3s %3s' % ( min_cost_flow.Tail(i), min_cost_flow.Head(i), min_cost_flow.Flow(i), min_cost_flow.Capacity(i), cost)) else: print('There was an issue with the min cost flow input.') print(' Arc Capacity Cost') for i in range(min_cost_flow.NumArcs()): print('%1s -> %2s %3s %4s' % ( min_cost_flow.Tail(i), min_cost_flow.Head(i), min_cost_flow.Capacity(i), min_cost_flow.UnitCost(i), )) print('\n') print(' Node Supply') for i in range(min_cost_flow.NumNodes()): print('%1s : %2s' % (i, min_cost_flow.Supply(i)))
def construct_solver(self): self._check_graph_integrity() self.min_cost_flow = pywrapgraph.SimpleMinCostFlow() for arc_index in range(len(self.start_nodes)): self.min_cost_flow.AddArcWithCapacityAndUnitCost( self.start_nodes[arc_index].number, self.end_nodes[arc_index].number, self.capacities[arc_index], self.costs[arc_index]) for node in self.node_by_number.values(): self.min_cost_flow.SetNodeSupply(node.number, node.supply)
def _build_graph(self): self.graph = pywrapgraph.SimpleMinCostFlow() start_node = 0 S = len(self.servers) R = len(self.requests) server_nodes = range(1, S + 1) self.server_nodes = server_nodes # for every request, there are two nodes request_nodes = range(S + 1, S + 2 * R + 1, 2) self.request_nodes = request_nodes end_node = S + 2 * R + 1 # take a node number, and return the server location node_to_server = lambda x: self.servers[x - 1] # take a node number, and return the request location node_to_request = lambda x: self.requests[(x - 1 - S) // 2] # now build the graph for current_server_node in server_nodes: # Add the edges from source to servers self.graph.AddArcWithCapacityAndUnitCost(start_node, current_server_node, 1, 0) # And from server to sink self.graph.AddArcWithCapacityAndUnitCost(current_server_node, end_node, 1, 0) # now, for each server, add the cost to move from server to request. for current_request_node in request_nodes: self.graph.AddArcWithCapacityAndUnitCost( current_server_node, current_request_node, 1, self.dist(node_to_request(current_request_node), node_to_server(current_server_node))) for current_request_node in request_nodes: # Add edge from request' to sink self.graph.AddArcWithCapacityAndUnitCost(current_request_node + 1, end_node, 1, 0) # Add edge from request to request' with a very low cost self.graph.AddArcWithCapacityAndUnitCost(current_request_node, current_request_node + 1, 1, -self.BigNumber) for next_request_node in range(current_request_node + 2, S + 2 * R + 1, 2): # Add edge from request' to all next requests self.graph.AddArcWithCapacityAndUnitCost( current_request_node + 1, next_request_node, 1, self.dist(node_to_request(current_request_node), node_to_request(next_request_node))) # Add supply and demand at the start and end node self.graph.SetNodeSupply(start_node, S) self.graph.SetNodeSupply(end_node, -S)
def main(): """MinCostFlow simple interface example.""" # [START solver] # Instantiate a SimpleMinCostFlow solver. min_cost_flow = pywrapgraph.SimpleMinCostFlow() # [END solver] # [START data] # Define four parallel arrays: sources, destinations, capacities, # and unit costs between each pair. For instance, the arc from node 0 # to node 1 has a capacity of 15. start_nodes = [0, 0, 1, 1, 1, 2, 2, 3, 4] end_nodes = [1, 2, 2, 3, 4, 3, 4, 4, 2] capacities = [15, 8, 20, 4, 10, 15, 4, 20, 5] unit_costs = [4, 4, 2, 2, 6, 1, 3, 2, 3] # Define an array of supplies at each node. supplies = [20, 0, 0, -5, -15] # [END data] # [START constraints] # Add each arc. for arc in zip(start_nodes, end_nodes, capacities, unit_costs): min_cost_flow.AddArcWithCapacityAndUnitCost(arc[0], arc[1], arc[2], arc[3]) # Add node supply. for count, supply in enumerate(supplies): min_cost_flow.SetNodeSupply(count, supply) # [END constraints] # [START solve] # Find the min cost flow. status = min_cost_flow.Solve() # [END solve] # [START print_solution] if status != min_cost_flow.OPTIMAL: print('There was an issue with the min cost flow input.') print(f'Status: {status}') exit(1) print('Minimum cost: ', min_cost_flow.OptimalCost()) print('') print(' Arc Flow / Capacity Cost') for i in range(min_cost_flow.NumArcs()): cost = min_cost_flow.Flow(i) * min_cost_flow.UnitCost(i) print('%1s -> %1s %3s / %3s %3s' % (min_cost_flow.Tail(i), min_cost_flow.Head(i), min_cost_flow.Flow(i), min_cost_flow.Capacity(i), cost))
def __init__(self, minimums, maximums, demands, encoder, sol=None, logger=None): """Initialize a makespan flow matcher Args: maximums - a list of integers specifying the maximum number of papers for each reviewer. minimums - list of integers specifying min number of papers per rev. demands - a list of integers specifying the number of reviews per paper. weights - the affinity matrix (np.array) of papers to reviewers. Rows correspond to reviewers and columns correspond to papers. solution - a matrix of assignments (same shape as weights). Returns: initialized makespan matcher. """ # TODO: incorporate constraints self.constraint_matrix = encoder.constraint_matrix affinity_matrix = encoder.aggregate_score_matrix.transpose() self.n_rev = np.size(affinity_matrix, axis=0) self.n_pap = np.size(affinity_matrix, axis=1) self.maximums = maximums self.minimums = minimums self.demands = demands # make sure that all weights are positive: self.orig_affs = affinity_matrix.copy() self.affinity_matrix = affinity_matrix.copy() min_aff = np.min(affinity_matrix) if min_aff < 0: self.affinity_matrix -= min_aff self.id = uuid.uuid4() self.makespan = 0.0 # the minimum allowable paper score. self.solution = sol if sol else np.zeros((self.n_rev, self.n_pap)) self.valid = True if sol else False assert(self.affinity_matrix.shape == self.solution.shape) self.maxaff = np.max(self.affinity_matrix) self.big_c = 10000 self.bigger_c = self.big_c ** 2 self.min_cost_flow = pywrapgraph.SimpleMinCostFlow() self.start_inds = [] self.end_inds = [] self.caps = [] self.costs = [] self.source = self.n_rev + self.n_pap self.sink = self.n_rev + self.n_pap + 1
def main(supplies): """MinCostFlow simple interface example.""" # Define four parallel arrays: start_nodes, end_nodes, capacities, and unit costs # between each pair. For instance, the arc from node 0 to node 1 has a # capacity of 15 and a unit cost of 4. load_graph() load_supply() start_nodes = [0, 0, 1, 1, 1, 2, 2, 3, 4] end_nodes = [1, 2, 2, 3, 4, 3, 4, 4, 2] capacities = [15, 8, 20, 4, 10, 15, 5, 20, 4] unit_costs = [4, 4, 2, 2, 6, 1, 3, 2, 3] # Define an array of supplies at each node. # Instantiate a SimpleMinCostFlow solver. min_cost_flow = pywrapgraph.SimpleMinCostFlow() # Add each arc. for i in range(0, len(start_nodes)): min_cost_flow.AddArcWithCapacityAndUnitCost(start_nodes[i], end_nodes[i], capacities[i], unit_costs[i]) # Add node supplies. for i in range(0, len(supplies)): min_cost_flow.SetNodeSupply(i, supplies[i]) # Find the minimum cost flow between node 0 and node 4. if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: print('Minimum cost:', min_cost_flow.OptimalCost()) print('') print(' Arc Flow / Capacity Cost') flag = 1 for i in range(min_cost_flow.NumArcs()): cost = min_cost_flow.Flow(i) * min_cost_flow.UnitCost(i) print('%1s -> %1s %3s / %3s %3s' % (min_cost_flow.Tail(i), min_cost_flow.Head(i), min_cost_flow.Flow(i), min_cost_flow.Capacity(i), cost)) return flag, min_cost_flow.Flow() else: print('There was an issue with the min cost flow input.') flag = 0 return flag
def solve(test): n = test[0] budget = test[1] matches = test[2] won_by_king = sum([1 for match in matches if match[0] == 0]) can_win = False for desired_score in range(max(ceildiv(n, 2), won_by_king), n): solver = pywrapgraph.SimpleMinCostFlow() matches_from = n matches_to = matches_from + n_choose_two(n) s = matches_to t = s + 1 bottleneck = t + 1 for i in range(matches_from, matches_to): solver.AddArcWithCapacityAndUnitCost(s, i, 1, 0) for i in range(matches_from, matches_to): match = matches[i - matches_from] solver.AddArcWithCapacityAndUnitCost(i, match[0], 1, 0) solver.AddArcWithCapacityAndUnitCost(i, match[1], 1, match[2]) solver.AddArcWithCapacityAndUnitCost(0, t, desired_score, 0) for i in range(1, n): solver.AddArcWithCapacityAndUnitCost(i, bottleneck, desired_score, 0) solver.AddArcWithCapacityAndUnitCost(bottleneck, t, n_choose_two(n) - desired_score, 0) solver.SetNodeSupply(s, n_choose_two(n)) solver.SetNodeSupply(t, -1 * n_choose_two(n)) status = solver.Solve() if (solver.OptimalCost() <= budget): can_win = True print( f"n: {n}, b: {budget}, x: {desired_score}, st: {status}, cost: {solver.OptimalCost()}" ) return can_win
def matching_source_demand(start_nodes, end_nodes, capacities, costs, supplies, source_list, demand_list, source_name='goods', demand_name='buyer'): # create max-flow-min-cost network costs = [int(i) for i in costs] capacities = [int(i) for i in capacities] min_cost_flow = pywrapgraph.SimpleMinCostFlow() for i in range(0, len(start_nodes)): min_cost_flow.AddArcWithCapacityAndUnitCost(start_nodes[i], end_nodes[i], capacities[i], costs[i]) for i in range(0, len(supplies)): min_cost_flow.SetNodeSupply(i, supplies[i]) st = min_cost_flow.SolveMaxFlowWithMinCost() all_hope_matching_df = pd.DataFrame( [], columns=[source_name, demand_name, 'qty', 'cap', 'cost']) if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: all_hope_matching_df[source_name] = [ min_cost_flow.Tail(i) for i in range(min_cost_flow.NumArcs()) ] all_hope_matching_df[demand_name] = [ min_cost_flow.Head(i) for i in range(min_cost_flow.NumArcs()) ] all_hope_matching_df['qty'] = [ min_cost_flow.Flow(i) for i in range(min_cost_flow.NumArcs()) ] all_hope_matching_df['cap'] = [ min_cost_flow.Capacity(i) for i in range(min_cost_flow.NumArcs()) ] all_hope_matching_df['cost'] = all_hope_matching_df['qty'] * \ [min_cost_flow.UnitCost(i) for i in range(min_cost_flow.NumArcs())] hope_matching_df = all_hope_matching_df[ all_hope_matching_df['qty'] > 0] else: print('There was an issue with the min cost flow input.') hope_matching_df[source_name] = hope_matching_df[source_name].apply( lambda x: source_list[x]) hope_matching_df[demand_name] = hope_matching_df[demand_name].apply( lambda x: demand_list[x - len(source_list)]) hope_matching_df.sort_values(by=[demand_name, 'cost'], inplace=True) return hope_matching_df
def solve(self, array): ''' Args: array - Numpy 2D array [nworkers, ntasks] Return: results ''' assert array.shape == ( self.nworkers, self.ntasks), "Wrong array shape, it should be ({}, {})".format( self.nworkers, self.ntasks) array_p = self.value * array array_p = -array_p # potential to cost array_p = array_p.astype(np.int32) costs = copy.copy(self.common_costs) for work_idx in range(self.nworkers): for task_idx in range(self.ntasks): costs.append(array_p[work_idx][task_idx]) costs = np.array(costs) costs = (costs.tolist()) assert len( costs ) == self.nnodes, "Length of costs should be {} but {}".format( self.nnodes, len(costs)) min_cost_flow = pywrapgraph.SimpleMinCostFlow() for idx in range(self.nnodes): min_cost_flow.AddArcWithCapacityAndUnitCost( self.start_nodes[idx], self.end_nodes[idx], self.capacities[idx], costs[idx]) for idx in range(self.ntasks + self.nworkers + 2): min_cost_flow.SetNodeSupply(idx, self.supplies[idx]) min_cost_flow.Solve() results = list() for arc in range(min_cost_flow.NumArcs()): if min_cost_flow.Tail(arc) != self.source and min_cost_flow.Head( arc) != self.sink: if min_cost_flow.Flow(arc) > 0: results.append([ min_cost_flow.Tail(arc) - 1, min_cost_flow.Head(arc) - self.nworkers - 1 ]) return results
def refine_solution_Transportation(Affinity, n_students_per_tutor, min_affinity): T, S = Affinity.shape # build the min-cost transportation problem # nodes and edges ind = np.where(Affinity>=min_affinity) start_nodes = ind[0] # tutors end_nodes = ind[1] + T # students # add artificial node to make sum(supplies)=0 start_nodes = np.r_[start_nodes, range(T)] end_nodes = np.r_[end_nodes, [S+T]*T] # students n_edges = len(start_nodes) # cost vector, capacities and supplies cost_vec = np.zeros(len(ind[0])) cost_vec[Affinity[ind]==min_affinity] = 1 cost_vec = np.r_[cost_vec, np.zeros(T)] capacities = [np.max(n_students_per_tutor)] * n_edges supplies = np.r_[n_students_per_tutor, [-1] * S, S-np.sum(n_students_per_tutor)] # Instantiate a SimpleMinCostFlow solver min_cost_flow = pywrapgraph.SimpleMinCostFlow() # Add each arc for i in range(0,len(start_nodes)): min_cost_flow.AddArcWithCapacityAndUnitCost(int(start_nodes[i]), \ int(end_nodes[i]), int(capacities[i]), int(cost_vec[i])) # Add node supplies for i in range(0,len(supplies)): min_cost_flow.SetNodeSupply(i, int(supplies[i])) # check that it is feasible if min_cost_flow.Solve() != min_cost_flow.OPTIMAL: print('There was an issue with the min-cost flow input.') keep_it = [False for ii in range(n_edges)] for ii in range(n_edges): keep_it[ii] = (min_cost_flow.Flow(ii)==1) & (min_cost_flow.UnitCost(ii)==1) tutor_student_assignment = [start_nodes[keep_it], end_nodes[keep_it]-T] return tutor_student_assignment