예제 #1
0
        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
예제 #2
0
        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)))
                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
예제 #3
0
def view_round(request, round_number, errors=None):
    if errors is None:
        errors = []
    valid_pairing, byes = True, []
    round_pairing = list(Round.objects.filter(round_number=round_number))

    random.seed(1337)
    random.shuffle(round_pairing)
    round_pairing.sort(key=lambda x: tab_logic.team_comp(x, round_number),
                       reverse=True)

    #For the template since we can't pass in something nicer like a hash
    round_info = [pair for pair in round_pairing]

    paired_teams = [team.gov_team for team in round_pairing
                    ] + [team.opp_team for team in round_pairing]
    n_over_two = Team.objects.filter(checked_in=True).count() / 2
    valid_pairing = len(round_pairing) >= n_over_two or round_number == 0
    for present_team in Team.objects.filter(checked_in=True):
        if not (present_team in paired_teams):
            errors.append("%s was not in the pairing" % (present_team))
            byes.append(present_team)
    pairing_exists = len(round_pairing) > 0
    pairing_released = TabSettings.get("pairing_released", 0) == 1
    judges_assigned = all((r.judges.count() > 0 for r in round_info))
    excluded_judges = Judge.objects.exclude(
        judges__round_number=round_number).filter(
            checkin__round_number=round_number)
    non_checkins = Judge.objects.exclude(
        judges__round_number=round_number).exclude(
            checkin__round_number=round_number)
    available_rooms = Room.objects.exclude(
        round__round_number=round_number).exclude(rank=0)
    size = max(list(map(len, [excluded_judges, non_checkins, byes])))
    # The minimum rank you want to warn on
    warning = 5
    judge_slots = [1, 2, 3]

    # A seemingly complex one liner to do a fairly simple thing
    # basically this generates the table that the HTML will display such that the output looks like:
    # [ Byes ][Judges not in round but checked in][Judges not in round but not checked in]
    # [ Team1][             CJudge1              ][                 Judge1               ]
    # [ Team2][             CJudge2              ][                 Judge2               ]
    # [      ][             CJudge3              ][                 Judge3               ]
    # [      ][                                  ][                 Judge4               ]
    excluded_people = list(
        zip(*[
            x + [""] * (size - len(x)) for x in [
                list(byes),
                list(excluded_judges),
                list(non_checkins),
                list(available_rooms)
            ]
        ]))

    return render(request, 'pairing_control.html', locals())
예제 #4
0
def view_round(request, round_number, errors = None):
    if errors is None:
        errors = []
    valid_pairing, byes = True, []
    print "1: ",time.time()
    round_pairing = list(Round.objects.filter(round_number = round_number))

    random.seed(1337)
    random.shuffle(round_pairing)
    round_pairing.sort(key = lambda x: tab_logic.team_comp(x, round_number),
                       reverse = True)

    print "2: ",time.time()
    #For the template since we can't pass in something nicer like a hash
    round_info = [[pair]+[None]*8 for pair in round_pairing]
    for pair in round_info:
        pair[1] = tab_logic.tot_wins(pair[0].gov_team)
        pair[2] = tab_logic.tot_speaks(pair[0].gov_team)
        pair[3] = tab_logic.num_govs(pair[0].gov_team)    
        pair[4] = tab_logic.num_opps(pair[0].gov_team)    
        pair[5] = tab_logic.tot_wins(pair[0].opp_team)
        pair[6] = tab_logic.tot_speaks(pair[0].opp_team)
        pair[7] = tab_logic.num_govs(pair[0].opp_team)    
        pair[8] = tab_logic.num_opps(pair[0].opp_team)
    print "3: ",time.time()

    paired_teams = [team.gov_team for team in round_pairing] + [team.opp_team for team in round_pairing]
    n_over_two = Team.objects.filter(checked_in=True).count() / 2
    valid_pairing = len(round_pairing) >= n_over_two
    for present_team in Team.objects.filter(checked_in=True):
        if not (present_team in paired_teams):
            errors.append("%s was not in the pairing" % (present_team))
            byes.append(present_team) 
    pairing_exists = len(round_pairing) > 0 
    excluded_judges = Judge.objects.exclude(judges__round_number = round_number).filter(checkin__round_number = round_number)
    non_checkins = Judge.objects.exclude(judges__round_number = round_number).exclude(checkin__round_number = round_number)
    size = max(map(len, [excluded_judges, non_checkins, byes]))
    # The minimum rank you want to warn on
    warning = 5
    judge_slots = [1,2,3]
    print "4: ",time.time()

    # A seemingly complex one liner to do a fairly simple thing
    # basically this generates the table that the HTML will display such that the output looks like:
    # [ Byes ][Judges not in round but checked in][Judges not in round but not checked in]
    # [ Team1][             CJudge1              ][                 Judge1               ]
    # [ Team2][             CJudge2              ][                 Judge2               ]
    # [      ][             CJudge3              ][                 Judge3               ]
    # [      ][                                  ][                 Judge4               ]
    excluded_people = zip(*map( lambda x: x+[""]*(size-len(x)), [list(byes), list(excluded_judges), list(non_checkins)])) 

    return render_to_response('display_info.html',
                               locals(),
                               context_instance=RequestContext(request))
예제 #5
0
def view_round(request, round_number):
    errors, excluded_teams = [], []
    round_pairing = list(Round.objects.filter(round_number=round_number))

    random.seed(1337)
    random.shuffle(round_pairing)
    round_pairing.sort(key = lambda x: tab_logic.team_comp(x, round_number),
                       reverse = True)

    #For the template since we can't pass in something nicer like a hash
    round_info = [pair for pair in round_pairing]

    paired_teams = [team.gov_team for team in round_pairing] + [team.opp_team for team in round_pairing]
    n_over_two = Team.objects.filter(checked_in=True).count() / 2

    for present_team in Team.objects.filter(checked_in=True):
        if not (present_team in paired_teams):
            excluded_teams.append(present_team)

    for team in excluded_teams:
        if not Bye.objects.filter(round_number=round_number, bye_team=team).exists():
            errors.append("{} is checked-in but has no round or bye".format(team))

    pairing_exists = len(round_pairing) > 0
    pairing_released = TabSettings.get("pairing_released", 0) == 1
    judges_assigned = all((r.judges.count() > 0 for r in round_info))
    excluded_judges = Judge.objects.exclude(judges__round_number=round_number).filter(checkin__round_number = round_number)
    non_checkins = Judge.objects.exclude(judges__round_number=round_number).exclude(checkin__round_number = round_number)
    available_rooms = Room.objects.exclude(round__round_number=round_number).exclude(rank=0)
    size = max(list(map(len, [excluded_judges, non_checkins, excluded_teams])))
    # The minimum rank you want to warn on
    warning = 5
    judge_slots = [1,2,3]

    # A seemingly complex one liner to do a fairly simple thing
    # basically this generates the table that the HTML will display such that the output looks like:
    # [ Byes ][Judges not in round but checked in][Judges not in round but not checked in]
    # [ Team1][             CJudge1              ][                 Judge1               ]
    # [ Team2][             CJudge2              ][                 Judge2               ]
    # [      ][             CJudge3              ][                 Judge3               ]
    # [      ][                                  ][                 Judge4               ]
    excluded_people = list(zip(*[x+[""]*(size-len(x)) for x in [list(excluded_teams), list(excluded_judges), list(non_checkins), list(available_rooms)]]))

    return render(request, 'pairing/pairing_control.html', locals())
예제 #6
0
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)

    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

    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)
        # 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)))
                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.items():
                for panelist in panelists:
                    if panelist not in pairing.judges.all():
                        pairing.judges.add(panelist)
                        judges.remove(panelist)
                pairing.save()
예제 #7
0
def view_round(request, round_number):
    errors, excluded_teams = [], []
    round_pairing = list(Round.objects.filter(round_number=round_number))

    tot_rounds = TabSettings.get("tot_rounds", 5)

    random.seed(1337)
    random.shuffle(round_pairing)
    round_pairing.sort(key=lambda x: tab_logic.team_comp(x, round_number),
                       reverse=True)

    #For the template since we can't pass in something nicer like a hash
    round_info = [pair for pair in round_pairing]

    paired_teams = [team.gov_team for team in round_pairing
                    ] + [team.opp_team for team in round_pairing]
    n_over_two = Team.objects.filter(checked_in=True).count() / 2

    for present_team in Team.objects.filter(checked_in=True):
        if present_team not in paired_teams:
            excluded_teams.append(present_team)

    excluded_teams_no_bye = [
        team for team in excluded_teams if not Bye.objects.filter(
            round_number=round_number, bye_team=team).exists()
    ]
    num_excluded = len(excluded_teams_no_bye)

    pairing_exists = len(round_pairing) > 0
    pairing_released = TabSettings.get("pairing_released", 0) == 1
    judges_assigned = all((r.judges.count() > 0 for r in round_info))
    excluded_judges = Judge.objects.exclude(
        judges__round_number=round_number).filter(
            checkin__round_number=round_number)
    non_checkins = Judge.objects.exclude(
        judges__round_number=round_number).exclude(
            checkin__round_number=round_number)
    available_rooms = Room.objects.exclude(
        round__round_number=round_number).exclude(rank=0)
    size = max(list(map(len, [excluded_judges, non_checkins, excluded_teams])))
    # The minimum rank you want to warn on
    warning = 5
    judge_slots = [1, 2, 3]

    # A seemingly complex one liner to do a fairly simple thing
    # Generates a nested list like:
    # [ Byes ][Judges not in round][Judges not in round]
    # [ Team1][     CJudge1       ][       Judge1      ]
    # [ Team2][     CJudge2       ][       Judge2      ]
    # [      ][     CJudge3       ][       Judge3      ]
    # [      ][                   ][       Judge4      ]
    excluded_people = list(
        zip(*[
            x + [""] * (size - len(x)) for x in [
                list(excluded_teams),
                list(excluded_judges),
                list(non_checkins),
                list(available_rooms)
            ]
        ]))

    return render(request, "pairing/pairing_control.html", locals())
예제 #8
0
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)
        # 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.items():
                for panelist in panelists:
                    if panelist not in pairing.judges.all():
                        pairing.judges.add(panelist)
                        judges.remove(panelist)
                pairing.save()
예제 #9
0
 def sort_key(round_obj):
     team_comp_result = tab_logic.team_comp(round_obj,
                                            current_round_number)
     get_rank = lambda judge: judge.rank
     rank_tuple = (argmin(round_obj.judges.all(), get_rank).rank, )
     return rank_tuple + tuple([-1 * i for i in team_comp_result])