[Rod Stephens Books]
Index Books Python Examples About Rod Contact
[Mastodon] [Bluesky]
[Build Your Own Ray Tracer With Python]

[Beginning Database Design Solutions, Second Edition]

[Beginning Software Engineering, Second Edition]

[Essential Algorithms, Second Edition]

[The Modern C# Challenge]

[WPF 3d, Three-Dimensional Graphics with WPF and C#]

[The C# Helper Top 100]

[Interview Puzzles Dissected]

Title: Generate a schedule for a round robin tournament in Python

[A round robin schedule]

My book Essential Algorithms, Second Edition describes an algorithm for creating a round robin schedule in detail. You can also find a description if the algorithm used here at University of Cambridge, NRICH: Tournament Scheduling.

Function generate_round_robin_odd returns a list of lists where results[i][j] gives the opponent of team i in round j of the round robin tournament. This function works only for an odd number of teams. The link above explains the method.

def generate_round_robin_odd(num_teams): '''Return a list orlists where results[i][j] gives the opponent of team i in round j. Note: num_teams must be odd. ''' # Make an empty list of lists. results = [list(range(num_teams)) for i in range(num_teams)] # Initialize the list of teams. teams = list(range(num_teams)) # Start the rounds. n2 = (num_teams - 1) // 2 for round in range(num_teams): for i in range(n2): team1 = teams[n2 - i] team2 = teams[n2 + i + 1] results[team1][round] = team2 results[team2][round] = team1 # Set the team with the bye. results[teams[0]][round] = 'bye' # Rotate the array. rotate_list(teams) return results

Helper function rotate_list rotates the items in the team list by moving the last item to the beginning of the list. The algorithm calls this routine after each round.

def rotate_list(teams): ''' Rotate the entries one position. Move the last item to the front of the list. ''' teams.insert(0, teams.pop())

Function generate_round_robin_even returns a similar array for an even number of teams. It calls generate_round_robin_odd to make a schedule for a tournament with one fewer teams. It then expands the result array and replaces the byes with the additional team. See the link above for a more complete explanation.

def generate_round_robin_even(num_teams): # Generate the result for one fewer teams. results = generate_round_robin_odd(num_teams - 1) # Copy the results into a bigger array, # replacing the byes with the extra team. results2 = [list(range(num_teams - 1)) for i in range(num_teams)] for team in range(num_teams - 1): for round in range(num_teams - 1): if results[team][round] == 'bye': # Change the bye to the new team. results2[team][round] = num_teams - 1 results2[num_teams - 1][round] = team else: results2[team][round] = results[team][round] return results2

Finally, function generate_round_robin simply calls functions generate_round_robin_odd or generate_round_robin_even depending on whether the number of teams is odd or even.

def generate_round_robin(num_teams): if num_teams % 2 == 0: return generate_round_robin_even(num_teams) else: return generate_round_robin_odd(num_teams)

To make the algorithm more useful, this example also includes two methods that print out schedules. The following print_matrix methods just prints the schedule's rows. The entry in row i column j gives the opponents for team i in round j.

def print_matrix(schedule): for row in schedule: print(row)

The following print_schedule method prints out the tournament's rounds in a more readable format.

def print_schedule(schedule): num_teams = len(schedule) num_rounds = len(schedule[0]) for round in range(num_rounds): print(f'Round {round}') for team1 in range(num_teams): team2 = schedule[team1][round] # Only print if it's a bye or team 1 < team 2. if team2 == 'bye': print(f' {team1} has a bye') elif team1 < team2: print(f' {team1} vs. {team2}')

This code loops through the rounds. For each round, it loops through the teams.

Notice that each matchup is in each round twice. If team A plays team B, then team B also plays team A. The method doesn't need to print them both, so it only prints an entry if team A has a bye or if team A is numerically less than team B.

Download the example to see all of the details.

© 2024 Rocky Mountain Computer Consulting, Inc. All rights reserved.