Code works fine except...
Arnaud Delobelle
arnodel at googlemail.com
Fri May 8 11:41:12 EDT 2009
John Yeung <gallium.arsenide at gmail.com> writes:
> On May 5, 11:37 pm, Ross <ross.j... at gmail.com> wrote:
>
>> On May 5, 10:33 am, MRAB <goo... at mrabarnett.plus.com> wrote:
>>
>> > Here's my approach (incomplete):
>>
>> FYI... I was testing your code further and discovered a strange
>> outcome... when there are 16 people for 7 courts, every 7th
>> round your code produces 4 byes instead of the correct 2 byes.
>
> Well, MRAB did say his was incomplete, and it's significantly shorter
> and cleaner than mine.
>
> Mine has even weirder-looking behavior at 16 players on 7 courts, but
> I think it's because mine tries harder to keep things balanced. After
> a few rounds, the inequalities start to build up, and my routine picks
> some people more often to "catch up", but it doesn't prevent the same
> person from being scheduled for multiple matches the same week. There
> may also be other, more subtle ways mine is broken.
>
> It also may be that the problem is inherently unsolvable for some
> values. (I'm still waiting for someone with sufficient math ability
> to swoop in and either provide a way that works for all values, or
> confirm that there are just some unavoidable pathological cases.)
>
> John
I was thinking about this problem today. What is needed is to generate
all matches between n players in an order such that any sequence of
(n//2-1) matches does not repeat any player. If there are an even
number of players, this guarantees an even distribution of byes as well
(i.e. a difference of at most 1 between the highest and lowest number of
byes). Unfortunately, if there are an odd number of players, I don't
think this is achievable because there are two sources of byes
unbalance:
* a player needs to be left out of each 'complete round' (where each
player plays each other'
* some players are left out of each weekly round because there are not
enough tennis courts for a complete round to be played in one week.
What I believe is achievable in the case of an odd number of players is
a difference of at most two between the highest and the lowest number of
byes for any player at any point in the tournament.
I don't have a proof of this because I haven't had the time to think
about it for long enough, but I have a toy implementation which I have
tested in a very limited manner. I think it will generate tournaments
with the property that bye imbalance never exceeds 2. I also think it is
not possible to achieve better in general (it's a conjecture!).
----------------------------------------
from itertools import count
def matches(players):
"Generates all matches between players"
n = len(players)
if n % 2:
for i in xrange(n):
for j in xrange(1, 1 + n/2):
yield players[(i+j)%n], players[(i-j)%n]
else:
m = n - 1
for i in xrange(m):
yield players[-1], players[i]
for j in xrange(1, n/2):
yield players[(i+j)%m], players[(i-j)%m]
def print_matches(players):
for line in zip(*matches(players)):
print ' '.join(line)
def tournament(players, courts, nrounds=None):
"""
players: list of players
courts: list of courts
nrounds: number of rounds needed or
"""
if nrounds is None:
rounds = count(1)
else:
rounds = xrange(1, nrounds + 1)
opponents = defaultdict(list)
courts = courts[:len(players)/2]
get_match = matches(players).next
try:
for round in rounds:
print '-'*10
print 'Round', round
for court in courts:
p1, p2 = get_match()
print 'Court %s: %s - %s' % (court, p1, p2)
except StopIteration:
print "All matches played"
----------------------------------------
Example:
>>> players = ['Ann', 'Bea', 'Clo', 'Dee', 'Evi', 'Fae', 'Gil', 'Haz']
>>> courts = ['One', 'Two', 'Three']
>>> tournament(players, courts, 4)
----------
Round 1
Court One: Haz - Ann
Court Two: Bea - Gil
Court Three: Clo - Fae
----------
Round 2
Court One: Dee - Evi
Court Two: Haz - Bea
Court Three: Clo - Ann
----------
Round 3
Court One: Dee - Gil
Court Two: Evi - Fae
Court Three: Haz - Clo
----------
Round 4
Court One: Dee - Bea
Court Two: Evi - Ann
Court Three: Fae - Gil
HTH
--
Arnaud
More information about the Python-list
mailing list