Add files via upload
This commit is contained in:
parent
17e02692cd
commit
7445a8399c
@ -62,9 +62,9 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# `all_pairs(P)`\n",
|
"# All Pairs of Players\n",
|
||||||
"\n",
|
"\n",
|
||||||
"We will generate all pairs of players like this:"
|
"We will generate all partner pairs of players like this:"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -144,7 +144,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"# `make_games(pairs)`\n",
|
"# `make_games(pairs)`\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Now let's take those pairs and place them together into games. We'll choose one pair of players, `A`, and then another pair `B` such that between them there are 4 different players. Then we'll try to make `other_games` out of the remaining pairs. If we can't, we'll make a different choice for `B`. "
|
"Now let's take those pairs and place them together into games. We'll choose one pair of players, `A`, to play against another pair `B`, making sure that between the two pairs there are four different players. Then we'll try to make `other_games` out of the remaining pairs. If we can't, we'll make a different choice for `B`. "
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -266,9 +266,9 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"That looks good. Note that `make_games` does not ensure that each player plays every other player twice—we'll worry about that later.\n",
|
"That looks good. Note that `make_games` does not ensure that each player plays every other player twice—we'll worry about that later.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# `schedule(games, courts)`\n",
|
"# Scheduling Games to Courts\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Now we need to schedule games onto courts, such that no player plays twice in any round, and we take as few rounds as possible. We'll define `schedule` to produce a `list` of rounds, where each round is a tuple of up to `courts` games. We'll use a greedy approach to assigning games to rounds; this may result in more rounds than is optimal."
|
"Now we need to schedule games onto courts in rounds, such that no player plays twice in any round, and we take as few rounds as possible. We'll define `schedule` to produce a `list` of rounds, where each round is a tuple of up to `courts` games. We'll use a greedy approach to assigning games to rounds; this does *not* guarantee the shortest possible schedule."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -405,6 +405,7 @@
|
|||||||
" print(fmt(row, *[c or '-' for c in counts], sum(counts) / 2))\n",
|
" print(fmt(row, *[c or '-' for c in counts], sum(counts) / 2))\n",
|
||||||
" \n",
|
" \n",
|
||||||
"def games_str(round):\n",
|
"def games_str(round):\n",
|
||||||
|
" \"A string representing a round of games.\"\n",
|
||||||
" return ' | '.join('{:X},{:X} vs {:X},{:X}'\n",
|
" return ' | '.join('{:X},{:X} vs {:X},{:X}'\n",
|
||||||
" .format(a, b, c, d) for ((a, b), (c, d)) in round)\n",
|
" .format(a, b, c, d) for ((a, b), (c, d)) in round)\n",
|
||||||
" \n",
|
" \n",
|
||||||
@ -791,7 +792,7 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"That's a very good schedule. It takes the minimum 15 rounds, and while not everyone plays everyone else 2 times, most counts are in the 1 to 3 range (except for pesky player 1, who faces 0 and B four times, and F zero times, and players 8 and B, who also do not play each other)."
|
"That's a good schedule. It takes the minimum 15 rounds, and although not all counts are 2, most are in the 1 to 3 range."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -800,19 +801,22 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"# Addendum: Counting Schedules\n",
|
"# Addendum: Counting Schedules\n",
|
||||||
"\n",
|
"\n",
|
||||||
"A reader asked \"*couldn't you have tried all possible schedules?*\" That's a great question! As [Ken Thompson says](https://users.ece.utexas.edu/~adnan/pike.html), \"when in doubt, use brute force.\" How many possible schedules are there? My first inclination was \"too many,\" even for *P* = 9, but is that really true? I'll count the number of schedules, approximately (that is, my formula will work exactly only for *P* where there is an even number of pairs and every round fills all the courts).\n",
|
"A reader asked \"*couldn't you have tried all possible schedules?*\" That's a great question! As [Ken Thompson says](https://users.ece.utexas.edu/~adnan/pike.html), \"when in doubt, use brute force.\" How many possible schedules are there? \n",
|
||||||
"\n",
|
"\n",
|
||||||
"- For *P* players, there are *P* × (*P* - 1) / 2 pairs of players.\n",
|
"- Assume a schedule with *R* rounds on *C* courts, with every court filled on every round.\n",
|
||||||
"- We can place these pairs into the schedule in any order, so take the factorial of the number of pairs.\n",
|
"- That means there are *G* = *CR* games and 2*G* slots in the schedule for pairs to fill.\n",
|
||||||
"- But that over-counts, because order doesn't matter in the following ways:\n",
|
"- We can fill those slots with pairs in (2*G*)! ways.\n",
|
||||||
"- The order of pairs within a game doesn't matter, so divide by 2 (for each game).\n",
|
"- But that over-counts, because order doesn't matter in the following three ways:\n",
|
||||||
"- The order of games within a round doesn't matter, so divide by the factorial of the number of courts (for each round).\n",
|
" - The order of pairs within a game doesn't matter, so divide by 2*<sup>G</sup>*.\n",
|
||||||
"- The order of rounds in the schedule doesn't matter, so divide by the factorial of the number of rounds."
|
" - The order of games within a round doesn't matter, so divide *C*!*<sup>R</sup>*.\n",
|
||||||
|
" - The order of rounds in the schedule doesn't matter, so divide by *R*!.\n",
|
||||||
|
"\n",
|
||||||
|
"That gives us:"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 50,
|
"execution_count": 65,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
@ -820,37 +824,40 @@
|
|||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"{4: 15,\n",
|
"{4: 15.0,\n",
|
||||||
" 5: 945,\n",
|
" 5: 945.0,\n",
|
||||||
" 6: 2027025,\n",
|
" 8: 2.8845653137679503e+19,\n",
|
||||||
" 7: 13749310575,\n",
|
" 9: 7.637693625347176e+27,\n",
|
||||||
" 8: 28845653137679503125,\n",
|
" 12: 4.375874524269406e+66,\n",
|
||||||
" 9: 7637693625347175036443671875}"
|
" 13: 2.53276118507763e+83,\n",
|
||||||
|
" 16: 8.78872489906208e+147,\n",
|
||||||
|
" 17: 1.1985831550364023e+174}"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 50,
|
"execution_count": 65,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"from math import factorial as fact\n",
|
"from math import factorial\n",
|
||||||
"\n",
|
"\n",
|
||||||
"def combos(P):\n",
|
"def schedules(P):\n",
|
||||||
" pairs = P * (P - 1) // 2 \n",
|
" \"Number of possible schedules for P players with all courts full.\"\n",
|
||||||
" games = pairs // 2\n",
|
" G = P * (P - 1) // 4 # Number of games\n",
|
||||||
" courts = P // 4\n",
|
" C = P // 4 # Number of courts\n",
|
||||||
" rounds = games // courts\n",
|
" R = G // C # Number of rounds\n",
|
||||||
" return fact(pairs) // 2 ** games // fact(courts) ** rounds // fact(rounds)\n",
|
" return factorial(2 * G) / 2 ** G / factorial(C) ** R / factorial(R)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"{P: combos(P) for P in range(4, 10)}"
|
"{P: schedules(P) \n",
|
||||||
|
" for P in (4, 5, 8, 9, 12, 13, 16, 17)}"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"We see that it would have been feasible to try every schedule up to *P*=7, but not for any *P* beyond that."
|
"We see that it would have been infeasible to try every schedule, even for *P*=8, let alone 9 or 16."
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user