2014-09-30 3 views
1

Я работаю над планировщиком турнира по боулингу. Проблема в том, что некоторые из боулеров имеют частный шар для боулинга. Таким образом, боулеры с тем же номером боулинга не могут быть в одном и том же порядке.Планировщик боулинга

я могу производить словарь, как это:

dict = {1:None,2:1,3:None,4:None,5:None,6:1,7:2,8:2,9:3,10:None} 

ДИКТ = {bowler_id, shared_ball} (None = не разделяет мяч)

Вот моя первая попытка, которая имеет проблемы:

from operator import itemgetter 

bowlers = {1:None,2:1,3:None,4:None,5:None,6:1,7:2,8:2,9:3,10:None,11:None,12:None,13:None,14:None,15:None,16:1,17:None,18:None,19:None,20:None,21:2,22:3,23:None} 
Lanes = 6 
Rounds = 6 
Schedule = {} 

sortedlist = sorted(bowlers.items(), key=itemgetter(1), reverse=True) 

for x in xrange(1,Lanes+1): 
    Schedule[''.join(['Lane', str(x)])] = [] 

while len(sortedlist) > 0: 
    z = zip(Schedule,sortedlist) 
    for i in z: 
     Schedule[i[0]].append((i[1][0] , i[1][1])) 
     sortedlist.pop(0) 
print Schedule 

У меня есть эти проблемы/проблемы:

Этот подход работает с противоположным e ffect: потому что я перейду по отсортированному списку, боулеры с одним и тем же мяч гарантированы в том же ходу.

Может ли кто-нибудь указать мне правильное направление?

Выход программы является:

{  
    'Lane6': [(9, 3), (6, 1), (10, None), (17, None)], 
    'Lane5': [(22, 3), (16, 1), (11, None), (18, None)], 
    'Lane4': [(7, 2), (1, None), (12, None), (19, None)], 
    'Lane3': [(8, 2), (3, None), (13, None), (20, None)], 
    'Lane2': [(21, 2), (4, None), (14, None), (23, None)], 
    'Lane1': [(2, 1), (5, None), (15, None)] 
} 

Каждого столбец представляет собой поворот на все дорожки. Когда вы смотрите на первый столбец, вы видите, что общие шары 3 и 2 встречаются больше, чем один раз в столбце. Это неправильно, потому что у вас не может быть двух боулеров с одним мячом за один ход.

Правильный результат будет что-то вроде:

{ 
    'Lane6': [(10, None), (9, 3),  (6, 1),  (17, None)], 
    'Lane5': [(22, 3),  (16, 1), (11, None), (18, None)], 
    'Lane4': [(7, 2),  (1, None), (12, None), (19, None)], 
    'Lane3': [(3, None), (13, None), (8, 2),  (20, None)], 
    'Lane2': [(14, None), (21, 2), (4, None), (23, None)], 
    'Lane1': [(2, 1),  (5, None), (15, None)] 
} 

Порядок боулеров может быть Randon, так как долго не существует никаких общих шаров в один ход.

+1

На самом деле, что вы хотите иметь в качестве желаемого? – Kasramvd

+0

@ Kasra Я добавил желаемый результат в тему. –

+2

* «порядок имеет значение ... поэтому словарь не является хорошим» * - ['collections.OrderedDict'] (https://docs.python.org/2/library/collections.html#collections.OrderedDict)? – jonrsharpe

ответ

1

Благодарим вас за интереснейший вызов!

Я переименовал некоторые идентификаторы, чтобы быть более значимыми, и я изменил мяч None на мяч 0, чтобы сделать выход опрятным.

Эта программа группы боулеров, в соответствии с которыми они используют, то выбирает не более одного из каждой группы, плюс любое количество боулеров, которые не используют общий мяч.

from copy import deepcopy 
from random import shuffle 
from json import dumps  # for pretty printing of results 

bowlers2balls = { 
    1:0,2:1,3:0,4:0,5:0,6:1,7:2,8:2,9:3,10:0,11:0,12:0,13:0, 
    14:0,15:0,16:1,17:0,18:0,19:0,20:0,21:2,22:3,23:0 
} 

Lanes = 6 
Schedule = {} 
min_turns = (len(bowlers2balls) - 1)/Lanes + 1 

# Create a list of lists. Bowlers with a shared ball are all in the 
# same sublist. Each bowler without a shared ball gets their own 
# sublist. Ball numbers do not appear here. 

shared = [[tup[0] for tup in bowlers2balls.items() if tup[1] == ball] 
      for ball in set(bowlers2balls.values()) if ball] 
for grp in shared: 
    shuffle(grp) 
unshared = [[tup[0]] for tup in bowlers2balls.items() if not tup[1]] 
full_bgroups = shared + unshared 

# Generate random schedules until we get one with minimum turns. It 
# often happens that we get a suboptimal one because the bowlers with 
# shared balls aren't used up. 

while True: 
    for lane in xrange(1,Lanes+1): 
     Schedule['Lane{}'.format(lane)] = [] 

    bgroups = deepcopy(full_bgroups) 
    while bgroups: 
     shuffle(bgroups) 
     for i, lane in enumerate(Schedule.keys()): 
      if i >= len(bgroups): 
       break 
      bowler = bgroups[i].pop() 
      Schedule[lane].append(
       ('{:2d}'.format(bowler), 
       bowlers2balls[bowler])) 
     # Remove emptied lists from bgroups 
     bgroups = filter(None, bgroups) 

    turns = max([len(s) for s in Schedule.values()]) 
    if turns <= min_turns: 
     break 

print (dumps(Schedule, sort_keys=True) 
     .strip('{}') 
     .replace(']], ', ']],\n')) 
+0

@Tom_Zych Спасибо за отличный ответ! Когда я начал с этой проблемы, я подумал, что это будет легко, но это действительно вызов. Единственное, что мне нужно добавить, это проверка того, что слишком много «общих шаров» используются, потому что тогда это становится бесконечным циклом. Я думаю, что для этого могу использовать общий список. –

Смежные вопросы