将n名玩家分配给3人团队以减少重复游戏的次数



很抱歉使用非描述性标题。这不是家庭作业问题——我有一个朋友请我帮他为他正在参加的FRC锦标赛分配队伍。

所以我有n玩家和x游戏。每场比赛有两支三人的队伍。我想制定一个时间表,尽量减少重复比赛的次数(也就是说,我不希望两支球队打两次比赛,在所有条件相同的情况下,我希望每支球队都尽可能独特(这样球员a、B和C就不会一直在同一支球队打球)。

我不是在问一个具体的答案,但也许可以指出我试图解决的问题的正式名称是什么?

编辑:

应该优先考虑尽可能多的独特(不同)游戏,同时让每个玩家玩几乎相同数量的游戏(如果可能的话,玩游戏最多和最少的玩家之间的差异可能不超过两个)。

这本身就不是循环赛,但如果像循环赛这样的锦标赛可以解决这个问题,我想听听如何解决。一名球员与另一名球员比赛的次数没有限制。

球员是可以互换的,所以一支有球员a、B和C的球队相当于一支有a、C和B的球队。

您正在寻找的一般科目是"组合设计",这是数学的一个深入而复杂的分支。

完全掌握组合设计肯定会为您的日程安排问题提供简单的解决方案。然而,这需要几十年的时间,所有这方面的专家似乎都在忙于写书。我所能得到的是,可能的游戏数量按照P!的顺序增加!。

幸运的是,锦标赛日程安排这一分支得到了一些非常务实和积极的人的关注,许多通用的解决方案也在使用。

其中哪一个值得你关注取决于你的锦标赛参数的大小:玩家数量、每轮同时进行的比赛数量以及你有时间进行的轮数。

我的第一个想法是使用"循环"调度的修改。如果你的比赛超出了循环赛,那么它可能还有其他更致命的实际困难。

使用循环赛进行团队组成的困难在于,球员最终总是与球员名单上离他们很近的其他球员在同一支球队。所以我修改了我的算法,直到团队组成、游戏组成和必须缺席一轮比赛的剩余球员(再见)分布得更均匀。

这些评论提到了与简单的循环赛的不同之处,我注意到我的最后努力与"冰雹"PRNG有一些共同之处。

parameter PLAYERCNT  // number of players
const TEAMCNT = 2  // number of teams in a game
const SLOTCNT = 3  // number of players on a team
const GAMECNT = trunc(PLAYERCNT / (TEAMCNT * SLOTCNT))  // max num simultaneous games
// the game and team assignment for one round
SEED : array [GAMECNT-1, TEAMCNT-1, SLOTCNT-1] of integer
POOL : array [PLAYERCNT-1] of boolean  // temp to mark selected players
// before generating any rounds:
BASE = 0
BUMP = 0
//
// to generate the next round:
// make all players available for this round
for PLAYER from 0 to PLAYERCNT-1 { POOL[PLAYER] = false }
// changing the bump repeatedly breaks up the teams, otherwise players always
// end up on the same team with someone within SLOTCNT on the player list
BUMP = BUMP+1  // bump part of hailstone algo
PLAYER = BASE
// changing the base distributes the collisions evenly over the list
// which also distributes the byes (players who have to sit out a round)
BASE = (BASE + (TEAMCNT * SLOTCNT)) mod PLAYERCNT  // base part of hailstone algo
// fill in the game and team assignments
for GAME from 0 to GAMECNT-1 {
for TEAM from 0 to TEAMCNT-1 {
for SLOT from 0 to SLOTCNT-1 {
SEED[GAME, TEAM, SLOT] = PLAYER
POOL[PLAYER] = true  // mark player as no longer available
// find next available player while detecting hailstone collisions
while POOL[PLAYER] {
PLAYER = (PLAYER + BUMP) mod PLAYERCNT
}
//
}
}
}
//

在测试设计中会遇到组合设计,您可以尝试修改中描述的方法http://testingeducation.org/BBST/testdesign/Cohen_AETG_System.pdf.

我假设你想要一个由一系列回合组成的时间表,每一回合都将所有参赛者分成两对三人组(或者六人一组)。然后,您的目标是最大限度地增加时间表中出现的不同的三元组/六组的数量。事实上,如果你的目标与此略有不同,只要你能区分好的时间表和坏的时间表,这里的方法仍然有效。

逐轮生成时间表,跟踪到目前为止生成的一组三元组/六组。对于每一轮,将大量随机分裂为三元组/六组,并选择发现的随机分裂,该随机分裂产生了迄今为止未见过的大多数三元组/6组。一旦你为特定的一轮选择了一个最佳的随机分组,记录下来,更新到目前为止发现的三元组/六组,然后继续下一轮。

由于这个过程是随机的,请使用不同的随机种子重复整个过程,看看你是否得到了更好的答案,并继续进行,直到你用完计算机时间。

在最初的设置中,那里描述的算法提供了使所有配对测试实用的结果。它们不如从已知的最优组合设计中产生的那些,但它很容易编程,而且非常灵活。

最新更新