Add files via upload
This commit is contained in:
parent
6773853027
commit
6c7f16fa25
422
ipynb/Pickleball.ipynb
Normal file
422
ipynb/Pickleball.ipynb
Normal file
@ -0,0 +1,422 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Scheduling a Doubles Pickleball Tournament\n",
|
||||||
|
"\n",
|
||||||
|
"My friend Steve asked for help in creating a schedule for a round-robin doubles pickleball tournament with 8 or 9 players on 2 courts. ([Pickleball](https://en.wikipedia.org/wiki/Pickleball) is a paddle/ball/net game played on a court that is smaller than tennis but larger than ping-pong.) \n",
|
||||||
|
"\n",
|
||||||
|
"To generalize: given *P* players and *C* available courts, we would like to create a **schedule**: a table where each row is a time period (a round of play), each column is a court, and each cell contains a game, which consists of two players partnered together and pitted against two other players. The preferences for the schedule are:\n",
|
||||||
|
"\n",
|
||||||
|
"- Each player should partner with each other player exactly once (or as close to that as possible).\n",
|
||||||
|
"- Fewer rounds are better (in other words, try to fill all the courts each round).\n",
|
||||||
|
"- Each player should play against each other player twice, or as close to that as possible.\n",
|
||||||
|
"- A player should not be scheduled to play two games at the same time.\n",
|
||||||
|
"\n",
|
||||||
|
"For example, here's a perfect schedule for *P*=8 players on *C*=2 courts:\n",
|
||||||
|
"\n",
|
||||||
|
" [([[1, 6], [2, 4]], [[3, 5], [7, 0]]),\n",
|
||||||
|
" ([[1, 5], [3, 6]], [[2, 0], [4, 7]]),\n",
|
||||||
|
" ([[2, 3], [6, 0]], [[4, 5], [1, 7]]),\n",
|
||||||
|
" ([[4, 6], [3, 7]], [[1, 2], [5, 0]]),\n",
|
||||||
|
" ([[1, 0], [6, 7]], [[3, 4], [2, 5]]),\n",
|
||||||
|
" ([[2, 6], [5, 7]], [[1, 4], [3, 0]]),\n",
|
||||||
|
" ([[2, 7], [1, 3]], [[4, 0], [5, 6]])]\n",
|
||||||
|
" \n",
|
||||||
|
"This means that in the first round, players 1 and 6 partner against 2 and 4 on one court, while 3 and 5 partner against 7 and 0 on the other. There are 7 rounds.\n",
|
||||||
|
"\n",
|
||||||
|
"My strategy for finding a good schedule is to use **hillclimbing**: start with an initial schedule, then repeatedly alter the schedule by swapping partners in one game with partners in another. If the altered schedule is better, keep it; if not, discard it. Repeat. \n",
|
||||||
|
"\n",
|
||||||
|
"## Coding it up\n",
|
||||||
|
"\n",
|
||||||
|
"The strategy in more detail:\n",
|
||||||
|
"\n",
|
||||||
|
"- First form all pairs of players, using `all_pairs(P)`.\n",
|
||||||
|
"- Put pairs together to form a list of games using `initial_games`.\n",
|
||||||
|
"- Use `Schedule` to create a schedule; it calls `one_round` to create each round and `scorer` to evaluate the schedule.\n",
|
||||||
|
"- Use `hillclimb` to improve the initial schedule: call `alter` to randomly alter a schedule, `Schedule` to re-allocate the games to rounds and courts, and `scorer` to check if the altered schedule's score is better.\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"(Note: with *P* players there are *P × (P - 1) / 2* pairs of partners; this is an even number when either *P* or *P - 1* is divisible by 4, so everything works out when, say, *P*=4 or *P*=9, but for, say, *P*=10 there are 45 pairs, and so `initial_games` chooses to create 22 games, meaning that one pair of players never play together, and thus play one fewer game than everyone else.)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import random\n",
|
||||||
|
"from itertools import combinations\n",
|
||||||
|
"from collections import Counter\n",
|
||||||
|
"\n",
|
||||||
|
"#### Types\n",
|
||||||
|
"\n",
|
||||||
|
"Player = int # A player is an int: `1`\n",
|
||||||
|
"Pair = list # A pair is a list of two players who are partners: `[1, 2]`\n",
|
||||||
|
"Game = list # A game is a list of two pairs: `[[1, 2], [3, 4]]`\n",
|
||||||
|
"Round = tuple # A round is a tuple of games: `([[1, 2], [3, 4]], [[5, 6], [7, 8]])`\n",
|
||||||
|
"\n",
|
||||||
|
"class Schedule(list):\n",
|
||||||
|
" \"\"\"A Schedule is a list of rounds (augmented with a score and court count).\"\"\"\n",
|
||||||
|
" def __init__(self, games, courts=2):\n",
|
||||||
|
" games = list(games)\n",
|
||||||
|
" while games: # Allocate games to courts, one round at a time\n",
|
||||||
|
" self.append(one_round(games, courts))\n",
|
||||||
|
" self.score = scorer(self)\n",
|
||||||
|
" self.courts = courts\n",
|
||||||
|
" \n",
|
||||||
|
"#### Functions\n",
|
||||||
|
" \n",
|
||||||
|
"def hillclimb(P, C=2, N=100000):\n",
|
||||||
|
" \"Schedule games for P players on C courts by randomly altering schedule N times.\"\n",
|
||||||
|
" sched = Schedule(initial_games(all_pairs(P)), C)\n",
|
||||||
|
" for _ in range(N):\n",
|
||||||
|
" sched = max(alter(sched), sched, key=lambda s: s.score)\n",
|
||||||
|
" return sched\n",
|
||||||
|
"\n",
|
||||||
|
"def all_pairs(P): return list(combinations(range(P), 2))\n",
|
||||||
|
"\n",
|
||||||
|
"def initial_games(pairs):\n",
|
||||||
|
" \"\"\"An initial list of games: [[[1, 2], [3, 4]], ...].\n",
|
||||||
|
" We try to have every pair play every other pair once, and\n",
|
||||||
|
" have each game have 4 different players, but that isn't always true.\"\"\"\n",
|
||||||
|
" random.shuffle(pairs)\n",
|
||||||
|
" games = []\n",
|
||||||
|
" while len(pairs) >= 2:\n",
|
||||||
|
" A = pairs.pop()\n",
|
||||||
|
" B = first(pair for pair in pairs if disjoint(pair, A)) or pairs[0]\n",
|
||||||
|
" games.append([A, B])\n",
|
||||||
|
" pairs.remove(B)\n",
|
||||||
|
" return games\n",
|
||||||
|
"\n",
|
||||||
|
"def disjoint(A, B): \n",
|
||||||
|
" \"Do A and B have disjoint players in them?\"\n",
|
||||||
|
" return not (players(A) & players(B))\n",
|
||||||
|
"\n",
|
||||||
|
"def one_round(games, courts):\n",
|
||||||
|
" \"\"\"Place up to `courts` games into `round`, all with disjoint players.\"\"\"\n",
|
||||||
|
" round = []\n",
|
||||||
|
" while True:\n",
|
||||||
|
" G = first(g for g in games if disjoint(round, g))\n",
|
||||||
|
" if not G or not games or len(round) == courts:\n",
|
||||||
|
" return Round(round)\n",
|
||||||
|
" round.append(G)\n",
|
||||||
|
" games.remove(G)\n",
|
||||||
|
"\n",
|
||||||
|
"def players(x): \n",
|
||||||
|
" \"All distinct players in a pair, game, or sequence of games.\"\n",
|
||||||
|
" return {x} if isinstance(x, Player) else set().union(*map(players, x))\n",
|
||||||
|
"\n",
|
||||||
|
"def first(items): return next(items, None)\n",
|
||||||
|
"\n",
|
||||||
|
"def pairing(p1, p2): return tuple(sorted([p1, p2]))\n",
|
||||||
|
" \n",
|
||||||
|
"def scorer(sched):\n",
|
||||||
|
" \"Score has penalties for a non-perfect schedule.\"\n",
|
||||||
|
" penalty = 50 * len(sched) # More rounds are worse (avoid empty courts)\n",
|
||||||
|
" penalty += 1000 * sum(len(players(game)) != 4 # A game should have 4 players!\n",
|
||||||
|
" for round in sched for game in round)\n",
|
||||||
|
" penalty += 1 * sum(abs(c - 2) ** 3 + 8 * (c == 0) # Try to play everyone twice\n",
|
||||||
|
" for c in opponents(sched).values())\n",
|
||||||
|
" return -penalty\n",
|
||||||
|
" \n",
|
||||||
|
"def opponents(sched):\n",
|
||||||
|
" \"A Counter of {(player, opponent): times_played}.\"\n",
|
||||||
|
" return Counter(pairing(p1, p2) \n",
|
||||||
|
" for round in sched for A, B in round for p1 in A for p2 in B)\n",
|
||||||
|
" \n",
|
||||||
|
"def alter(sched):\n",
|
||||||
|
" \"Modify a schedule by swapping two pairs.\"\n",
|
||||||
|
" games = [Game(game) for round in sched for game in round] \n",
|
||||||
|
" G = len(games)\n",
|
||||||
|
" i, j = random.sample(range(G), 2) # index into games\n",
|
||||||
|
" a, b = random.choice((0, 1)), random.choice((0, 1)) # index into each game\n",
|
||||||
|
" games[i][a], games[j][b] = games[j][b], games[i][a]\n",
|
||||||
|
" return Schedule(games, sched.courts)\n",
|
||||||
|
"\n",
|
||||||
|
"def report(sched):\n",
|
||||||
|
" \"Print information about this schedule.\"\n",
|
||||||
|
" for i, round in enumerate(sched, 1):\n",
|
||||||
|
" print('Round {}: {}'.format(i, '; '.join('{} vs {}'.format(*g) for g in round)))\n",
|
||||||
|
" games = sum(sched, ())\n",
|
||||||
|
" P = len(players(sched))\n",
|
||||||
|
" print('\\n{} games in {} rounds for {} players'.format(len(games), len(sched), P))\n",
|
||||||
|
" opp = opponents(sched)\n",
|
||||||
|
" fmt = ('{:2X}|' + P * ' {}' + ' {}').format\n",
|
||||||
|
" print('Number of times each player plays against each opponent:\\n')\n",
|
||||||
|
" print(' |', *map('{:X}'.format, range(P)), ' Total')\n",
|
||||||
|
" print('--+' + '--' * P + ' -----')\n",
|
||||||
|
" for row in range(P):\n",
|
||||||
|
" counts = [opp[pairing(row, col)] for col in range(P)]\n",
|
||||||
|
" print(fmt(row, *[c or '-' for c in counts], sum(counts) // 2))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# 8 Player Tournament\n",
|
||||||
|
"\n",
|
||||||
|
"I achieved (in a previous run) a perfect schedule for 8 players: the 14 games fit into 7 rounds, each player partners with each other once, and plays each individual opponent twice:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 2,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"Round 1: [1, 6] vs [2, 4]; [3, 5] vs [7, 0]\n",
|
||||||
|
"Round 2: [1, 5] vs [3, 6]; [2, 0] vs [4, 7]\n",
|
||||||
|
"Round 3: [2, 3] vs [6, 0]; [4, 5] vs [1, 7]\n",
|
||||||
|
"Round 4: [4, 6] vs [3, 7]; [1, 2] vs [5, 0]\n",
|
||||||
|
"Round 5: [1, 0] vs [6, 7]; [3, 4] vs [2, 5]\n",
|
||||||
|
"Round 6: [2, 6] vs [5, 7]; [1, 4] vs [3, 0]\n",
|
||||||
|
"Round 7: [2, 7] vs [1, 3]; [4, 0] vs [5, 6]\n",
|
||||||
|
"\n",
|
||||||
|
"14 games in 7 rounds for 8 players\n",
|
||||||
|
"Number of times each player plays against each opponent:\n",
|
||||||
|
"\n",
|
||||||
|
" | 0 1 2 3 4 5 6 7 Total\n",
|
||||||
|
"--+---------------- -----\n",
|
||||||
|
" 0| - 2 2 2 2 2 2 2 7\n",
|
||||||
|
" 1| 2 - 2 2 2 2 2 2 7\n",
|
||||||
|
" 2| 2 2 - 2 2 2 2 2 7\n",
|
||||||
|
" 3| 2 2 2 - 2 2 2 2 7\n",
|
||||||
|
" 4| 2 2 2 2 - 2 2 2 7\n",
|
||||||
|
" 5| 2 2 2 2 2 - 2 2 7\n",
|
||||||
|
" 6| 2 2 2 2 2 2 - 2 7\n",
|
||||||
|
" 7| 2 2 2 2 2 2 2 - 7\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"report([\n",
|
||||||
|
" ([[1, 6], [2, 4]], [[3, 5], [7, 0]]),\n",
|
||||||
|
" ([[1, 5], [3, 6]], [[2, 0], [4, 7]]),\n",
|
||||||
|
" ([[2, 3], [6, 0]], [[4, 5], [1, 7]]),\n",
|
||||||
|
" ([[4, 6], [3, 7]], [[1, 2], [5, 0]]),\n",
|
||||||
|
" ([[1, 0], [6, 7]], [[3, 4], [2, 5]]),\n",
|
||||||
|
" ([[2, 6], [5, 7]], [[1, 4], [3, 0]]),\n",
|
||||||
|
" ([[2, 7], [1, 3]], [[4, 0], [5, 6]]) ])"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# 9 Player Tournament\n",
|
||||||
|
"\n",
|
||||||
|
"For 9 players, I can fit the 18 games into 9 rounds, but some players play each other 1 or 3 times:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 3,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"Round 1: [1, 7] vs [4, 0]; [3, 5] vs [2, 6]\n",
|
||||||
|
"Round 2: [2, 7] vs [1, 3]; [4, 8] vs [6, 0]\n",
|
||||||
|
"Round 3: [5, 0] vs [1, 6]; [7, 8] vs [3, 4]\n",
|
||||||
|
"Round 4: [7, 0] vs [5, 8]; [1, 2] vs [4, 6]\n",
|
||||||
|
"Round 5: [3, 8] vs [1, 5]; [2, 0] vs [6, 7]\n",
|
||||||
|
"Round 6: [1, 4] vs [2, 5]; [3, 6] vs [8, 0]\n",
|
||||||
|
"Round 7: [5, 6] vs [4, 7]; [1, 8] vs [2, 3]\n",
|
||||||
|
"Round 8: [1, 0] vs [3, 7]; [2, 8] vs [4, 5]\n",
|
||||||
|
"Round 9: [3, 0] vs [2, 4]; [6, 8] vs [5, 7]\n",
|
||||||
|
"\n",
|
||||||
|
"18 games in 9 rounds for 9 players\n",
|
||||||
|
"Number of times each player plays against each opponent:\n",
|
||||||
|
"\n",
|
||||||
|
" | 0 1 2 3 4 5 6 7 8 Total\n",
|
||||||
|
"--+------------------ -----\n",
|
||||||
|
" 0| - 2 1 2 2 1 3 3 2 8\n",
|
||||||
|
" 1| 2 - 3 3 2 2 1 2 1 8\n",
|
||||||
|
" 2| 1 3 - 3 3 2 2 1 1 8\n",
|
||||||
|
" 3| 2 3 3 - 1 1 1 2 3 8\n",
|
||||||
|
" 4| 2 2 3 1 - 2 2 2 2 8\n",
|
||||||
|
" 5| 1 2 2 1 2 - 3 2 3 8\n",
|
||||||
|
" 6| 3 1 2 1 2 3 - 2 2 8\n",
|
||||||
|
" 7| 3 2 1 2 2 2 2 - 2 8\n",
|
||||||
|
" 8| 2 1 1 3 2 3 2 2 - 8\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"report([\n",
|
||||||
|
" ([[1, 7], [4, 0]], [[3, 5], [2, 6]]),\n",
|
||||||
|
" ([[2, 7], [1, 3]], [[4, 8], [6, 0]]),\n",
|
||||||
|
" ([[5, 0], [1, 6]], [[7, 8], [3, 4]]),\n",
|
||||||
|
" ([[7, 0], [5, 8]], [[1, 2], [4, 6]]),\n",
|
||||||
|
" ([[3, 8], [1, 5]], [[2, 0], [6, 7]]),\n",
|
||||||
|
" ([[1, 4], [2, 5]], [[3, 6], [8, 0]]),\n",
|
||||||
|
" ([[5, 6], [4, 7]], [[1, 8], [2, 3]]),\n",
|
||||||
|
" ([[1, 0], [3, 7]], [[2, 8], [4, 5]]),\n",
|
||||||
|
" ([[3, 0], [2, 4]], [[6, 8], [5, 7]]) ])"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# 10 Player Tournament\n",
|
||||||
|
"\n",
|
||||||
|
"With *P*=10 there is an odd number of pairings (45), so two players necessarily play one game less than the other players. Let's see what kind of schedule we can come up with:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 4,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"Round 1: (6, 7) vs (0, 5); (3, 4) vs (2, 8)\n",
|
||||||
|
"Round 2: (1, 8) vs (0, 3); (7, 9) vs (4, 5)\n",
|
||||||
|
"Round 3: (3, 6) vs (1, 7); (0, 9) vs (2, 5)\n",
|
||||||
|
"Round 4: (2, 9) vs (6, 8); (1, 3) vs (4, 7)\n",
|
||||||
|
"Round 5: (0, 8) vs (5, 7); (4, 6) vs (2, 3)\n",
|
||||||
|
"Round 6: (2, 4) vs (3, 5); (1, 6) vs (8, 9)\n",
|
||||||
|
"Round 7: (6, 9) vs (3, 7); (1, 2) vs (5, 8)\n",
|
||||||
|
"Round 8: (1, 4) vs (5, 9); (0, 7) vs (3, 8)\n",
|
||||||
|
"Round 9: (1, 5) vs (2, 7); (3, 9) vs (0, 6)\n",
|
||||||
|
"Round 10: (7, 8) vs (4, 9); (0, 1) vs (2, 6)\n",
|
||||||
|
"Round 11: (4, 8) vs (5, 6); (0, 2) vs (1, 9)\n",
|
||||||
|
"\n",
|
||||||
|
"22 games in 11 rounds for 10 players\n",
|
||||||
|
"Number of times each player plays against each opponent:\n",
|
||||||
|
"\n",
|
||||||
|
" | 0 1 2 3 4 5 6 7 8 9 Total\n",
|
||||||
|
"--+-------------------- -----\n",
|
||||||
|
" 0| - 2 2 2 - 2 2 2 2 2 8\n",
|
||||||
|
" 1| 2 - 3 2 1 2 2 2 2 2 9\n",
|
||||||
|
" 2| 2 3 - 2 2 3 2 - 2 2 9\n",
|
||||||
|
" 3| 2 2 2 - 3 - 3 3 2 1 9\n",
|
||||||
|
" 4| - 1 2 3 - 3 1 2 2 2 8\n",
|
||||||
|
" 5| 2 2 3 - 3 - 1 3 2 2 9\n",
|
||||||
|
" 6| 2 2 2 3 1 1 - 2 2 3 9\n",
|
||||||
|
" 7| 2 2 - 3 2 3 2 - 2 2 9\n",
|
||||||
|
" 8| 2 2 2 2 2 2 2 2 - 2 9\n",
|
||||||
|
" 9| 2 2 2 1 2 2 3 2 2 - 9\n",
|
||||||
|
"CPU times: user 2min 39s, sys: 661 ms, total: 2min 40s\n",
|
||||||
|
"Wall time: 2min 43s\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"%time report(hillclimb(P=10))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"In this schedule several players never play each other; it may be possible to improve on that (in another run that has better luck with random numbers).\n",
|
||||||
|
"\n",
|
||||||
|
"# 16 Player Tournament\n",
|
||||||
|
"\n",
|
||||||
|
"Let's jump to 16 players on 4 courts (this will take a while):"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 5,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"Round 1: (0, 12) vs (9, 13); (5, 10) vs (11, 15); (6, 8) vs (1, 3); (2, 7) vs (4, 14)\n",
|
||||||
|
"Round 2: (5, 12) vs (0, 10); (6, 11) vs (3, 9); (8, 15) vs (2, 14)\n",
|
||||||
|
"Round 3: (12, 15) vs (4, 6); (10, 13) vs (1, 9); (2, 5) vs (8, 11)\n",
|
||||||
|
"Round 4: (11, 14) vs (0, 9); (3, 13) vs (7, 10); (2, 15) vs (4, 12)\n",
|
||||||
|
"Round 5: (10, 11) vs (0, 15); (12, 14) vs (5, 13); (1, 8) vs (6, 9); (3, 7) vs (2, 4)\n",
|
||||||
|
"Round 6: (3, 11) vs (8, 13); (7, 9) vs (5, 15); (1, 6) vs (4, 10); (2, 12) vs (0, 14)\n",
|
||||||
|
"Round 7: (3, 10) vs (7, 12); (1, 14) vs (5, 11); (6, 13) vs (4, 8)\n",
|
||||||
|
"Round 8: (4, 5) vs (0, 8); (6, 10) vs (2, 11); (1, 13) vs (9, 15)\n",
|
||||||
|
"Round 9: (3, 5) vs (2, 9); (10, 15) vs (1, 7); (0, 11) vs (6, 12); (8, 14) vs (4, 13)\n",
|
||||||
|
"Round 10: (1, 10) vs (3, 8); (6, 7) vs (5, 9); (11, 12) vs (4, 15)\n",
|
||||||
|
"Round 11: (4, 7) vs (1, 11); (9, 14) vs (10, 12); (0, 6) vs (2, 13)\n",
|
||||||
|
"Round 12: (10, 14) vs (5, 8); (9, 12) vs (2, 3); (4, 11) vs (7, 13)\n",
|
||||||
|
"Round 13: (7, 8) vs (0, 13); (3, 12) vs (1, 5); (14, 15) vs (4, 9)\n",
|
||||||
|
"Round 14: (0, 5) vs (1, 4); (13, 14) vs (3, 15); (9, 10) vs (2, 8)\n",
|
||||||
|
"Round 15: (0, 3) vs (1, 15); (2, 6) vs (5, 7)\n",
|
||||||
|
"Round 16: (7, 11) vs (8, 12); (3, 4) vs (5, 14); (6, 15) vs (0, 2)\n",
|
||||||
|
"Round 17: (3, 14) vs (9, 11); (8, 10) vs (0, 4); (5, 6) vs (7, 15); (1, 2) vs (12, 13)\n",
|
||||||
|
"Round 18: (0, 1) vs (7, 14); (13, 15) vs (3, 6)\n",
|
||||||
|
"Round 19: (11, 13) vs (2, 10); (0, 7) vs (8, 9); (6, 14) vs (1, 12)\n",
|
||||||
|
"\n",
|
||||||
|
"60 games in 19 rounds for 16 players\n",
|
||||||
|
"Number of times each player plays against each opponent:\n",
|
||||||
|
"\n",
|
||||||
|
" | 0 1 2 3 4 5 6 7 8 9 A B C D E F Total\n",
|
||||||
|
"--+-------------------------------- -----\n",
|
||||||
|
" 0| - 2 2 - 2 2 2 2 3 2 2 2 3 2 2 2 15\n",
|
||||||
|
" 1| 2 - - 3 2 2 3 2 2 2 3 1 2 2 2 2 15\n",
|
||||||
|
" 2| 2 - - 2 2 2 3 2 2 2 2 2 3 2 2 2 15\n",
|
||||||
|
" 3| - 3 2 - 1 2 2 2 2 3 2 2 2 3 2 2 15\n",
|
||||||
|
" 4| 2 2 2 1 - 2 2 3 3 - 1 2 2 2 3 3 15\n",
|
||||||
|
" 5| 2 2 2 2 2 - 2 3 2 2 2 2 2 - 3 2 15\n",
|
||||||
|
" 6| 2 3 3 2 2 2 - 2 2 2 1 2 2 2 - 3 15\n",
|
||||||
|
" 7| 2 2 2 2 3 3 2 - 2 2 2 2 1 2 1 2 15\n",
|
||||||
|
" 8| 3 2 2 2 3 2 2 2 - 2 3 2 - 3 2 - 15\n",
|
||||||
|
" 9| 2 2 2 3 - 2 2 2 2 - 2 2 2 2 3 2 15\n",
|
||||||
|
" A| 2 3 2 2 1 2 1 2 3 2 - 3 2 2 1 2 15\n",
|
||||||
|
" B| 2 1 2 2 2 2 2 2 2 2 3 - 2 2 2 2 15\n",
|
||||||
|
" C| 3 2 3 2 2 2 2 1 - 2 2 2 - 2 3 2 15\n",
|
||||||
|
" D| 2 2 2 3 2 - 2 2 3 2 2 2 2 - 2 2 15\n",
|
||||||
|
" E| 2 2 2 2 3 3 - 1 2 3 1 2 3 2 - 2 15\n",
|
||||||
|
" F| 2 2 2 2 3 2 3 2 - 2 2 2 2 2 2 - 15\n",
|
||||||
|
"CPU times: user 15min 6s, sys: 2.67 s, total: 15min 9s\n",
|
||||||
|
"Wall time: 15min 16s\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"%time report(hillclimb(P=16, C=4))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"We get a pretty good schedule, although it takes 19 rounds rather than the 15 it would take if every court was filled, and again there are some players who never face each other."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.5.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 1
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user