我需要制定一项体育赛事的时间表。
一共有30支队伍。每支球队必须打8场比赛。这意味着每支球队都不可能再次参加所有其他球队的比赛,但我需要避免这两支球队相互竞争不止一次。
我的想法是生成所有可能的匹配(30个队:(30*29)/2 = 435 matches),并从这个列表中选择120个匹配(每个队8次匹配:8 * 30 / 2 = 120 matches)。
这就是我遇到困难的地方:我如何选择这120场比赛?我尝试了一些简单的解决方案(比如列表的第一次匹配,然后是最后一次,等等),但它们似乎不适用于30个团队。我也试图生成所有可能的比赛组合,并找到哪一个是工作的,但与30支球队,这是太多的计算时间。
是否有我可以实现的现有算法?
更新
我需要的是一个简单的时间表,不排除。每队打8场比赛,仅此而已。一天到头来不会有一个赢家。
每支球队都有自己的赛程,这个时间表不会因为他们的输赢而改变。计划一整天都在进行,而且是一成不变的。
更新2
起初,我不想对我的问题施加太多的限制,但似乎没有任何约束(除了每支球队不超过一次比赛),这只是一个随机挑选8场比赛的问题。
下面是一些更多的细节:
在这项运动中,有6个不同的运动项目(足球,手球,篮球等)。这意味着有6场同时进行的比赛。新一轮比赛每15分钟开始一次。
每支球队必须打8场比赛,每项运动至少要打一次。
这6项运动正在三个不同的地方进行。这意味着,在白天,每个团队将不得不从一个地方搬到另一个地方。这些行动应尽可能减少。
一支球队不能连续打两场比赛。
发布于 2010-05-31 07:37:51
您可以研究一些已经知道的匹配方法:
例如瑞士象棋系统
编辑:
再看一遍你的要求--每支球队都应该和其他球队打一次,而胜利者不一定要被决定。似乎一个单一的圆罗宾系统可以做您想做的事情。你可以把任何额外的比赛都抛到你需要的8以上。
发布于 2010-05-31 07:39:13
这真的很简单,只需将team i与i-4、i-3、i-2、i-1、i+1、i+2、i+3、i+4联合起来。这可以使用下面的算法来完成。
import java.util.*;
public class Test {
public static void main(String[] args) {
int TEAMS = 30, MATCHES = 8;
int[] matchCount = new int[TEAMS]; // for a sanity check.
List<Match> matches = new ArrayList<Match>();
for (int team1 = 0; team1 < TEAMS; team1++)
for (int team2 = team1 + 1; team2 <= team1 + MATCHES/2; team2++) {
matches.add(new Match(team1, team2 % TEAMS));
// Just for a sanity check:
matchCount[team1]++;
matchCount[team2 % TEAMS]++;
}
System.out.println(matches);
// Sanity check:
System.out.println(matches.size());
System.out.println(Arrays.toString(matchCount));
}
static class Match {
int team1, team2;
public Match(int team1, int team2) {
this.team1 = team1;
this.team2 = team2;
}
public String toString() {
return team1 + " vs " + team2;
}
}
}输出:
[0 vs 1, 0 vs 2, 0 vs 3, 0 vs 4, 1 vs 2, 1 vs 3, 1 vs 4, 1 vs 5, 2 vs 3, 2 vs 4, 2 vs 5, 2 vs 6, 3 vs 4, 3 vs 5, 3 vs 6, 3 vs 7, 4 vs 5, 4 vs 6, 4 vs 7, 4 vs 8, 5 vs 6, 5 vs 7, 5 vs 8, 5 vs 9, 6 vs 7, 6 vs 8, 6 vs 9, 6 vs 10, 7 vs 8, 7 vs 9, 7 vs 10, 7 vs 11, 8 vs 9, 8 vs 10, 8 vs 11, 8 vs 12, 9 vs 10, 9 vs 11, 9 vs 12, 9 vs 13, 10 vs 11, 10 vs 12, 10 vs 13, 10 vs 14, 11 vs 12, 11 vs 13, 11 vs 14, 11 vs 15, 12 vs 13, 12 vs 14, 12 vs 15, 12 vs 16, 13 vs 14, 13 vs 15, 13 vs 16, 13 vs 17, 14 vs 15, 14 vs 16, 14 vs 17, 14 vs 18, 15 vs 16, 15 vs 17, 15 vs 18, 15 vs 19, 16 vs 17, 16 vs 18, 16 vs 19, 16 vs 20, 17 vs 18, 17 vs 19, 17 vs 20, 17 vs 21, 18 vs 19, 18 vs 20, 18 vs 21, 18 vs 22, 19 vs 20, 19 vs 21, 19 vs 22, 19 vs 23, 20 vs 21, 20 vs 22, 20 vs 23, 20 vs 24, 21 vs 22, 21 vs 23, 21 vs 24, 21 vs 25, 22 vs 23, 22 vs 24, 22 vs 25, 22 vs 26, 23 vs 24, 23 vs 25, 23 vs 26, 23 vs 27, 24 vs 25, 24 vs 26, 24 vs 27, 24 vs 28, 25 vs 26, 25 vs 27, 25 vs 28, 25 vs 29, 26 vs 27, 26 vs 28, 26 vs 29, 26 vs 0, 27 vs 28, 27 vs 29, 27 vs 0, 27 vs 1, 28 vs 29, 28 vs 0, 28 vs 1, 28 vs 2, 29 vs 0, 29 vs 1, 29 vs 2, 29 vs 3]
120
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]如果您想要一个更随机的设置,您可以简单地为每个团队分配一个介于1到30之间的随机数。
更新以处理您所增加的约束:让match I成为运动i mod 6。
发布于 2010-05-31 07:20:22
你确定你不能得到32支队伍:-)?
这将使事情变得更简单--有一个标准的锦标赛结构,但每场比赛的输家都会出现在他们自己的图表中。我认为这会使在比赛中至少赢得一场比赛的球队数量最大化。
有30支球队,你可以让两支球队在第一轮中打一场“友谊赛”和一场友谊赛。但这个组织变得更加复杂。
https://stackoverflow.com/questions/2941911
复制相似问题