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
示例#2
0
 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 = []
示例#3
0
    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))
        ])
示例#4
0
    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.')
示例#5
0
文件: min-cost.py 项目: amey-joshi/am
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)}')
示例#6
0
    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))
示例#7
0
    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)
示例#8
0
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.')
示例#9
0
文件: tp1.py 项目: Nikkunemufr/Python
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.")
示例#10
0
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
示例#11
0
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)
示例#12
0
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
示例#13
0
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}
示例#16
0
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.')
示例#18
0
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())
        
示例#19
0
    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.')
示例#21
0
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)
示例#23
0
    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))
示例#25
0
    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
示例#26
0
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
示例#27
0
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
示例#28
0
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
示例#29
0
    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
示例#30
0
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