我正在寻找一种算法来生成一组计划 团队。例如,想象一下每个球队参加的运动赛季 彼此,一次作为主队,另一次作为访客团队 另一支球队。
如果球队是一名球员,那么在赛季中生成一组所有比赛都很容易 以下小组列表:
set((x, y) for x in teams for y in teams if x != y)
但是我也希望按照时间顺序对游戏进行排序 它满足有效游戏时间表的约束的方式 看起来“自然随机”。
约束是游戏列表应该可以分组成一个数字 每轮由n / 2场比赛组成的轮次(其中n是 每个团队与另一个团队配对的团队数量。
为了使时间表看起来更自然,两个团队不应该面对每个 其他两轮连续两轮。也就是说,如果(a,b)在一个中播放 圆形,游戏(b,a)不应该在分机上播放。
此外,每支球队应尽可能多地参加比赛 作为主队的客场球队和其他轮次。我不这么认为 总是可以实现这个约束,所以它更好 有事。例如,一支球队不应该打8场主场比赛 然后8场比赛。
以下是我现在的情况。该算法的主要问题是 它经常被困在while循环中。特别是当 团队数量是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)
答案 0 :(得分:2)
我找到了一个方法here,我稍微适应了这个方法:
def round_robin(units, sets = None):
""" Generates a schedule of "fair" pairings from a list of units """
count = len(units)
sets = sets or (count - 1)
half = count / 2
for turn in range(sets):
left = units[:half]
right = units[count - half - 1 + 1:][::-1]
pairings = zip(left, right)
if turn % 2 == 1:
pairings = [(y, x) for (x, y) in pairings]
units.insert(1, units.pop())
yield pairings
teams = ['a', 'b', 'c', 'd']
print list(round_robin(teams, sets = len(teams) * 2 - 2))
现在我只需将其转换为plpgsql。 :)
答案 1 :(得分:0)
REQUIREMENTS for the BALANCED ROUND ROBIN algorithm
The requirements of the algorithm can be defined by these four rules:
1) All versus all
Each team must meet exactly once, and once only, the other teams in the division league.
If the division is composed of n teams, the championship takes place in the n-1 rounds.
2) Alternations HOME / AWAY rule
The sequence of alternations HOME / AWAY matches for every teams in the division league, should be retained if possible.
For any team in the division league at most once in the sequence of consecutive matches HAHA, occurs the BREAK of the rhythm, i.e. HH or AA match in the two consecutive rounds.
3) The rule of the last slot number
The team with the highest slot number must always be positioned in the last row of the grid.
For each subsequent iteration the highest slot number of grid alternates left and right position; left column (home) and right (away).
The system used to compose the league schedule is "counter-clockwise circuit."
In the construction of matches in one round of the championship, a division with an even number of teams.
If in a division is present odd number of teams, it will be inserted a BYE/Dummy team in the highest slot number of grid/ring.
4) HH and AA are non-terminal and not initial
Cadence HH or AA must never happen at the beginning or at the end of the of matches for any team in the division.
Corrective inversion RULE performs only once, in the bottom line in the RING, LeftRight redundant inversion flip-flop RULE, so we will never obtain in the last two rounds CC or FF.
Round Robin ALGORITHM
The algorithm that satisfies rule (1) is obtained with a simple algorithm Round Robin:
where every successive round is obtained applying to the slot numbers ring a "counterclockwise" rotation.
To satisfy the rule (2) we must "improve", the simple round robin algorithm by performing balancing of Home and Away sequence.
It is performed by applying several "counterclockwise" rotations in the slot numbers ring in order to obtain acceptable combinations of slot positions for the next round.
The number of rotations required in the ring is (n / 2 -1).
So we will get that in the two successive rounds, almost all the teams playing at home in the previous round, will play away from home in the next round.
DATA STRUCTURE
n_teams: (4,6,8,..,20)
n_rounds: n_teams -1;
环 - 电路 环是这样的数据结构,即可执行和形式化地定义的特定类型的序列:环元素之间的(逆时针)旋转操作和操作INSERT_LAST_TEAM, 环内容定义匹配计划中每个特定轮次的所有匹配 Ring.Length是一个等于n_teams的偶数 Left_ring子序列:Ring子序列,元素从1到n / 2。 Right_ring子序列:具有从n / 2 + 1到n的元素的环子序列。 Match [i] = Ring_element [i]:Ring_element [n - i + 1];其中i = 1到n / 2 MATCH是由两个TEAMS组成的有序对(Home_team:Away_team)。 第一轮 主页:离开 01:07 02:06 03:05 04:08
Next_Iteration is obtained by applying these rules:
a) perform (n/2 – 1) times * ANTI CLOCKWISE ROTATIONs
b) all right column elements, below the last team, will be shifted upwards
c) INSERT_LAST_TEAM
(Insert_Last_Element_into_ Ring_onLeft (n) or
Insert_Last_Element_into_Ring_onRight(n), alternatively)
d.1) Last Line LeftRight redundant swap RULE
eventually have to swap elements in the last row once again
d.1) last team left/right - flip/flop
In the following example it will be explained how the Ring elements of 8 teams
are gradually transformed in five steps,
from from the SECOND ROUND into the THIRD ROUND.
If we start from from the SECOND ROUND:
05 :04
06 :03
07 :02
08 :01
a. After we perform THREE Anti-clockwise rotations, (n =8, 3 = 8/2 -1)
we will get the situation like this:
02 :01
03 :08
04 :07
05 :06
b. When we apply the LAST SLOT RULE:
the right column elements (06,07) below last team (08) will be shifted upwards
02 :01
03
04 :07
05 :06
c. And now we will apply the LAST SLOT RULE-bottom right,
we will get the situation which describes the THIRD ROUND:
(08 must be moved to the bottom right position)
02 :01
03 :07
04 :06
05 :08
d.1 Now it will be checked if for this iteration number (i.e. round)
depending on CODE SIX or ZERO Cadence, we eventually have to
swap elements in the last row redundantly,
Left/Right swaping
d.2 And at the end we will apply the LAST TEAM SLOT ROULE
swap left & right elements,
if in the previous iteration last team was positioned on the right,
in this iteration it should be positioned on the left bottom position,
so the last line elements will be swapped, else do nothing.
THIRD ROUND:
02 :01
03 :07
04 :06
05 :08