On May 3, 8:29 pm, John Machin <sjmac...@lexicon.net> wrote: > On May 4, 12:36 pm, Ross <ross.j...@gmail.com> wrote: > > > > > For the past couple weeks, I've been working on an algorithm to > > schedule tennis leagues given court constraints and league > > considerations (i.e. whether it's a singles or a doubles league). Here > > were my requirements when I was designing this algorithm: > > > -Each player plays against a unique opponent each week. > > -Similarly, in a doubles league, each player plays with a unique > > partner each week. > > -Each player gets a fair number of bye weeks (i.e. the player with the > > most bye weeks will have no more than one bye week than the player > > with the least number of bye weeks) > > > I'm very close to arriving at my desired solution, but I have one > > glaring flaw. When I have an even number of players sign up for my > > league and there are court constraints, my current algorithm gives the > > first player in my league a bye week every single week. I'll post my > > code below and see how you guys think I should add to/ amend my code. > > > def round_robin(players, rounds): > > if len(players)%2: > > players.insert(0, None) > > mid = len(players)//2 > > for i in range(rounds): > > yield zip(players[:mid], players[mid:]) > > players = players[0:1] + players[mid:mid+1] + players[1:mid-1] + > > players[mid+1:] + players[mid-1:mid] > > > def test_round_robin(players, rounds, courts, doubles = False): > > players = range(players) > > DON'T change the type/contents/meaning of a variable name like that. > E.g. use "nthings" for a number of things and "things" for a > collection of things. > > > for week in round_robin(players,rounds,courts): > > The round_robin() function has only TWO arguments. This code won't > even run. > > When you document neither your data structures nor what your functions > are intended to do, the last hope for somebody trying to make sense of > your code is to give meaningful names to your variables. "week" and > "doubles_week" are NOT meaningful. > > > if doubles == True: > > Bletch. s/ == True// > > > doubles_week = len(week)/2.0 > > I doubt very much that using floating point is a good idea here. > > > byes = doubles_week - courts > > if byes == 0: > > bye_list = [] > > else: > > bye_list = > > week[::int(round(1.072*(courts/byes)+1.08))] > > The derivation of the constants 1.072 and 1.08 is .... what? > > > playing = [u for u in week if u not in bye_list] > > midd = len(playing)//2 > > doub_sched = zip(playing[:midd], playing[midd:]) > > print doub_sched, bye_list > > else: > > byes = len(week)- courts > > if byes == 0: > > bye_list = [] > > else: > > bye_list = > > week[::int(round(1.072*(courts/byes)+1.08))] > > playing = [u for u in week if u not in bye_list] > > print playing, bye_list
For everybody's enlightenment, I have gone through and commented my code so you can better understand what I'm doing. Here it is: def round_robin(players, rounds): # if number of players odd, insert None at first position if len(players)%2: players.insert(0, None) mid = len(players)//2 for i in range(rounds): yield zip(players[:mid], players[mid:]) players = players[0:1] + players[mid:mid+1] + players[1:mid-1] + players[mid+1:] + players[mid-1:mid] """ rotates players like this: 1 2 -> 3 -> 4 / | 5 <- 6 <-7 <- 8 """ def test_round_robin(players, rounds, courts, doubles = False): players = range(players) for week in round_robin(players,rounds): if doubles == True: #for doubles pairings doubles_week = len(week)/2.0 byes = doubles_week - courts #number of tuples to be put into bye_list if byes == 0: bye_list = [] else: """ following formula equally spaces out tuples selected for bye_list and selects appropriate number according to length of the league""" bye_list = week[::int(round(1.072*(courts/byes)+1.08))] playing = [u for u in week if u not in bye_list] midd = len(playing)//2 doub_sched = zip(playing[:midd], playing[midd:])#matches the remaining tuples into doubles matches print doub_sched, bye_list else: byes = len(week)- courts if byes == 0: bye_list = [] else: bye_list = week[::int(round(1.072*(courts/byes)+1.08))] playing = [u for u in week if u not in bye_list] print playing, bye_list -- http://mail.python.org/mailman/listinfo/python-list