[Python] Swiss Scheduling System for Ping-Pong league

Discussão em 'Python' iniciado por Stack, Novembro 28, 2024.

  1. Stack

    Stack Membro Participativo

    Swiss-sched. help! please

    I am working on scheduling 8 showcases for the year. I have dataframes for each showcase that have rank and conference from where each player is from. Each showcase has a different number of players registered but it is always a different number of players. Ex. 48, 20 players. There can be some players that participate in multiple showcases or all 8.

    The ranks never change. They are set at the beginning of the year.

    In each showcase there are 3 rounds and all players have to play one game in each round. Players cannot play each other more than once throughout the entire year and cannot play another player from the same conference. The matches for players are to be determined by similar rankings.

    I've been trying to use a swiss system to schedule the games in python and I am able to generate out but it is not consistent as not all opponents are matched up in each round. I believe it is because we have an extra constraint that being 'conferences' where in a regular swiss system it is only constrained by 'rank'. The system has to be constrained by both 'rank' and 'conference'.

    Does anyone have any suggestions on any packages or types of algorithms that I could use? Or if you think there is a better way to tackle this problem.

    Thanks!!!

    ++++ Edit ++++

    Okay to be honest I'm not sure where the problem is so I'm just going to inlcude the first part:

    Here is what I did:

    class Player:
    def __init__(self, name, rating, area):
    self.name = name
    self.rating = rating
    self.area = area
    self.games_played = 0
    def optimize_pairings(players, pairings_history, round_num):
    # Ensure players list contains only Player objects
    if not all(isinstance(player, Player) for player in players):
    raise ValueError("Invalid player objects in the players list.")

    # Create a binary variable for each pair of players
    pair_vars = pulp.LpVariable.dicts("Pair", ((p1, p2) for p1 in players for p2 in players if p1 != p2), cat='Binary')

    # Create a PuLP minimization problem
    prob = pulp.LpProblem("Pairing Optimization", pulp.LpMinimize)

    # Objective: minimize the total rating difference between paired players
    prob += pulp.lpSum(pair_vars[(p1, p2)] * abs(p1.rating - p2.rating) for p1 in players for p2 in players if p1 != p2)

    # Add constraints
    for p1 in players:
    prob += pulp.lpSum(pair_vars[(p1, p2)] for p2 in players if p1 != p2) == 1 # Each player is paired with exactly one opponent

    for p1 in players:
    for p2 in players:
    if p1 != p2:
    prob += pair_vars[(p1, p2)] + pair_vars[(p2, p1)] <= 1 # No rematches between tournaments

    for p1 in players:
    for p2 in players:
    if p1 != p2:
    if p1.area == p2.area:
    prob += pair_vars[(p1, p2)] == 0 # No player can play an opponent from the same conference

    # Exclude pairings already used in previous tournaments
    for (p1, p2) in pair_vars.keys():
    if (p1, p2) in pairings_history or (p2, p1) in pairings_history:
    prob += pair_vars[(p1, p2)] == 0

    # Solve the ILP problem
    prob.solve()

    # Extract pairings from the solution
    paired_players = [(p1, p2) for (p1, p2), var in pair_vars.items() if pulp.value(var) == 1]

    # Update pairings history for the current round
    pairings_history.update({(p1, p2) for (p1, p2) in paired_players})

    return paired_players


    Here is also the link to an example of the results/data.

    Continue reading...

Compartilhe esta Página