Algorithm 循环赛的调度算法?
我最近做了一些研究工作,并会见了唐纳德·克努斯。但是我没有找到解决问题的正确算法 问题我们的联赛有n名球员。每个星期他们都有一场比赛。在n-1周内,每支球队都相互对抗。每天有n/2场比赛。但是一个队一周只能打一次。如果我们生成一个(n/k)组合,我们得到所有的组合。。。(假设k=2)但我需要把它们按正确的顺序排列 我的第一个建议是。。。不是最好的。我只是做了一个数组,然后让计算机试试,如果他找到了正确的方法。如果没有,回到开始,洗牌数组,然后再做一次,好吧,我用PHP(n=8)编程,结果是可行的,但需要很多时间,对于n=16,它也会给我一个超时 所以我想如果我们能找到一个算法,或者任何人都知道一本关于这个问题的书 这是我的代码:Algorithm 循环赛的调度算法?,algorithm,combinatorics,Algorithm,Combinatorics,我最近做了一些研究工作,并会见了唐纳德·克努斯。但是我没有找到解决问题的正确算法 问题我们的联赛有n名球员。每个星期他们都有一场比赛。在n-1周内,每支球队都相互对抗。每天有n/2场比赛。但是一个队一周只能打一次。如果我们生成一个(n/k)组合,我们得到所有的组合。。。(假设k=2)但我需要把它们按正确的顺序排列 我的第一个建议是。。。不是最好的。我只是做了一个数组,然后让计算机试试,如果他找到了正确的方法。如果没有,回到开始,洗牌数组,然后再做一次,好吧,我用PHP(n=8)编程,结果是可行的
经典算法的工作原理如下: 给队伍编号1..n。(这里取n=8。) 把所有的小组写成两行
1 2 3 4
8 7 6 5
各栏显示了该轮比赛的球队(1对8,2对7,…)
现在,保持1固定,但轮换所有其他团队。在第二周,你会得到
1 8 2 3
7 6 5 4
在第三周,你会得到
1 7 8 2
6 5 4 3
这会持续到第n-1周,在这种情况下
1 3 4 5
2 8 7 6
如果n是奇数,则执行相同的操作,但添加一个虚拟团队。任何与虚拟团队匹配的人都将在该周获得一个分数。以下是JavaScript中的代码
function makeRoundRobinPairings(players) {
if (players.length % 2 == 1) {
players.push(null);
}
const playerCount = players.length;
const rounds = playerCount - 1;
const half = playerCount / 2;
const tournamentPairings = [];
const playerIndexes = players.map((_, i) => i).slice(1);
for (let round = 0; round < rounds; round++) {
const roundPairings = [];
const newPlayerIndexes = [0].concat(playerIndexes);
const firstHalf = newPlayerIndexes.slice(0, half);
const secondHalf = newPlayerIndexes.slice(half, playerCount).reverse();
for (let i = 0; i < firstHalf.length; i++) {
roundPairings.push({
white: players[firstHalf[i]],
black: players[secondHalf[i]],
});
}
// rotating the array
playerIndexes.push(playerIndexes.shift());
tournamentPairings.push(roundPairings);
}
return tournamentPairings;
}
函数makeRoundRobinPairings(玩家){
如果(players.length%2==1){
玩家。推(空);
}
const playerCount=players.length;
常量轮数=玩家计数-1;
const half=播放计数/2;
const tournamentPairings=[];
constplayerIndex=players.map((uu,i)=>i.slice(1);
for(让round=0;round
更新:
修复了评论中报告的一个bug我为此提出了一个更新的解决方案,其中包含可重用的函数(灵感来自:
const testData=[
“红色”,
“橙色”,
“黄色”,
“绿色”,
“蓝色”,
“靛蓝”,
“紫罗兰”,
];
常量匹配参与者=(参与者)=>{
const p=数组from(参与者);
如果(p%2==1){
p、 推送(空);
}
常数对=[];
while(p.length!=0){
参与者a=p.shift();
参与者b=p.pop();
if(participantA!=未定义&&participantB!=未定义){
配对。推送([参与者A,参与者B]);
}
}
返回对;
};
常量rotatarray=(数组)=>{
常数p=数组。从(数组);
常量firstElement=p.shift();
常量lastElement=p.pop();
返回[firstElement,lastElement,…p];
};
const generateTournance=(参与者)=>{
const tournamentRounds=[];
const rounds=Math.ceil(participants.length/2);
设p=Array.from(参与者);
for(设i=0;i log(generateTournament(testData))代码>我只是在这里添加了这个评论,因为这个主题似乎是转发一些好奇的家伙的合适地方。看到@varun代码中的bug。使用:['a'、'b'、'c'、'd'][第一轮]0:{p1:“a”,p2:“c”}1:{p1:“a”,p2:“b”}[第二轮]0:{p1:“a”,p2:“c”}[第三轮]0:{p1:“a”,p2:“a”}1:{p1:“c”,p2:“d”}关于@varun代码中的错误,这修复了它:更改为“let playernes=playeriens=playeriens.slice(1).map(,i=”到“=”playerieriens=p.map(=”);playerIndex.shift();”