Я ищу алгоритм для генерации расписания для набора
команды. Например, представьте спортивный сезон, в котором каждая команда играет
друг с другом, один раз в качестве домашней команды, а другой в качестве команды на
другое поле команд.
Создать набор всех игр в сезоне легко, если команды
список команд, которые будут выполнять следующие команды:
set((x, y) for x in teams for y in teams if x != y)
Но я также хочу заказать игры в хронологическом порядке в такой
таким образом, что он удовлетворяет ограничению действительного графика игры, а также
выглядит "естественно случайным".
Ограничение состоит в том, что список игр должен быть сгруппирован в число
раундов, где каждый раунд состоит из n / 2 игр (где n является
количество команд), в которой каждая команда соединена с другой.
Чтобы расписание выглядело более естественным, две команды не должны сталкиваться с каждой
другие дважды в последовательных раундах. То есть, если (a, b) играется в одном
раунд, в игру (b, a) не следует играть в ext.
Также, насколько возможно, каждая команда должна играть в каждом следующем раунде, как
команда гостей и другие раунды в качестве хозяев поля. Я так не думаю
можно всегда выполнять это ограничение, поэтому лучше
есть вещь. Например, одна команда не должна играть в 8 домашних игр и
затем 8 выездных игр.
Вот что я получил сейчас. Основная проблема с алгоритмом заключается в том, что
это часто застревает в цикле. Особенно когда
количество команд 16 или больше. Это также очень неэффективно, потому что это
основывается на использовании функции случайной выборки и надеется получить ее правильно:
from random import sample
def season_schedule_order(teams, pairs):
n_games_per_round = len(teams) // 2
last_pairs = set()
while pairs:
r_pairs = set(sample(pairs, n_games_per_round))
# Check that each team is present once in the round.
r_teams = set(x for (x, y) in r_pairs) | set(y for (x, y) in r_pairs)
if r_teams != teams:
continue
# Check that two teams doesn't face each other again.
rev_pairs = set((y, x) for (x, y) in r_pairs)
if rev_pairs & last_pairs:
continue
pairs -= r_pairs
for p in r_pairs:
yield p
last_pairs = r_pairs
teams = set(['aik', 'djurgarden', 'elfsborg', 'gais',
'gefle', 'hacken', 'halmstad', 'helsingborg'])
pairs = set((x, y) for x in teams for y in teams if x != y)
for (ht, at) in season_schedule_order(teams, pairs):
print '%-20s %-20s' % (ht, at)