循环匹配定位算法

时间:2015-04-10 08:00:50

标签: javascript algorithm

我试图找出一种为循环赛锦标赛设置匹配位置的算法。

  • 每支球队互相比赛两次,一次在主场,一次在外。
  • 每个团队都有一个家庭位置。
  • 锦标赛中有很多球队共享同一个位置。

我已经拥有了所有比赛的数组。匹配看起来像:

{
  date: "Thu Jan 08 2015 12:00:00",
  home: "Bob",
  away: "Frank",
  location: null
}

我想遍历所有匹配并分配location。我尝试了各种解决方案,但没有任何工作完美。

  • 当然,如果Bob的家庭位置在date上可用,我们就可以使用它。
  • 我们必须考虑鲍勃和弗兰克所扮演的另一场比赛。切换主场/客场球队没关系,但我们必须确保它是平衡的。 (即鲍勃和弗兰克各自在家玩一次)
  • 如果即使在尝试切换回家/离开后也无法分配位置,我们必须尝试位置拆分

位置拆分

可以拆分匹配位置,以便在一个位置同时播放多个匹配。我们如何确定某个位置是否可以拆分超出了这个问题的范围,但我们只是说我们有一个名为canLocationBeSplit(location)的函数,它返回bool的真或假。

两队之间任意一场比赛的主场或客场都可以分开。但是,除非绝对必要,否则我们只想开始拆分位置。同样,每支球队必须一次在主场比赛。

如果匹配仍然没有可用的位置,我们只需将其保留为null

问题

所以我的问题是,是否有人建议使用合适的递归算法来解决这个问题?谢谢你的时间。

1 个答案:

答案 0 :(得分:1)

这不是一个小问题。由于不确定是否存在任何解决方案,因此很难证明您可能发现的任何解决方案在不使用暴力方法的情况下都是最优的,并将其与每个结果进行比较。

没有解决方案的星座的一个例子是4个团队,它们共享一个无法拆分的家庭位置。所需的解决方案是为某些匹配分配NULL值,“最优”解决方案将尽可能少的NULL值(因此找到一个最优解决方案是一个优化问题,甚至可能是NP难的?!)。

所以我会根据您拥有的团队数量提出两点建议:

  • 使用强力计算并计算所有可能的位置组合。话虽这么说,让我们估计这意味着什么。假设你有20支球队。在最坏的情况下,10场比赛全部在同一天播放(例如每个星期六)。因此,对于每周(38个不同的日期),您需要从20个中选择10个位置并计算这些位置的每个排列。这为您提供了38*binom(20,10)*10! = 25.476.817.766.400个需要验证的不同组合(检查是否满足您的上述要求),然后进行比较以找到最佳分布。如果你只有10个团队,这个数字只会下降到241.920个可能的组合,这实际上相当小!

  • 为第一个日期创建合理的位置分布并迭代日期,尽可能地指定位置,而不更改先前设置的位置。这很可能不会给你一个最佳结果,并且可能会留下一些没有位置的匹配,但是你会在很短的时间内获得至少一个建议的位置分布。

为了获得我在第二种方法中所说的“合理”分布,我建议确定每个位置和每个日期在这个位置可能有多少不同的比赛。然后首先分配具有最少匹配的位置,然后重复,直到没有匹配为止。

示例:

Team A - Home Location: 1
Team B - Home Location: 1
Team C - Home Location: 1
Team D - Home Location: 2
Team E - Home Location: 3
Team F - Home Location: 4

在某个特定日期匹配:

Match 1: Team A vs Team D
Match 2: Team B vs Team E
Match 3: Team C vs Team F

如果A队在位置2之前打过D队,我们会得到:

Location 1 could host 3 matches (all matches)
Location 2 could host no matches
Location 3 could host 1 match (Match 2)
Location 4 could host 1 match (Match 3)

因此,我们会将Location 3分配给Match 2,将Location 4分配给Match 3,只留下Location 1分配给Match 1

就像我说的,这不是一个最佳的解决方案,可能会产生一些没有指定位置的匹配,但我希望这会产生足够好的结果。