コード例 #1
0
ファイル: torus2.py プロジェクト: ehua7365/ToricCode
def findPairs(A,B,edgesX,edgesY,L):
    # Generate the graphs for input into mwmatching algorithm
    nA,nB = len(A),len(B)
    graphEdgesA = [] # List of graph edges corresponding to path lengths A
    for i in xrange(nA-1):
        for j in xrange(i+1,nA):
            graphEdgesA.append((i,j,2*L-minDistance(A[i],A[j],L)))
    graphEdgesB = [] # List of graph edges corresponding to path lengths B
    for i in xrange(nB-1):
        for j in xrange(i+1,nB):
            graphEdgesB.append((i,j,2*L-minDistance(B[i],B[j],L)))

    # Feed graphs into mwmatching algorithm
    matchesA = mwmatching.maxWeightMatching(graphEdgesA)
    pairsA = []
    for i in xrange(len(matchesA)):
        p = [A[i],A[matchesA[i]]]
        p.sort()
        pairsA.append(p)
    # Remove duplicates
    pairsA = dict((x[0], x) for x in pairsA).values()
    
    matchesB = mwmatching.maxWeightMatching(graphEdgesB)
    pairsB = []
    for i in xrange(len(matchesB)):
        p = [B[i],B[matchesB[i]]]
        p.sort()
        pairsB.append(p)
    # Remove duplicates
    pairsB = dict((x[0], x) for x in pairsB).values()
    return (pairsA,pairsB)
コード例 #2
0
def findPairs(A, B, edgesX, edgesY, L):
    # Generate the graphs for input into mwmatching algorithm
    nA, nB = len(A), len(B)
    graphEdgesA = []  # List of graph edges corresponding to path lengths A
    for i in xrange(nA - 1):
        for j in xrange(i + 1, nA):
            graphEdgesA.append((i, j, 2 * L - minDistance(A[i], A[j], L)))
    graphEdgesB = []  # List of graph edges corresponding to path lengths B
    for i in xrange(nB - 1):
        for j in xrange(i + 1, nB):
            graphEdgesB.append((i, j, 2 * L - minDistance(B[i], B[j], L)))

    # Feed graphs into mwmatching algorithm
    matchesA = mwmatching.maxWeightMatching(graphEdgesA)
    pairsA = []
    for i in xrange(len(matchesA)):
        p = [A[i], A[matchesA[i]]]
        p.sort()
        pairsA.append(p)
    # Remove duplicates
    pairsA = dict((x[0], x) for x in pairsA).values()

    matchesB = mwmatching.maxWeightMatching(graphEdgesB)
    pairsB = []
    for i in xrange(len(matchesB)):
        p = [B[i], B[matchesB[i]]]
        p.sort()
        pairsB.append(p)
    # Remove duplicates
    pairsB = dict((x[0], x) for x in pairsB).values()
    return (pairsA, pairsB)
コード例 #3
0
    def split(self, items, actors, bids, exclusive=True):
        print "Attempting to split:"
        print "== Items: "
        pprint(items)
        print "== between:"
        pprint(actors)
        print "== as per the bids:"
        pprint(bids)
        averages = self.calc_averages(items, bids)
        bid_dict = {}
        for bid in bids:
            bid_dict[(bid.item, bid.actor)] = bid

        edges = []
        for i in range(len(items)):
            for j in range(len(actors)):
                if (items[i], actors[j]) in bid_dict:
                    bid = bid_dict[(items[i], actors[j])]
                    edges.append((i, len(items) + j, self.score(bid, averages)))

        mw = mwmatching.maxWeightMatching(edges)
        result = {}
        unused_actors = actors[:]
        unused_items = items[:]
        for i in range(len(items)):
            if mw[i] != -1:
                winner = actors[mw[i] - len(items)]
                result[items[i]] = (winner, bid_dict[(items[i], winner)].amount)
                unused_actors.remove(winner)
                unused_items.remove(items[i])
            else:
                result[items[i]] = None


        # This isn't really ideal, but this code is meant to handle the case
        # where not all bids can be satisfied. The max-weight solution will
        # force someone into a room at a different price than they bid.
        # In my tests, it seems to always be a lower price, but I'm not counting
        # on that.
        #
        # Example input that causes this issue (5 person / 5 item auction):
        #
        # 1640, 1540, 1140, 1640, 1740
        # 1540, 1240, 1340, 1640, 1940
        # 1740, 1540, 1040, 1640, 1740
        # 1440, 1640, 1240, 1640, 1740
        # 1640, 1640, 1140, 1640, 1640
        total_dollars = sum([bid.amount for bid in bids if bid.actor == actors[0]])
        amount_spent = sum([v[1] for k,v in result.items() if v is not None])
        remaining_amount = total_dollars - amount_spent
        if len(unused_items):
            remaining_per_item = remaining_amount / len(unused_items)

        if unused_actors:
            print "Warning: could not properly satisfy auction."
            for k,v in result.items():
                if v is None:
                    result[k] = (unused_actors, remaining_per_item)

        return result
コード例 #4
0
ファイル: pair.py プロジェクト: Janzert/tournament_tools
def weighted_pairing(tourn, scale):
    players = list(tourn.players)
    num_alive = len(players)

    weights = []
    for p1_ix, p1 in enumerate(players):
        for p2_ix, p2 in enumerate(players[p1_ix + 1:], p1_ix + 1):
            wt = scale.pair(p1, p2)
            weights.append((p1_ix, p2_ix, 0 - wt))
        if num_alive % 2 == 1:
            wt = scale.bye(p1)
            weights.append((p1_ix, num_alive, 0 - wt))
    opponents = maxWeightMatching(weights, maxcardinality=True)
    weight_dict = {(v1, v2): wt for v1, v2, wt in weights}
    result_weight = sum(weight_dict[(v1, v2)] for v1, v2 in enumerate(opponents)
        if v1 < v2)

    if num_alive % 2 == 1:
        bye = players[opponents.index(num_alive)]
    else:
        bye = None
    pairings = [(players[p1_ix], players[p2_ix])
            for p1_ix, p2_ix in enumerate(opponents[:num_alive])
            if p2_ix != num_alive and p1_ix < p2_ix
            ]
    return pairings, bye
コード例 #5
0
def weighted_pairing(tourn, scale):
    players = list(tourn.players)
    num_alive = len(players)

    weights = []
    for p1_ix, p1 in enumerate(players):
        for p2_ix, p2 in enumerate(players[p1_ix + 1:], p1_ix + 1):
            wt = scale.pair(p1, p2)
            weights.append((p1_ix, p2_ix, 0 - wt))
        if num_alive % 2 == 1:
            wt = scale.bye(p1)
            weights.append((p1_ix, num_alive, 0 - wt))
    opponents = maxWeightMatching(weights, maxcardinality=True)
    weight_dict = {(v1, v2): wt for v1, v2, wt in weights}
    result_weight = sum(weight_dict[(v1, v2)]
                        for v1, v2 in enumerate(opponents) if v1 < v2)

    if num_alive % 2 == 1:
        bye = players[opponents.index(num_alive)]
    else:
        bye = None
    pairings = [(players[p1_ix], players[p2_ix])
                for p1_ix, p2_ix in enumerate(opponents[:num_alive])
                if p2_ix != num_alive and p1_ix < p2_ix]
    return pairings, bye
コード例 #6
0
ファイル: metapynets.py プロジェクト: marctc/metapynets
 def _comp_score(c1, c2):
     bi_graph = []
     score_comp = {}
     n1 = 0
     for i in c1:
         n2 = len(c1)
         for j in c2:
            #simcomp = calc_score_cache(i, j)
             simcomp = calc_score(i, j)
             bi_graph.append((n1, n2, simcomp))
             score_comp[n1, n2] = simcomp
             n2 += 1
         n1 += 1
     match = maxWeightMatching(bi_graph)
     i = 0
     n = 0
     score = 0
     while i < len(match) and n < min(len(c1), len(c2)):
         if match[i] != -1:
             try:
                 score += score_comp[i, match[i]]
             except:
                 pass
             n += 1
         i += 1
     return score/max(len(c1), len(c2))
コード例 #7
0
ファイル: assign_judges.py プロジェクト: ifly6/mit-tab
        def try_paneling(potential_pairings, all_judges, num_to_panel, gap):
            if len(potential_pairings) == 0 or num_to_panel <= 0:
                # Base case, failed to panel
                print "Failed to panel"
                return {}


            rounds = sorted(potential_pairings,
                            key=lambda r: (argmin(r.judges.all(),
                                           lambda j: j.rank).rank,) + \
                                           tuple([-1 * i for i in tab_logic.team_comp(r, current_round_number)]))
            base_judge = argmax(rounds[:num_to_panel][-1].judges.all(), lambda j: j.rank)
            print "Found maximally ranked judge {0}".format(base_judge)
            potential_panelists = [j for j in all_judges if
                                   j.rank > (float(base_judge.rank) - float(gap))]
            print "Potential panelists:", potential_panelists
            # If we don't have enough potential panelists, try again with fewer panels
            if len(potential_panelists) < 2 * num_to_panel:
                print "Not enough judges to panel!: ", len(potential_panelists), num_to_panel
                return try_paneling(potential_pairings, all_judges, num_to_panel - 1, gap)

            panel_assignments = []
            rounds_to_panel = rounds[:num_to_panel]
            num_to_panel = len(rounds_to_panel)
            for pairing in rounds_to_panel:
                panel_assignments.append([j for j in pairing.judges.all()])

            # Do it twice so we get panels of 3
            for i in (0,1):
                graph_edges = []
                for (judge_i, judge) in enumerate(potential_panelists):
                    for (pairing_i, pairing) in enumerate(rounds_to_panel):
                        if not judge_conflict(judge, pairing.gov_team, pairing.opp_team):
                            judges = panel_assignments[pairing_i] + [judge]
                            graph_edges.append((pairing_i,
                                                judge_i + num_to_panel,
                                                calc_weight_panel(judges)))
                pprint.pprint(graph_edges)
                judge_assignments = mwmatching.maxWeightMatching(graph_edges, maxcardinality=True)
                print judge_assignments
                if ((-1 in judge_assignments[:num_to_panel]) or
                    (num_to_panel > 0 and len(graph_edges) == 0)):
                    print "Scratches are causing a retry"
                    return try_paneling(potential_pairings, all_judges, num_to_panel - 1, gap)
                # Save the judges to the potential panel assignments
                judges_used = []
                for i in range(num_to_panel):
                    judge = potential_panelists[judge_assignments[i] - num_to_panel]
                    panel_assignments[i].append(judge)
                    judges_used.append(judge)
                # Remove any used judges from the potential panelist pool
                for judge in judges_used:
                    print "Removing {0}".format(judge)
                    potential_panelists.remove(judge)

            print "panels: ", panel_assignments
            result = {}
            for (panel_i, panel) in enumerate(panel_assignments):
                result[rounds_to_panel[panel_i]] = panel
            return result
コード例 #8
0
ファイル: pairing_alg.py プロジェクト: BenMusch/mit-tab
def perfect_pairing(list_of_teams):
    """ Uses the mwmatching library to assign teams in a pairing """
    graph_edges = []
    for i in range(len(list_of_teams)):
        for j in range(len(list_of_teams)):
        # may want to change actual penalties
        # a team should not have an edge back to itself
        # nor do we need to calculate an edge from a to b and b to a
            if i > j:
                wt = calc_weight(list_of_teams[i],
                                 list_of_teams[j], i, j,
                                 list_of_teams[len(list_of_teams) - i - 1],
                                 list_of_teams[len(list_of_teams) - j - 1],
                                 len(list_of_teams) - i - 1,
                                 len(list_of_teams) - j - 1)
                # Add the edge to the graph
                graph_edges += [(i,j,wt)]
    pairings_num = mwmatching.maxWeightMatching(graph_edges, maxcardinality=True)
    #print "Pairing numbers"
    #print pairings_num
    all_pairs = []
    for pair in pairings_num:
        if pair < len(list_of_teams):
            if [list_of_teams[pairings_num.index(pair)], list_of_teams[pair]] not in all_pairs and [list_of_teams[pair], list_of_teams[pairings_num.index(pair)]] not in all_pairs:
                all_pairs +=[[list_of_teams[pairings_num.index(pair)], list_of_teams[pair]]]
                #print "all pairs"
                #print all_pairs
    #print all_pairs
    return determine_gov_opp(all_pairs)
def getDisjointPairs(pairs):

    # Input:
    # * *pairs* - A dictionary with names of pairs as keys and lists of the two qubits of each pair as values
    #
    # Process:
    # * A graph is created using the pairs as edges, and is assigned random weights.
    #   These max weight matched to find a disjoint set of pairs.
    #
    # Output:
    # * *matchingPairs* - A list of the names of a random set of disjoint pairs included in the matching.

    edges = []
    for p in pairs.keys():
        edges.append((pairs[p][0], pairs[p][1], random.randint(0, 100)))

    # match[j] = k means that edge j and k are matched
    match = mw.maxWeightMatching(edges, maxcardinality=True)

    # get a list of the pair names for each pair in the matching (not including fakes)
    matchingPairs = []
    for v in range(len(match)):
        for p in pairs.keys():
            if pairs[p] == [v, match[v]] and p[0:4] != 'fake':
                matchingPairs.append(p)

    return matchingPairs
コード例 #10
0
def getDisjointPairs ( pairs, oneProb = [] ):

    # Input:
    # * *pairs* - A dictionary with names of pairs as keys and lists of the two qubits of each pair as values
    # 
    # Process:
    # * A graph is created using the pairs as edges, and is assigned random weights.
    #   These max weight matched to find a disjoint set of pairs.
    # 
    # Output:
    # * *matchingPairs* - A list of the names of a random set of disjoint pairs included in the matching.
    
    # if a set of oneProbs is supplied, the weight for an edge is the difference between their fracs
    weight = {}
    for p in pairs.keys():
        if oneProb:
            weight[p] = -calculateFracDifference( calculateFrac( oneProb[ pairs[p][0] ] ) , calculateFrac( oneProb[ pairs[p][1] ] ) )
        else:
            weight[p] = random.randint(0,100)     
    
    edges = []
    for p in pairs.keys():
        edges.append( ( pairs[p][0], pairs[p][1], weight[p] ) )
    
    # match[j] = k means that edge j and k are matched
    match = mw.maxWeightMatching(edges, maxcardinality=True)
    
    # get a list of the pair names for each pair in the matching (not including fakes)
    matchingPairs = []
    for v in range(len(match)):
        for p in pairs.keys():
            if pairs[p]==[v,match[v]] and p[0:4]!='fake' :
                matchingPairs.append(p)
                
    return matchingPairs
コード例 #11
0
def compare_clusters(cl1, cl2):

    n1 = len(cl1)
    edges = []
    edge_weights = {}

    for c in range(len(cl1)):

        for d in range(len(cl2)):

            inter = len(cl1[c].intersection(cl2[d]))
            if inter > 0:
                edges.append((c, (d + 1) * 10 * n1, inter))
                edge_weights[(c, (d + 1) * 10 * n1)] = inter

    match = mwmatching.maxWeightMatching(edges)

    w = 0
    for c in range(len(cl1)):
        mate = match[c]

        if mate >= 0:
            w += edge_weights[(c, mate)]

    return w
コード例 #12
0
ファイル: tsp_pcc.py プロジェクト: Mondego/pcc
 def __query__(subgraph_paths):
     objs = maxWeightMatching([(int(p.city1.name), int(p.city2.name), 1 - p.distance) for p in subgraph_paths], True)
     req_paths = [(str(i), str(objs[i])) for i in range(len(objs)) if objs[i] != -1]
     return [
         path
         for path in subgraph_paths
         for req_path in req_paths
         if min_weight_perfect_match.__predicate__(path, req_path)
     ]
コード例 #13
0
 def __query__(subgraph_paths):
     objs = maxWeightMatching(
         [(int(p.city1.name), int(p.city2.name), 1 - p.distance)
          for p in subgraph_paths], True)
     req_paths = [(str(i), str(objs[i])) for i in range(len(objs))
                  if objs[i] != -1]
     return [
         path for path in subgraph_paths for req_path in req_paths
         if min_weight_perfect_match.__predicate__(path, req_path)
     ]
コード例 #14
0
ファイル: lp_cp.py プロジェクト: rajatsen91/queueing_bandit
def maxweight_schedule(q, ucb_mat, K):
    edges = []
    for i in range(K):
        for j in range(K):
            temp = (i, K + j, max([ucb_mat[i, j] * q[i], 0]))
            edges = edges + [temp]

            # print edges

    match = maxWeightMatching(edges, True)
    P = np.zeros([K, K])
    for i in range(K):
        P[i, match[i] - K] = 1

    return P
コード例 #15
0
ファイル: match_standalone.py プロジェクト: jboscolo/RH
def maximum_matching_ratio(reference, predicted, score_threshold=0.2):
    scores = {}

    n = len(reference)
    for id1, c1 in enumerate(reference):
        for id2, c2 in enumerate(predicted):
            score = matching_score(c1, c2)
            if score <= score_threshold:
                continue

            scores[id1, id2+n] = score

    input = [(v1, v2, w) for (v1, v2), w in scores.iteritems()]
    mates = maxWeightMatching(input)
    score = sum(scores[i, mate] for i, mate in enumerate(mates) if i < mate)
    return score / n
コード例 #16
0
def maximum_matching_ratio(reference, predicted, score_threshold=0.2):
    scores = {}

    n = len(reference)
    for id1, c1 in enumerate(reference):
        for id2, c2 in enumerate(predicted):
            score = matching_score(c1, c2)
            if score <= score_threshold:
                continue

            scores[id1, id2 + n] = score

    input = [(v1, v2, w) for (v1, v2), w in scores.items()]
    mates = maxWeightMatching(input)
    score = sum(scores[i, mate] for i, mate in enumerate(mates) if i < mate)
    return score / n
コード例 #17
0
ファイル: evaluate.py プロジェクト: nimar/seismic-2d
def match_episodes(gold, guess, MINASSOC=2, DMAX=5, TMAX=50):
  """
  We want a max cardinality min cost matching for the provided events.

  Returns the number of matchable events and the matching indices.
  """
  ## we will first construct a list of edges between gold and guess events
  ## that are allowed to be matched.
  
  edges = []
  matchable_gold = 0
  
  for goldnum, goldev in enumerate(gold.events):
    
    # events with very few detections are unmatchable
    if len(gold.assocs[goldnum]) < MINASSOC:
      continue
    
    matchable_gold += 1
    
    for guessnum, guessev in enumerate(guess.events):
      # check the separation in space and time
      dist = compute_distance((goldev.lon, goldev.lat),
                              (guessev.lon, guessev.lat))
      timesep = abs(goldev.time - guessev.time)
      
      # note that the guess events are placed after the gold events hence
      # they are numbered as "len(gold.events) + guessnum"
      if dist <= DMAX and timesep <= TMAX:
        edges.append((goldnum, len(gold.events) + guessnum,
                      - dist / DMAX - timesep / TMAX))
  
  ## call the max-cardinality "max" weight matching, note that we used negative
  ## weights above so we effectively get max cardinality "min" weight matching
  
  mat = mwmatching.maxWeightMatching(edges, maxcardinality=True)
  
  ## convert the indices back to the original numbering
  
  indices = []
  for i in range(len(gold.events)):
    if i < len(mat) and mat[i] >= 0:
      assert(mat[i] >= len(gold.events))
      indices.append((i, mat[i] - len(gold.events)))

  return matchable_gold, indices
コード例 #18
0
    def M_M_R(self, truth, detected, score_threshold=0.5):
        scores = {}
        n = len(truth)
        #c1,c2为两个社团,
        for id_truth, c1 in enumerate(truth):
            for id_detected, c2 in enumerate(detected):
                score = self.matching_score(c1, c2)
                if score < score_threshold:
                    #continue
                    scores[id_truth, id_detected + n] = -1

                scores[id_truth, id_detected + n] = score

        input = [(v1, v2, w) for (v1, v2), w in scores.items()]
        mates = maxWeightMatching(input)
        score = sum(scores[i, mate] for i, mate in enumerate(mates)
                    if i < mate)
        return score / n, mates
コード例 #19
0
ファイル: metapynets.py プロジェクト: marctc/metapynets
 def get_score(self):
     bi_graph = []
     score = 0
     # v0, v1, v2
     # [2, -1, 0]
     for i in self.score_matrix:
         l = list(i)
         l.append(self.score_matrix[i])
         bi_graph.append(tuple(l))
     r = maxWeightMatching(bi_graph)
     for b in r:
         a = r.index(b)
         if self.score_matrix.has_key((a, b)):
             s = self.score_matrix[a, b]
             score += s
     if max(len(self.r_dict1), len(self.r_dict2)) == 0:
         return 0.0
     else:
         return score/max(len(self.r_dict1), len(self.r_dict2))
コード例 #20
0
def maximum_matching_ratio(reference, predicted, score_threshold=0.2):
    scores = {}
    count = 0
    n = len(reference)
    for id1, c1 in enumerate(reference):
        for id2, c2 in enumerate(predicted):
            score = matching_score(c1, c2)
            if score == 1:
                count = count + 1
            if score <= score_threshold:
                continue

            scores[id1, id2 + n] = score
    print('score is:', scores)
    print('fully matched V1', count, 'out of', n)
    inpt = [(v1, v2, w) for (v1, v2), w in scores.items()]
    mates = maxWeightMatching(inpt)
    score = sum(scores[i, mate] for i, mate in enumerate(mates) if i < mate)
    return score / n
コード例 #21
0
ファイル: TSP.py プロジェクト: Vlad-Shcherbina/icfpc2012-tbd
def minimal_weight_perfect_matching(nodes, weights):
    ''' Heuristic algorithm for minimal weight perfect matching.
        A wrapper for something I found on the web. '''
        
    nodes = list(nodes)
   
    weighted_edges = []
    for i, node1 in enumerate(nodes):
        for j, node2 in enumerate(nodes):
            if j > i:
                weighted_edges.append((i, j, -weights[node1][node2]))
    
    mate = mwmatching.maxWeightMatching(weighted_edges, maxcardinality=True)
    
    matching = []
    for (i, j) in enumerate(mate):
        if j > i:   # implies j > -1, i.e. matching exists
            matching.append((nodes[i], nodes[j]))
    
    return matching
コード例 #22
0
ファイル: torus.py プロジェクト: ehua7365/ToricCode
def findPairs(A,edgesX,edgesY,L):
    # Generate the graphs for input into mwmatching algorithm
    nA = len(A)
##    print 'length of A = %d'%nA
    graphEdgesA = [] # List of graph edges corresponding to path lengths A
    for i in xrange(nA-1):
        for j in xrange(i+1,nA):
            graphEdgesA.append((i,j,2*L-minDistance(A[i],A[j],L)))
##    print 'graphEdgesA %d'%len(graphEdgesA)
    # Feed graphs into mwmatching algorithm
    matchesA = mwmatching.maxWeightMatching(graphEdgesA)
##    print 'matchesA '
##    print matchesA
    pairsA = []
    for i in xrange(len(matchesA)):
        p = [A[i],A[matchesA[i]]]
        p.sort()
        pairsA.append(p)
    # Remove duplicates
    pairsA = dict((x[0], x) for x in pairsA).values()
    return pairsA
コード例 #23
0
ファイル: splitter.py プロジェクト: tdooner/item-splitter
    def split(self, items, actors, bids, exclusive=True):
        print "Attempting to split:"
        print "== Items: "
        pprint(items)
        print "== between:"
        pprint(actors)
        print "== as per the bids:"
        pprint(bids)
        averages = self.calc_averages(items, bids)
        bid_dict = {}
        for bid in bids:
            bid_dict[(bid.item, bid.actor)] = bid

        edges = []
        for i in range(len(items)):
            for j in range(len(actors)):
                if (items[i], actors[j]) in bid_dict:
                    bid = bid_dict[(items[i], actors[j])]
                    edges.append((i, len(items) + j, self.score(bid, averages)))

        # Actually do the auction, maximizing whatever score function we have
        mw = mwmatching.maxWeightMatching(edges, maxcardinality=True)
        result = {}
        for i in range(len(items)):
            if mw[i] != -1:
                winner = actors[mw[i] - len(items)]
                result[items[i]] = (winner, bid_dict[(items[i], winner)].amount)
            else:
                result[items[i]] = None

        # If we have left over items then continue auctioning off items
        # TODO: figure out if this is "good enough" or actually optimal, I
        # really don't think that it is optimal.  I think that this is greedy
        remaining_items = [item for item in items if result[item] is None]
        if len(remaining_items) > 0:
            remaining_result = self.split(remaining_items, actors, bids, exclusive)
            result = dict(result.items() + remaining_result.items())

        return result
コード例 #24
0
ファイル: torus.py プロジェクト: navyTensor/ToricCode
def findPairs(A, edgesX, edgesY, L):
    # Generate the graphs for input into mwmatching algorithm
    nA = len(A)
    ##    print 'length of A = %d'%nA
    graphEdgesA = []  # List of graph edges corresponding to path lengths A
    for i in xrange(nA - 1):
        for j in xrange(i + 1, nA):
            graphEdgesA.append((i, j, 2 * L - minDistance(A[i], A[j], L)))


##    print 'graphEdgesA %d'%len(graphEdgesA)
# Feed graphs into mwmatching algorithm
    matchesA = mwmatching.maxWeightMatching(graphEdgesA)
    ##    print 'matchesA '
    ##    print matchesA
    pairsA = []
    for i in xrange(len(matchesA)):
        p = [A[i], A[matchesA[i]]]
        p.sort()
        pairsA.append(p)
    # Remove duplicates
    pairsA = dict((x[0], x) for x in pairsA).values()
    return pairsA
コード例 #25
0
ファイル: pairing_alg.py プロジェクト: alexgrubhub/mit-tab
def perfect_pairing(list_of_teams):
    #assign weights to edges:
    graph_edges = []
    for i in range(len(list_of_teams)):
        for j in range(len(list_of_teams)):
            # may want to change actual penalties
            # a team should not have an edge back to itself
            # nor do we need to calculate an edge from a to b and b to a
            if i > j:
                wt = calc_weight(list_of_teams[i], list_of_teams[j], i, j,
                                 list_of_teams[len(list_of_teams) - i - 1],
                                 list_of_teams[len(list_of_teams) - j - 1],
                                 len(list_of_teams) - i - 1,
                                 len(list_of_teams) - j - 1)
                #now add edge to graph
                graph_edges += [(i, j, wt)]
    pairings_num = mwmatching.maxWeightMatching(graph_edges,
                                                maxcardinality=True)
    #print "Pairing numbers"
    #print pairings_num
    all_pairs = []
    for pair in pairings_num:
        if pair < len(list_of_teams):
            if [list_of_teams[pairings_num.index(pair)], list_of_teams[pair]
                ] not in all_pairs and [
                    list_of_teams[pair],
                    list_of_teams[pairings_num.index(pair)]
                ] not in all_pairs:
                all_pairs += [[
                    list_of_teams[pairings_num.index(pair)],
                    list_of_teams[pair]
                ]]
                #print "all pairs"
                #print all_pairs
    #print all_pairs
    return determine_gov_opp(all_pairs)
コード例 #26
0
ファイル: assign_judges.py プロジェクト: BenMusch/mit-tab
def add_judges(pairings, judges, panel_points):
    # First clear any existing judge assignments
    for pairing in pairings:
        pairing.judges.clear()

    current_round_number = TabSettings.objects.get(key="cur_round").value - 1

    # Try to have consistent ordering with the round display
    random.seed(1337)
    random.shuffle(pairings)
    random.seed(1337)
    random.shuffle(judges)


    # Order the judges and pairings by power ranking (high speaking teams get high ranked judges)
    judges = sorted(judges, key=lambda j: j.rank, reverse = True)
    pairings.sort(key=lambda x: tab_logic.team_comp(x, current_round_number),
                  reverse = True)

    pprint.pprint(pairings)

    pairing_groups = [list() for panel_point in panel_points] + [list()]
    panel_gaps = {}
    current_group = 0
    for pairing in pairings:
        pairing_groups[current_group].append(pairing)
        if current_group < len(panel_points) and pairing == panel_points[current_group][0]:
            panel_gaps[current_group] = panel_points[current_group][1]
            current_group += 1

    pprint.pprint(panel_points)

    for (group_i, group) in enumerate(pairing_groups):
        num_rounds = len(group)
        # Assign chairs (single judges) to each round using perfect pairing
        graph_edges = []
        for (judge_i, judge) in enumerate(judges):
            for (pairing_i, pairing) in enumerate(group):
                if not judge_conflict(judge, pairing.gov_team, pairing.opp_team):
                    graph_edges.append((pairing_i,
                                        judge_i + len(group),
                                        calc_weight(judge_i, pairing_i)))
        judge_assignments = mwmatching.maxWeightMatching(graph_edges, maxcardinality=True)
        print "wat"
        # If there is no possible assignment of chairs, raise an error
        if -1 in judge_assignments[:num_rounds] or (num_rounds > 0 and len(graph_edges) == 0):
            if len(graph_edges) == 0:
                raise errors.JudgeAssignmentError("Impossible to assign judges, consider reducing your gaps if you are making panels, otherwise find some more judges.")
            elif -1 in judge_assignments[:num_rounds]:
                pairing_list = judge_assignments[:len(pairings)]
                bad_pairing = pairings[pairing_list.index(-1)]
                raise errors.JudgeAssignmentError("Could not find a judge for: %s" % str(bad_pairing))
            else:
                raise errors.JudgeAssignmentError()

        # Save the judges to the pairings
        for i in range(num_rounds):
            group[i].judges.add(judges[judge_assignments[i] - num_rounds])
            group[i].chair = judges[judge_assignments[i] - num_rounds]
            group[i].save()

        # Remove any assigned judges from the judging pool
        for pairing in group:
            for judge in pairing.judges.all():
                judges.remove(judge)

        # Function that tries to panel num_to_panel rounds of the potential_pairings
        # Has built in logic to retry with lower number of panels if we fail due
        # to either scratches or wanting to many rounds
        def try_paneling(potential_pairings, all_judges, num_to_panel, gap):
            if len(potential_pairings) == 0 or num_to_panel <= 0:
                # Base case, failed to panel
                print "Failed to panel"
                return {}


            rounds = sorted(potential_pairings,
                            key=lambda r: (argmin(r.judges.all(),
                                           lambda j: j.rank).rank,) + \
                                           tuple([-1 * i for i in tab_logic.team_comp(r, current_round_number)]))
            base_judge = argmax(rounds[:num_to_panel][-1].judges.all(), lambda j: j.rank)
            print "Found maximally ranked judge {0}".format(base_judge)
            potential_panelists = [j for j in all_judges if
                                   j.rank > (float(base_judge.rank) - float(gap))]
            print "Potential panelists:", potential_panelists
            # If we don't have enough potential panelists, try again with fewer panels
            if len(potential_panelists) < 2 * num_to_panel:
                print "Not enough judges to panel!: ", len(potential_panelists), num_to_panel
                return try_paneling(potential_pairings, all_judges, num_to_panel - 1, gap)

            panel_assignments = []
            rounds_to_panel = rounds[:num_to_panel]
            num_to_panel = len(rounds_to_panel)
            for pairing in rounds_to_panel:
                panel_assignments.append([j for j in pairing.judges.all()])

            # Do it twice so we get panels of 3
            for i in (0,1):
                graph_edges = []
                for (judge_i, judge) in enumerate(potential_panelists):
                    for (pairing_i, pairing) in enumerate(rounds_to_panel):
                        if not judge_conflict(judge, pairing.gov_team, pairing.opp_team):
                            judges = panel_assignments[pairing_i] + [judge]
                            graph_edges.append((pairing_i,
                                                judge_i + num_to_panel,
                                                calc_weight_panel(judges)))
                pprint.pprint(graph_edges)
                judge_assignments = mwmatching.maxWeightMatching(graph_edges, maxcardinality=True)
                print judge_assignments
                if ((-1 in judge_assignments[:num_to_panel]) or
                    (num_to_panel > 0 and len(graph_edges) == 0)):
                    print "Scratches are causing a retry"
                    return try_paneling(potential_pairings, all_judges, num_to_panel - 1, gap)
                # Save the judges to the potential panel assignments
                judges_used = []
                for i in range(num_to_panel):
                    judge = potential_panelists[judge_assignments[i] - num_to_panel]
                    panel_assignments[i].append(judge)
                    judges_used.append(judge)
                # Remove any used judges from the potential panelist pool
                for judge in judges_used:
                    print "Removing {0}".format(judge)
                    potential_panelists.remove(judge)

            print "panels: ", panel_assignments
            result = {}
            for (panel_i, panel) in enumerate(panel_assignments):
                result[rounds_to_panel[panel_i]] = panel
            return result

        # Use the try_paneling function for any rounds that have been marked as panel
        # points, note that we start with trying to panel the entire bracket and
        # rely on try_paneling's retries to fix it
        if group_i in panel_gaps and panel_gaps[group_i]:
            panels = try_paneling(group, judges, len(group), panel_gaps[group_i])
            for (pairing, panelists) in panels.iteritems():
                for panelist in panelists:
                    if panelist not in pairing.judges.all():
                        pairing.judges.add(panelist)
                        judges.remove(panelist)
                pairing.save()
コード例 #27
0
            (vertexNum, edgeNum) = line.split()
            vertexNum = int(vertexNum)
            edgeNum = int(edgeNum)
        else:
            (vertexI, vertexJ, weight) = line.split()
            vertexI = int(vertexI)
            vertexJ = int(vertexJ)
            weight = int(weight)
            if weight < 0:
                print "Error: Weights must be >= 0"
                sys.exit(-1)
            graphArray.append((vertexI, vertexJ, weight))
        lineIdx += 1

    # Call the maximum weight matching API function
    matchArray = mwmatching.maxWeightMatching(graphArray, maxCard)

    # Convert raw output
    vertexCount = len(matchArray)
    matchVertexCount = 0
    idx = 0
    matchGraphHash = {}
    for val in matchArray:
        if val != -1:
            key = " ".join([str(num) for num in sorted([idx, val])])
            if not key in matchGraphHash:
                matchGraphHash[key] = 1
            else:
                matchGraphHash[key] += 1
            matchVertexCount += 1
        idx += 1
コード例 #28
0
def rental_harmony(total_rent,values) :

#%%  
    n = len(values)
    assert (values.shape == (n,n))
    housemate = list(values.index)
    
    #%% PART 1: ROOM ASSIGNMENTS
    ###########################################
    # Apply van Rantwijk's Maximum Weight Matching package:
    # create a weighted bipartite graph where 
    # vertices 0,...,n-1 represent housemates and
    # vertices n,2n-1 represent rooms,
    # and edge weights represent utility assignments.
    edge_weights = [(i,n+j,values[i][housemate[j]]) 
        for i in range(0,n) for j in range(0,n)]

    #s[i]=j will mean housemate[i] will get room j:
    s = maxWeightMatching(edge_weights,maxcardinality=True)[n:]

    #store s in a data frame with labelled rows for easier debugging    
    assignment = pd.DataFrame({housemate[i] : [s[i]] for i in range(0,n)}).T
    assignment.columns = ["Room"]
    
    #%% PART 2: RENT ASSIGNMENTS
    ############################################
    all_pairs = [(i,j) 
        for i in range(0,n) 
        for j in range(0,n)]
    distinct_pairs = [(i,j) 
        for i in range(0,n) 
        for j in range(0,n) 
        if i != j]
    
    #%%
    # In the end, d[i,j] will be the rent personi i pays 
    # minus the rent person j pays; that is, 
    # d[i,j] = price[s[i]] - price[s[j]]
    # But first the values of d[i,j] will be unknown.
    # M will be a matrix of linearly independent rows that
    # we build over time, which, when applied to the vector 
    # of optimal prices, will return another vector y.  
    # Once M has n rows, we can stop and solve for the 
    # optimal pricing.    
    global d 
    d = dict({})
    global M
    global y    
    def reset_mutables () :    
        global d 
        global M
        global y
        d = {ij : None for ij in distinct_pairs}
        for i in range(0,n):
            d[i,i] = 0
        M = np.matrix([[1]*n])
        y = np.matrix([[total_rent]])

    reset_mutables()
        
    #%%
    # For notational convenience, we let
    # v[i,j] = values.loc[housemate[i],s[j]]
    #        = the value housemate i will assign to person j's room.
    # let r_i = price[s[i]] = the rent paid by person i, so
    # v[i,i] - r_i > v[i,j] - r_j, thus
    # d[i,j] = r_i - r_j < v[i,i] - v[i,j]
    # Therefore
    # u[i,j] = v[i,i] - v[i,j]
    # will be an upper bound for d[i,j].
    v = {(i,j) : values.loc[housemate[i],s[j]] for (i,j) in all_pairs}
    u = {(i,j) : (v[i,i] - v[i,j]) for i in range(0,n) for j in range(0,n)}


    #%% 
    def get_min_density_cycle():
        vertices = range(0,n)
        length_dict = {(i,j) : 1 if d[i,j] == None else 0 for (i,j) in all_pairs}
        weight_dict = {(i,j) : u[i,j] if d[i,j] == None else d[i,j] for (i,j) in all_pairs}
        return min_density_cycle(vertices,weight_dict,length_dict,error_tolerance=1e-4)

    #%%
    def vec(i,j) : 
        entries = [1 if k == i else (-1 if k==j else 0) for k in range(0,n)]
        return np.array(entries)
        
    def in_rowspan (row,M) :
        return la.matrix_rank(np.vstack([M,row])) == M.shape[0]
    
    def maybe_add_to_M (i,j) :
        new_row = np.array(vec(i,j))
        global M
        global y
        if not in_rowspan(new_row,M) and not d[i,j] == None:
            M = np.vstack([M,new_row])
            y = np.vstack([y,[d[i,j]]])
    

    #%%
    def edges_of(path) :
        return [(path[i],path[i+1]) for i in range(0,len(path)-1)]
    #edges_of((1,3,4))

    def free_edges () : 
        return [(i,j) for (i,j) in distinct_pairs if d[(i,j)] == None]

    def free_edges_of(path) : 
        return [ij for ij in edges_of(path) if d[ij]==None]
    #free_edges_of((0,1,2))

    
    #%%
    def set_next_rent_differences () :
        global min_cycle; 
        global min_density; 
        (min_density,min_cycle) = get_min_density_cycle()
        global free_pairs; free_pairs = free_edges_of(min_cycle)    
        global d
        global M
        global y
        for (i,j) in free_pairs :
            #print (i,j)
            d[i,j] = u[i,j] - min_density
            maybe_add_to_M (i,j)
    
    #%%
    def set_implied_values () :
        global M
        global y
        for (i,j) in free_edges() :        
            r = vec(i,j)
            if in_rowspan(r,M) :
                row_coeffs = np.matrix(la.lstsq(M.T, r.T)[0])
                #print (row_coeffs)
                d[i,j] = (row_coeffs * y)[0,0]
    
    #%% COMPUTE OPTIMAL PRICES!
    reset_mutables()
    while len(free_edges())>0:
        set_next_rent_differences()
        set_implied_values()
        
    #%%
    #Compute rents (indexed by people)
    rent = la.solve(M,y).T.tolist()[0]
    rent_frame = pd.DataFrame(rent)
    rent_frame.index = housemate
    rent_frame.columns = ["Rent"]
    #rent_frame
    
    #%%
    solution = pd.concat([assignment,rent_frame], axis = 1)
     
    #%% CHECK:   
    #The utility of housemate j's room-and-rent to housemate i 
    def utility (i,j) :
        return (values.loc[housemate[i],j] - rent[s.index(j)])
    #utility(1,0)
    
#%%
    envies = pd.DataFrame({
    housemate[i] : [round(utility(i,j) - utility(i,s[i]),2) for j in range(0,n)] for i in range(0,n) 
    }).T
    
    #%%
#    print("\nEnvies:")
#    print(envies.to_string())
#    print("\nEnvies:")    
    envy_free = all([(e<=0) for e in list(envies.values.flatten())])
    if not envy_free:
        print("Warning: not all envies are negative!")

    #%%
    return (solution,envies,envy_free)
コード例 #29
0
def pairings(players):
    ws = weights(players)
    ps = mwmatching.maxWeightMatching(ws)
    assert(-1 not in ps) # maxWeightMatching is happy to leave nodes out if the graph is maximal, but we are not. Fail early in such a case.
    return ps
コード例 #30
0
def swissPairings(tournament):
    """Returns a list of pairs of players for the next round of a match.
  
    Assuming that there are an even number of players registered, each player
    appears exactly once in the pairings.  Each player is paired with another
    player with an equal or nearly-equal win record, that is, a player adjacent
    to him or her in the standings.
    
    Args:
      tournament:  the tournament id you want to run swiss pairings on
  
    Returns:
      A list of tuples, each of which contains (id1, name1, id2, name2)
        id1: the first player's unique id
        name1: the first player's name
        id2: the second player's unique id
        name2: the second player's name
        
    Algorithm to pair and ensure no rematches was modeled on Leaguevine:
    https://www.leaguevine.com/blog/18/swiss-tournament-scheduling-leaguevines-new-algorithm/
    with modifications to weighting to make it a function of win & rank difference.
    The minimum weight maximum match algorithm was implemented based on work in:
    http://healthyalgorithms.com/2009/03/23/aco-in-python-minimum-weight-perfect-matchings-aka-matching-algorithms-and-reproductive-health-part-4/
    And the actual maximum weight matching algorithm code used is by Joris van Rantwijk:
    http://jorisvr.nl/maximummatching.html 
    """
    pairs = []
    conn = connect()
    c = conn.cursor()
    standings = playerStandings()
    # figure out who gets a bye if there are an odd number of players
    num_of_players = len(standings)
    if (num_of_players % 2) > 0:
        # assign a bye to the lowest standing player without a bye
        byes = whoHadABye(tournament)
        player = num_of_players - 1
        if len(byes) == 0:
            # assign the last player if no one has a bye yet
            bye_id = standings[player][0]
            reportMatch(tournament, bye_id, 0)
            # remove this player from the standings tuple
            standings = tuple(x for x in standings if x[0] != bye_id)
        else:
            # assign the bye to the lowest player who hasn't had one
            bye_id = -1
            while bye_id < 0:
                if ((standings[player][0],) in byes):
                    player -= 1
                    # condition below should never be reached as rounds < players
                    if player == -1: bye_id = standings[0][0];
                else:
                    bye_id = standings[player][0]
                    # record a bye for this player
                    reportMatch(tournament, bye_id, 0)
                    # remove this player from the standings tuple
                    standings = tuple(x for x in standings if x[0] != bye_id)
    # standing will now have an even number of players
    # use minimum weight maximum match graph theory algorithm
    # to assign Swiss Pairings and avoid rematches(due to high rematch weight)
    """ Minimum weight maximum matching algorithm and modifications from
        http://healthyalgorithms.com/2009/03/23/aco-in-python-minimum-weight-perfect-matchings-aka-matching-algorithms-and-reproductive-health-part-4/
    """        
    edges = weights(standings, tournament) 
    # neg weights in max weight match algorithm gives min weights
    neg_edges = [(i, j, -wt) for i, j, wt in edges]
    # use the graph neg_edges in the max weight algorithm to get assignments
    assignments = maxWeightMatching(neg_edges, maxcardinality=True)
    for i in range(len(assignments)):
        player_2 = assignments[i]
        # skip 2nd assignment element in the edge node pair - since all pair
        # elements are repeated the lower index element has already been assigned
        if player_2 > i:
            pairs.append((standings[i][0], standings[i][1],
                    standings[player_2][0], standings[player_2][1]))      
    return pairs
     
    conn.close()
コード例 #31
0
from mwmatching import maxWeightMatching
from random import randrange
from time import clock
from math import pow

for n in list(range(2, 151)):
    n_edges = (pow(n, 2) + n) / 2
    edges = []
    for i in list(range(n - 1)):
        for j in list(range(i + 1, n)):
            edges.append([i, j, randrange(0, n_edges)])

    # Return a list "mate", such that mate[i] == j if vertex i is matched to
    # vertex j, and mate[i] == -1 if vertex i is not matched.
    before = clock()
    match = maxWeightMatching(edges, maxcardinality=True)
    after = clock()

    print str(n) + "\t" + str(after - before)
コード例 #32
0
def main():
    # Process the cmd-line arguments
    try:
        optlist, args = getopt.getopt(sys.argv[1:], 'e:w:ch')
    except getopt.GetoptError as err:
        print(str(err))
        usage()
        sys.exit(-1)

    maxCard = False
    for o, a in optlist:
        if o == '-e':
            inputFile = a
        elif o == '-w':
            outputFile = a
        elif o == '-c':
            maxCard = True
        elif o == '-h':
            usage()
            sys.exit()
        else:
            assert False, "unhandled option"

    # Must specify input and output filenames
    try:
        inputFile
    except:
        print("Need to specify input filename")
        usage()
        sys.exit()
    try:
        outputFile
    except:
        print("Need to specify output filename")
        usage()
        sys.exit()

    # Read the input graph file
    graphArray = []
    try:
        f = open(inputFile, 'r')
    except IOError:
        print("Cannot open %s" % (inputFile))
        sys.exit()
    lineIdx = 0
    for line in f:
        line = line.rstrip()
        if lineIdx == 0:
            (vertexNum, edgeNum) = line.split()
            vertexNum = int(vertexNum)
            edgeNum = int(edgeNum)
        else:
            (vertexI, vertexJ, weight) = line.split()
            vertexI = int(vertexI)
            vertexJ = int(vertexJ)
            weight = int(weight)
            if weight < 0:
                print("Error: Weights must be >= 0")
                sys.exit(-1)
            graphArray.append((vertexI, vertexJ, weight))
        lineIdx += 1

    # Call the maximum weight matching API function
    matchArray = mwmatching.maxWeightMatching(graphArray, maxCard)

    # Convert raw output
    vertexCount = len(matchArray)
    matchVertexCount = 0
    idx = 0
    matchGraphHash = {}
    for val in matchArray:
        if val != -1:
            key = " ".join([str(num) for num in sorted([idx, val])])
            if not key in matchGraphHash:
                matchGraphHash[key] = 1
            else:
                matchGraphHash[key] += 1
            matchVertexCount += 1
        idx += 1

    # Write output to file
    try:
        f = open(outputFile, 'w')
    except IOError:
        print("Cannot open %s" % (outputFile))
        sys.exit()

    header = "%d %d" % (vertexNum, matchVertexCount / 2)
    f.write(header + "\n")
    for edge in matchGraphHash:
        f.write(edge + "\n")
    f.close()

    return
コード例 #33
0
ファイル: assign_judges.py プロジェクト: msokol416/mit-tab
def add_judges(pairings, judges, panel_points):
    # First clear any existing judge assignments
    for pairing in pairings:
        pairing.judges.clear()

    current_round_number = TabSettings.objects.get(key="cur_round").value - 1

    # Try to have consistent ordering with the round display
    random.seed(1337)
    random.shuffle(pairings)
    random.seed(1337)
    random.shuffle(judges)

    # Order the judges and pairings by power ranking (high speaking teams get high ranked judges)
    judges = sorted(judges, key=lambda j: j.rank, reverse=True)
    pairings.sort(key=lambda x: tab_logic.team_comp(x, current_round_number),
                  reverse=True)

    pprint.pprint(pairings)

    pairing_groups = [list() for panel_point in panel_points] + [list()]
    panel_gaps = {}
    current_group = 0
    for pairing in pairings:
        pairing_groups[current_group].append(pairing)
        if current_group < len(
                panel_points) and pairing == panel_points[current_group][0]:
            panel_gaps[current_group] = panel_points[current_group][1]
            current_group += 1

    pprint.pprint(panel_points)

    for (group_i, group) in enumerate(pairing_groups):
        num_rounds = len(group)
        # Assign chairs (single judges) to each round using perfect pairing
        graph_edges = []
        for (judge_i, judge) in enumerate(judges):
            for (pairing_i, pairing) in enumerate(group):
                if not judge_conflict(judge, pairing.gov_team,
                                      pairing.opp_team):
                    graph_edges.append((pairing_i, judge_i + len(group),
                                        calc_weight(judge_i, pairing_i)))
        judge_assignments = mwmatching.maxWeightMatching(graph_edges,
                                                         maxcardinality=True)
        print "wat"
        # If there is no possible assignment of chairs, raise an error
        if -1 in judge_assignments[:num_rounds] or (num_rounds > 0
                                                    and len(graph_edges) == 0):
            if len(graph_edges) == 0:
                raise errors.JudgeAssignmentError(
                    "Impossible to assign judges, consider reducing your gaps if you are making panels, otherwise find some more judges."
                )
            elif -1 in judge_assignments[:num_rounds]:
                pairing_list = judge_assignments[:len(pairings)]
                bad_pairing = pairings[pairing_list.index(-1)]
                raise errors.JudgeAssignmentError(
                    "Could not find a judge for: %s" % str(bad_pairing))
            else:
                raise errors.JudgeAssignmentError()

        # Save the judges to the pairings
        for i in range(num_rounds):
            group[i].judges.add(judges[judge_assignments[i] - num_rounds])
            group[i].chair = judges[judge_assignments[i] - num_rounds]
            group[i].save()

        # Remove any assigned judges from the judging pool
        for pairing in group:
            for judge in pairing.judges.all():
                judges.remove(judge)

        # Function that tries to panel num_to_panel rounds of the potential_pairings
        # Has built in logic to retry with lower number of panels if we fail due
        # to either scratches or wanting to many rounds
        def try_paneling(potential_pairings, all_judges, num_to_panel, gap):
            if len(potential_pairings) == 0 or num_to_panel <= 0:
                # Base case, failed to panel
                print "Failed to panel"
                return {}


            rounds = sorted(potential_pairings,
                            key=lambda r: (argmin(r.judges.all(),
                                           lambda j: j.rank).rank,) + \
                                           tuple([-1 * i for i in tab_logic.team_comp(r, current_round_number)]))
            base_judge = argmax(rounds[:num_to_panel][-1].judges.all(),
                                lambda j: j.rank)
            print "Found maximally ranked judge {0}".format(base_judge)
            potential_panelists = [
                j for j in all_judges
                if j.rank > (float(base_judge.rank) - float(gap))
            ]
            print "Potential panelists:", potential_panelists
            # If we don't have enough potential panelists, try again with fewer panels
            if len(potential_panelists) < 2 * num_to_panel:
                print "Not enough judges to panel!: ", len(
                    potential_panelists), num_to_panel
                return try_paneling(potential_pairings, all_judges,
                                    num_to_panel - 1, gap)

            panel_assignments = []
            rounds_to_panel = rounds[:num_to_panel]
            num_to_panel = len(rounds_to_panel)
            for pairing in rounds_to_panel:
                panel_assignments.append([j for j in pairing.judges.all()])

            # Do it twice so we get panels of 3
            for i in (0, 1):
                graph_edges = []
                for (judge_i, judge) in enumerate(potential_panelists):
                    for (pairing_i, pairing) in enumerate(rounds_to_panel):
                        if not judge_conflict(judge, pairing.gov_team,
                                              pairing.opp_team):
                            judges = panel_assignments[pairing_i] + [judge]
                            graph_edges.append(
                                (pairing_i, judge_i + num_to_panel,
                                 calc_weight_panel(judges)))
                pprint.pprint(graph_edges)
                judge_assignments = mwmatching.maxWeightMatching(
                    graph_edges, maxcardinality=True)
                print judge_assignments
                if ((-1 in judge_assignments[:num_to_panel])
                        or (num_to_panel > 0 and len(graph_edges) == 0)):
                    print "Scratches are causing a retry"
                    return try_paneling(potential_pairings, all_judges,
                                        num_to_panel - 1, gap)
                # Save the judges to the potential panel assignments
                judges_used = []
                for i in range(num_to_panel):
                    judge = potential_panelists[judge_assignments[i] -
                                                num_to_panel]
                    panel_assignments[i].append(judge)
                    judges_used.append(judge)
                # Remove any used judges from the potential panelist pool
                for judge in judges_used:
                    print "Removing {0}".format(judge)
                    potential_panelists.remove(judge)

            print "panels: ", panel_assignments
            result = {}
            for (panel_i, panel) in enumerate(panel_assignments):
                result[rounds_to_panel[panel_i]] = panel
            return result

        # Use the try_paneling function for any rounds that have been marked as panel
        # points, note that we start with trying to panel the entire bracket and
        # rely on try_paneling's retries to fix it
        if group_i in panel_gaps and panel_gaps[group_i]:
            panels = try_paneling(group, judges, len(group),
                                  panel_gaps[group_i])
            for (pairing, panelists) in panels.iteritems():
                for panelist in panelists:
                    if panelist not in pairing.judges.all():
                        pairing.judges.add(panelist)
                        judges.remove(panelist)
                pairing.save()
コード例 #34
0
from mwmatching import maxWeightMatching
import sys

edges = []

filepath = sys.argv[1]

with open(filepath, "r") as f:
    lines = f.readlines()
    for line in lines:
        edge = [int(x) for x in line.rstrip('\n').split(" ")]
        edge[2] = edge[2]*-1
        edges.append(edge)
        
matching_assignment = maxWeightMatching(edges, maxcardinality=True)

matching_edges = []
for i in range(len(matching_assignment)):
    if (i < matching_assignment[i]):
        matching_edges.append([i, matching_assignment[i]])

print matching_edges
コード例 #35
0
ファイル: scheduler-delta.py プロジェクト: aoanla/RDWC2018
def pair_round(teams, amalfi, tsp=False, output=True, fullwidth=False):
    ordering = calc_ordering(teams)
    edges = []
    matrix = {}
    for team, i in zip(teams, range(len(teams))):
        for opp in team['eligible_opponents']:
            if opp > i:  #we've not done this pairing before
                #generate weightings
                wt = Weight(
                    i, opp, amalfi, ordering
                )  #amalfi here for "ideal distance" of rating pairing
                #add edge
                edges.append((i, opp, wt))
    #print edges
    #print max(-e[2] for e in edges)
    if (tsp == True):
        #for TSP (for max-weight matching, we just don't add the completed links at all)
        minwt = min(-e[2] for e in edges)
        maxwt = max(-e[2] for e in edges)
        wtrange = maxwt - minwt
        goodwt = minwt - wtrange  #very good
        badwt = maxwt + wtrange  #very bad
        #print "{0} Good, {1} Bad, {2} min, {3} max, {4} range".format(goodwt,badwt,minwt,maxwt,wtrange)
        #negw = 2 * maxwt #we want the prev opponents, other than the most recent, to be really unpopular
        for team, i in zip(teams, range(len(teams))):
            for opp in team['prev_opponents'][:-1]:  #all but last one
                if opp > i:
                    wt = -badwt
                    edges.append((i, opp, wt))
            if len(team['prev_opponents']) > 0:
                edges.append(
                    (i, team['prev_opponents'][-1], -goodwt)
                )  #the most recent opponent is a *perfect* link, so we always select it (these have twice the weight of anything else)			#for TSP we need a matrix - and we also need the "best" value to be smallest, not largest
        #make matrix of dist
        matrix = {}
        for i in range(len(teams)):
            matrix[i] = {}
            for j in range(i, len(teams)):
                matrix[i][j] = badwt - goodwt
        for e in edges:
            matrix[e[0]][
                e[1]] = -e[2] - goodwt  #fill in edge weights where they exist
        #print matrix
    #print edges
    if (tsp == False):
        pair_dests = mwmatching.maxWeightMatching(edges, maxcardinality=True)
    else:
        pair_dests = [None] * len(teams)

        def Distance(i, j):
            if i < j:
                return matrix[i][j]
            else:
                return matrix[j][i]

        routing = pywrapcp.RoutingModel(
            len(teams), 1, 0
        )  #create the routing model in Google OR Tools, for 1 route to find, all nodes, start at node 0
        search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()

        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
        #use GUIDED_LOCAL_SEARCH metaheuristic (could also turn on Simulated Annealing, or Tabu Search)
        search_parameters.local_search_metaheuristic = (
            routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
        search_parameters.time_limit_ms = 60000  #allow 60 seconds of processing to improve the path via above metaheuristic
        routing.SetArcCostEvaluatorOfAllVehicles(Distance)
        assignment = routing.SolveWithParameters(search_parameters)
        if assignment:  #we have a solution
            total_weight = assignment.ObjectiveValue()
            index = routing.Start(
                0)  #get first node in route 0 (the only route we look for)
            #we assume that the next value will be the previous pair from the last matching, as that's a zero weight path
            next_idx = assignment.Value(routing.NextVar(index))
            pairs_ = []
            pairs_.append((index, next_idx))
            while (not routing.IsEnd(next_idx)
                   ):  #while we're not at the end of the chain -
                index = next_idx
                next_idx = assignment.Value(routing.NextVar(index))
                pairs_.append((index, next_idx))
            if pairs_[-1][-1] == len(teams):
                #this is the sentinel value, so we replace it with 0
                pairs_ = pairs_[:-1]
                pairs_.append((index, 0))  #and close the loop
            #half of these pairs are hopefully the zero-length matches from previous match, so
            #print pairs_
            if fullwidth == False:
                pairs = [
                    p for p in pairs_ if Distance(p[0], p[1]) != 0
                ]  #remove any zero weight pairs, which should *only* be the previous matches
            else:
                pairs = [p for p in pairs_]
            #check len pairs is len(teams)/2
            #if len(pairs) != len(teams)/2:
            #	#oh no!
            #	print "length of pairs not expected!"
            #	print pairs
            #	sys.exit(33)
            for p in pairs:  #and make our pair dests
                pair_dests[p[0]] = p[1]
                if fullwidth == False:
                    pair_dests[p[1]] = p[0]
    #remove the new opponent from the eligible opponents list for next time
    if fullwidth == True:
        for p in pair_dests:
            pp = pair_dests[p]
            if pp in teams[p]['eligible_opponents']:
                teams[p]['eligible_opponents'].remove(pp)
                teams[p]['prev_opponents'].append(pp)
            if p in teams[pp]['eligible_opponents']:
                teams[pp]['eligible_opponents'].remove(p)
                teams[pp]['prev_opponents'].append(p)
            #remove all desires satisfied by p
            if p in top8:
                teams[pp][
                    'desires_wt'] = -1  #actively suppress adjacent top8 games for any team
            elif teams[pp]['desires_wt'] > 0:
                teams[pp]['desires_wt'] *= 2
            if pp in top8:
                teams[p]['desires_wt'] = -1
            elif teams[p]['desires_wt'] > 0:
                teams[p][
                    'desires_wt'] *= 2  #and multiply up the desire if it isn't 0
    else:
        for p, t in zip(pair_dests, teams):
            if (p == -1):  #no match
                continue
            if (p not in t['prev_opponents']):
                try:
                    t['eligible_opponents'].remove(p)
                    t['prev_opponents'].append(
                        p)  #and add to previous opponents list
                except:
                    print "Failure to remove item: {0} (from {1})".format(
                        p, t['name'])
                    #sys.exit(1)
            #remove all desires satisfied by p
            if p in top8:
                #t['desires_wt'] = -2 #actively suppress multiple top8 matches for a team
                #try just removing all the top8s
                t['desires_wt'] = 0
                for ii in top8:
                    #print ii
                    #print t['eligible_opponents']
                    try:
                        t['eligible_opponents'].remove(
                            ii)  #remove all top8 teams as potential matches
                    except:
                        pass
                    try:
                        teams[ii]['eligible_opponents'].remove(
                            lookup[t['name']])  #must be mutual!
                    except:
                        pass
                #print t['eligible_opponents']
            elif t['desires_wt'] > 0:
                t['desires_wt'] *= 1  #and multiply up the desire if it isn't 0

    #and process the pairs as actual pairs (remove duplication, and present as duples)
    pairs = []
    if output:
        for p, i in zip(pair_dests, range(len(teams))):
            if fullwidth == False:  #list not symmetric in fullwidth
                if p < i:  #already did this one
                    continue
            pairs.append((i, p))
            print teams[i]['name'] + ' vs ' + teams[p]['name'] + '\n'
        #return pairs for this round [side-effect: teams are modified]
        return pairs
コード例 #36
0
            (vertexNum, edgeNum) = line.split()
            vertexNum = int(vertexNum)
            edgeNum = int(edgeNum)
        else:
            (vertexI, vertexJ, weight) = line.split()
            vertexI = int(vertexI)
            vertexJ = int(vertexJ)
            weight = int(weight)
            if weight < 0:
                print "Error: Weights must be >= 0"
                sys.exit(-1)
            graphArray.append((vertexI, vertexJ, weight))
        lineIdx += 1

    # Call the maximum weight matching API function
    matchArray = mwmatching.maxWeightMatching(graphArray, maxCard)

    # Convert raw output
    vertexCount = len(matchArray)
    matchVertexCount = 0
    idx = 0
    matchGraphHash = {}
    for val in matchArray:
        if val != -1:
            key = " ".join([str(num) for num in sorted([idx, val])])
            if not key in matchGraphHash:
                matchGraphHash[key] = 1
            else:
                matchGraphHash[key] += 1
            matchVertexCount += 1
        idx += 1
コード例 #37
0
ファイル: call_mwwatching.py プロジェクト: Grzechooo/CLOT
from mwmatching import maxWeightMatching


edges = [(1,2,-10) , (30,40,-100) , (1,30,-20) , (2,40,-30)]
ans = maxWeightMatching(edges,True)
print ans
コード例 #38
0
def swissPairings(tournId):
    """Returns a list of pairs of players for the next round of a match.

    Each player is paired with another player with an equal or nearly-equal
    win record, that is, a player adjacent to him or her in the standings.
    Rematches are guaranteed not to occur, and if there is an odd number of
    players then one player will randomly be selected to have bye (automatic
    win). Each play will only recieve one bye per tournament.

    To find optimal pairings, all non-rematch pairings are represented as edges
    in graph of player nodes, with edges weighted inversely proportionaly to the
    difference in wins between the two players. The maximum weighted pairings
    are then calculated use the algorithm found at:
    http://jorisvr.nl/article/maximum-matching
    This approach was inspired by this article:
    https://www.leaguevine.com/blog/18/swiss-tournament-scheduling-leaguevines-new-algorithm/
    NOTE: This algorithm is O(n^3)

    Returns:
      A list of tuples, each of which contains (id1, name1, id2, name2)
        id1: the first player's unique id
        name1: the first player's name
        id2: the second player's unique id
        name2: the second player's name
    """

    # Check round is complete
    if not roundComplete(tournId):
        raise RuntimeError(
            'Round not complete, complete it before calling swissPairings')
    standings = playerStandings(tournId)
    pairings = []

    # Give one player bye if neccesary.
    if len(standings) % 2 != 0:
        players = set(standings)
        while players:
            # Randomly select player for bye.
            player = random.sample(players, 1)[0]
            if not hadBye(tournId, player.id):
                byePlayer = player
                break
            else:
                # Player has already had bye, try again.
                players.remove(player)
        else:
            # For some all players have had bye, should never happen!
            raise RuntimeError('Could not find player who has not had bye')

        # Remove the bye player from standings list
        standings.pop(standings.index(byePlayer))
        pairings.append([byePlayer.id, byePlayer.name, None, None])

    # Generate edges
    edges = []
    # Iterate of all possible matchups, to build edges in graph.
    for i in range(len(standings)):
        for j in range(i + 1, len(standings)):
            player = standings[i]
            opponent = standings[j]
            if not haveAlreadyPlayed(tournId, player.id, opponent.id):
                # Using maximum weighted pairings algorithm,
                # weight = matches_played - difference_in_wins, for fairest matches.
                difference_in_wins = abs(player.wins - opponent.wins)
                weight = player.matches_played - difference_in_wins
                edges.append((i, j, weight))

    # Algorithm returns results as list, where the each value represents
    # the opponent of each index, eg.
    # [2, 3, 0, 1] mean player 0 plays player 2 and player 1 plays player 3.
    # Now convert this list into list of pairings.
    matches_list = maxWeightMatching(edges, maxcardinality=True)
    for player_idx, opponent_idx in enumerate(matches_list):
        if player_idx > opponent_idx:
            # Pair will have been created in previous iteration.
            continue
        player, opponent = standings[player_idx], standings[opponent_idx]
        pairings.append((player.id, player.name, opponent.id, opponent.name))
    return pairings
コード例 #39
0
from mwmatching import maxWeightMatching
from random import randrange
from time import clock
from math import pow

for n in list(range(2, 151)):
  n_edges = (pow(n, 2) + n) / 2
  edges = []
  for i in list(range(n - 1)):
    for j in list(range(i + 1, n)):
      edges.append([i, j, randrange(0, n_edges)])

  # Return a list "mate", such that mate[i] == j if vertex i is matched to
  # vertex j, and mate[i] == -1 if vertex i is not matched.
  before = clock()
  match = maxWeightMatching(edges, maxcardinality=True)
  after = clock()

  print str(n) + "\t" + str(after - before)
コード例 #40
0
ファイル: splitter.py プロジェクト: jolynch/splitit
    def split(self, items, actors, costs, exclusive=True):
        print "Attempting to split:"
        print "== Items: "
        pprint(items)
        print "== between:"
        pprint(actors)
        print "== as per the costs:"
        pprint(costs)
        print "== Expanding the actors and items =="

        def expand_list(lst, new_length):
            # This ensures that if we have more items than actors or more actors
            # than items, we ensure that we always return the optimal result
            expanded_lst = lst * (new_length / len(lst))
            return [item + "-" + str(index / len(lst)) for index, item in enumerate(expanded_lst)]

        lcm_actors_items = lcm(len(actors), len(items))
        expanded_actors = expand_list(actors, lcm_actors_items)
        expanded_items = expand_list(items, lcm_actors_items)

        cost_dict = {}
        for cost in costs:
            cost_dict[(cost.item, cost.actor)] = cost

        exp_cost = {}
        for actor in expanded_actors:
            for item in expanded_items:
                root_actor = actor[: actor.rfind("-")]
                root_item = item[: item.rfind("-")]
                real_item = item[item.find("-") + 1 :] == "0"
                if real_item:
                    original_cost = cost_dict[(root_item, root_actor)]
                    exp_cost[(item, actor)] = Cost(item, actor, original_cost.amount)
                else:
                    exp_cost[(item, actor)] = Cost(item, actor, 0)

        cost_dict = exp_cost
        new_costs = [Cost(b.item, b.actor, b.amount) for k, b in cost_dict.iteritems()]
        averages = self.calc_averages(expanded_items, new_costs)

        edges = []
        for i in range(len(expanded_items)):
            for j in range(len(expanded_actors)):
                if (expanded_items[i], expanded_actors[j]) in cost_dict:
                    cost = cost_dict[(expanded_items[i], expanded_actors[j])]
                    edges.append((i, len(expanded_items) + j, self.score(cost, averages)))

        # Actually do the auction, maximizing whatever score function we have
        mw = mwmatching.maxWeightMatching(edges, maxcardinality=True)
        result = {}
        for i in range(len(expanded_items)):
            if mw[i] != -1:
                winner = expanded_actors[mw[i] - len(expanded_items)]
                result[expanded_items[i]] = (winner, cost_dict[(expanded_items[i], winner)].amount)
            else:
                result[expanded_items[i]] = None

        final_result = {}
        for item, winner in result.iteritems():
            root_item = item[: item.rfind("-")]
            root_winner = (winner[0][: winner[0].rfind("-")], winner[1])
            real_item = item[item.find("-") + 1 :] == "0"
            if real_item:
                final_result[root_item] = root_winner

        return final_result
コード例 #41
0
def getMatchedList_Swiss(tourney_id):
	"""pair up the players according to the swiss tournament matching rules"""

	#head_to_head_biggermat
	head_to_head_biggermat, head_to_head_2d = new_utility_functions.getHeadToHeadTable(tourney_id)

	num_players = len(head_to_head_biggermat)-1
	assert(num_players>=2)

	#in this function, we use ids from 0 to num_players.
	#here, we create a mapping from these ids to the database's player_ids, 
	#randomly shuffled to try and avoid paterns in the matching
	temp = deepcopy(head_to_head_biggermat[0][1:])
	playersidlocal_playerids = [temp[i] for i in range(0,num_players)]
	#logging.info('playersidlocal_playerids')
	#logging.info(playersidlocal_playerids)

	num_wins = []
	num_games = []
	for i in range(0,num_players):
		num_wins.append(0)
		num_games.append(0)
		for j  in range(0,num_players):
			num_wins[i] += head_to_head_2d[i][j][0]
			num_games[i] += (head_to_head_2d[i][j][0]+head_to_head_2d[i][j][0])/2

	#deal with odd num_players
	player_who_sits_out = -1
	if num_players%2 == 1:
		tmp = zip(num_games,range(0,num_players))
		tmp.sort()
		#logging.info('tmp')
		#logging.info(tmp)
		player_who_sits_out = tmp[-1][1] #this player is one who has highest number of games
		logging.info('player_who_sits_out')
		logging.info(player_who_sits_out)

	#make edges
	edges=[]
	for i in range(0,num_players):
		for j  in range(i+1,num_players):
			if (head_to_head_2d[i][j][0]==0) and (head_to_head_2d[i][j][1]==0):
				if (player_who_sits_out!=i) and (player_who_sits_out!=j):
					# i,j have not played yet
					abs_win_diff = abs(num_wins[i]-num_wins[j])
					edges.append((i,j,-abs_win_diff+0.1*random.random())) #note the - sign.  the 0.1*random.random() is to randomise things WITHOUT changing the ranking of num wins etc. 
				else:
					edges.append((i,j,-1000000)) #a big number, to ensure we never make this match
	#logging.info('edges')
	#logging.info(edges)

	#call the clever matching algorithm
	matchups = maxWeightMatching(edges,True)
	#logging.info('matchups')
	#logging.info(matchups)
	if not matchups:
		return [] #we havent got any matchups.  likely that the tournament is over. 

	#package matchups into right format
	doneq = [False] * num_players
	new_match_list = []
	for i in range(0,len(matchups)):
		if not doneq[i]:
			doneq[i]=True
			j = matchups[i]
			if j != -1:
				doneq[j]=True
			
				i_id = playersidlocal_playerids[i]
				j_id = playersidlocal_playerids[j]
			
				new_match_list.append(str(i_id))
				new_match_list.append(str(j_id))
	##if player_who_sits_out >= 0:
	##	new_match_list.append(str(playersidlocal_playerids[player_who_sits_out])) #he wont get a game though, because of the odd number

	#logging.info('new_match_list')
	#logging.info(new_match_list)
	
	return new_match_list
コード例 #42
0
def swissPairings(tournament):
    """Returns a list of pairs of players for the next round of a match.
  
    Assuming that there are an even number of players registered, each player
    appears exactly once in the pairings.  Each player is paired with another
    player with an equal or nearly-equal win record, that is, a player adjacent
    to him or her in the standings.
    
    Args:
      tournament:  the tournament id you want to run swiss pairings on
  
    Returns:
      A list of tuples, each of which contains (id1, name1, id2, name2)
        id1: the first player's unique id
        name1: the first player's name
        id2: the second player's unique id
        name2: the second player's name
        
    Algorithm to pair and ensure no rematches was modeled on Leaguevine:
    https://www.leaguevine.com/blog/18/swiss-tournament-scheduling-leaguevines-new-algorithm/
    with modifications to weighting to make it a function of win & rank difference.
    The minimum weight maximum match algorithm was implemented based on work in:
    http://healthyalgorithms.com/2009/03/23/aco-in-python-minimum-weight-perfect-matchings-aka-matching-algorithms-and-reproductive-health-part-4/
    And the actual maximum weight matching algorithm code used is by Joris van Rantwijk:
    http://jorisvr.nl/maximummatching.html 
    """
    pairs = []
    conn = connect()
    c = conn.cursor()
    standings = playerStandings()
    # figure out who gets a bye if there are an odd number of players
    num_of_players = len(standings)
    if (num_of_players % 2) > 0:
        # assign a bye to the lowest standing player without a bye
        byes = whoHadABye(tournament)
        player = num_of_players - 1
        if len(byes) == 0:
            # assign the last player if no one has a bye yet
            bye_id = standings[player][0]
            reportMatch(tournament, bye_id, 0)
            # remove this player from the standings tuple
            standings = tuple(x for x in standings if x[0] != bye_id)
        else:
            # assign the bye to the lowest player who hasn't had one
            bye_id = -1
            while bye_id < 0:
                if (standings[player][0],) in byes:
                    player -= 1
                    # condition below should never be reached as rounds < players
                    if player == -1:
                        bye_id = standings[0][0]
                else:
                    bye_id = standings[player][0]
                    # record a bye for this player
                    reportMatch(tournament, bye_id, 0)
                    # remove this player from the standings tuple
                    standings = tuple(x for x in standings if x[0] != bye_id)
    # standing will now have an even number of players
    # use minimum weight maximum match graph theory algorithm
    # to assign Swiss Pairings and avoid rematches(due to high rematch weight)
    """ Minimum weight maximum matching algorithm and modifications from
        http://healthyalgorithms.com/2009/03/23/aco-in-python-minimum-weight-perfect-matchings-aka-matching-algorithms-and-reproductive-health-part-4/
    """
    edges = weights(standings, tournament)
    # neg weights in max weight match algorithm gives min weights
    neg_edges = [(i, j, -wt) for i, j, wt in edges]
    # use the graph neg_edges in the max weight algorithm to get assignments
    assignments = maxWeightMatching(neg_edges, maxcardinality=True)
    for i in range(len(assignments)):
        player_2 = assignments[i]
        # skip 2nd assignment element in the edge node pair - since all pair
        # elements are repeated the lower index element has already been assigned
        if player_2 > i:
            pairs.append((standings[i][0], standings[i][1], standings[player_2][0], standings[player_2][1]))
    return pairs

    conn.close()
コード例 #43
0
ファイル: parittaja.py プロジェクト: mniemela/mtg-parittaja
    def parita(self):
        self.kierros += 1
        #jos single elimination, paritetaan sillä tavalla
        if self.single_elimination:
            self.paritaEliminaatio()
            return
        viimeinen = self.kierros == self.max_kierrokset
        kierros_pelaajat = []
        #otetaan kierroksella mukana olevat pelaajat standingsien
        #mukaisessa järjestyksessä listaan
        score = -1
        bracket = []
        i = 0
        for p in sorted(self.pelaajat.itervalues()):
            if p.dropped:
                continue
            elif score != p.score():
                i += 1
                bracket.append(i)
                kierros_pelaajat.append(p)
                score = p.score()
            else:
                kierros_pelaajat.append(p)
                bracket.append(i)
        #jos pariton määrä pelaajia, lisätään bye
        if len(kierros_pelaajat) % 2 == 1:
            kierros_pelaajat.append(self.bye)
            bracket.append(i)
        edges = []
        weights = [x for x in range((len(kierros_pelaajat)**2 -
            len(kierros_pelaajat)) / 2)]
        i = 0
        #Jos on edetty 'matriisin' diagonaalille (eli ollaan pelaajan
        #itsensä kohdalla), hypätään seuraavaan sarakkeeseen. Jo pelanneiden painoarvo on 0. 
        #Score-erotuksesta saa penaltyä painoarvoon.
        
        if not viimeinen:
            for p in kierros_pelaajat:
                j = 0
                for r in kierros_pelaajat:
                    if p.nimi == r.nimi:
                        break
                    elif p.onkoPelannut(r):
                        edges.append((i, j, 0))
                        weights.pop()
                    #Byen menemiseen korkeampaan brackettiin isompi penalty kuin
                    #normaaliin down/uppairaukseen
                    elif p.nimi == "**Bye**" or r.nimi == "**Bye**":
                        edges.append((i, j, 200000 - abs(bracket[i] - bracket[j])**2 * 
                            6000 - weights.pop(random.randint(0, len(weights) - 1))))
                    else:
                        edges.append((i, j, 200000 - abs(bracket[i] - bracket[j])**2 * 
                            2000 - weights.pop(random.randint(0, len(weights) - 1))))
                    j += 1
                i += 1
        #täällä käydään läpi pelaajat, lisääminen aloitetaan kun on päästy pelaajasta
        #itsestään yli, seuraavalle standingeissä jota vastaan voi pelata annetaan parempi paino.
        else:
            paired = [False for x in range(len(kierros_pelaajat))]
            for p in kierros_pelaajat:
                j = i
                for r in kierros_pelaajat[i:]:
                    if p.nimi == r.nimi:
                        j += 1
                    elif p.onkoPelannut(r):
                        edges.append((j, i, 0))
                        j += 1
                        weights.pop()
                    elif not paired[i] and not paired[j]:
                        paired[i] = True
                        paired[j] = True
                        edges.append((j, i, 200000 - weights.pop(random.randint(0, len(weights) - 1))))
                        j += 1
                    else:
                        edges.append((j, i, 150000 - weights.pop(random.randint(0, len(weights) - 1))))
                        j += 1
                i += 1

                    
        tulos = mwmatching.maxWeightMatching(edges)
        i = 0
        kaytetty = []
        #lisätään matsit, jos on jo lisättynä niin jatketaan
        for p in tulos:
            if i in kaytetty:
                i += 1
                continue
            self.matsit.append(Matsi(kierros_pelaajat[i], kierros_pelaajat[p]))
            kaytetty.append(p)
            i += 1