将n名球员分配给3人队,以减少重复比赛次数?

时间:2014-01-13 20:09:14

标签: algorithm

对于非描述性标题,我们深表歉意。这不是一个家庭作业问题 - 我有一个朋友要求我帮助他指派参加他正在参加的FRC锦标赛的球队。

所以我有 n 玩家和 x 游戏。每场比赛都有两队三名球员。我想制定一个计划,试图减少重复游戏的数量(也就是说,我不希望两个团队互相玩两次,而且所有事情都是平等的,我宁愿每个团队都像可能(因此玩家A,B和C不会在同一个团队中一直玩))。

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

编辑:

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

这不是循环本身,但如果像类似循环赛的锦标赛可以解决这个问题,我想听听如何解决。玩家玩另一个玩家的次数没有限制。

玩家可以互换,因此拥有玩家A,B和C的团队相当于拥有玩家A,C和B的团队。

2 个答案:

答案 0 :(得分:1)

您正在寻找的一般科目是"combinatorial design",这是一个深刻而复杂的数学分支。

完全掌握组合设计肯定会为您的调度问题提供简单的解决方案。然而,这需要几十年的时间,而且该主题的所有专家似乎都在忙着写书。我所能摆脱的就是可能的游戏数量增加了P !.

幸运的是,一个支行,锦标赛安排,受益于一些非常实际和有动力的人的注意,并且许多通用解决方案是常用的。

其中哪一项值得您关注,取决于锦标赛参数的大小:玩家数量,每轮同时进行的游戏数量以及您有时间的轮次数。

我的第一个想法是使用"round-robin"调度的修改。如果您的锦标赛超出了循环赛的范围,它可能还有其他更致命的实际困难。

使用循环法进行团队合作的难度在于玩家总是与玩家列表中非常靠近他们的其他玩家在同一个团队中。所以我修改了我的算法,直到团队组成,游戏构成以及必须坐在一轮(byes)的剩余玩家分布更均匀。

评论指的是与简单循环的差异,并且我注意到我的最后努力与“hailstone”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
        }
        //
      }
    }
  }
//

答案 1 :(得分:1)

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

我假设你想要一个包含一系列轮次的赛程,每轮比赛将所有参赛者分成三对(或者可能是六人组)。然后,您的目标是最大化计划中出现的三对三对一组/六对组的数量。事实上,如果你的目标略有不同,这里的方法仍然有效,只要你能从糟糕的时间表中得出好的时间表。

逐轮生成计划,跟踪到目前为止生成的三元组/六组的集合。对于每一轮,产生一些大量的随机分裂成三元组/六组,并挑选发现的随机分裂,其产生迄今为止未见的大多数三元组/六组。一旦为特定回合选择了最佳随机分组,记录它,更新到目前为止找到的三组/六组,然后继续进行下一轮。

由于此过程是随机的,因此请使用不同的随机种子重复整个过程,以查看是否获得了更好的答案,并继续操作直到计算机时间用完为止。

在其原始设置中,其中描述的算法提供了使所有对测试切实可行的结果。它们不如已知的最佳组合设计那样好,但它易于编程且非常灵活。