Algorithm 具有大量参与者的锦标赛的调度算法?

Algorithm 具有大量参与者的锦标赛的调度算法?,algorithm,combinatorics,Algorithm,Combinatorics,比如说,我们有100多名参与者和3个获奖名额。我需要安排尽可能少的比赛,以找到3名优胜者。其余的地方一点都不重要。 循环算法看起来不必要而且昂贵 以下是我的解决方案: const match = (a, b) => { if (!a || !b) { return {winner: a || b} } // simulate match const winner = Math.random() > 0.5 ? a : b console.log(`Matc

比如说,我们有100多名参与者和3个获奖名额。我需要安排尽可能少的比赛,以找到3名优胜者。其余的地方一点都不重要。 循环算法看起来不必要而且昂贵

以下是我的解决方案:

const match = (a, b) => {
  if (!a || !b) {
    return {winner: a || b}
  }
  // simulate match
  const winner = Math.random() > 0.5 ? a : b
  console.log(`Match between ${a} and ${b}: ${winner} wins`)
  return {winner, looser: winner === a ? b : a}
}
let participants = {
  // [id]: {win: Number, loose: Number}
}
let participantsNumber = 100
let n = 0

// create random participants
while(n < participantsNumber) {
  n++
  participants[String(n)] = {win: 0, loose: 0}
}

let round = 0
while(participantsNumber > 3) {
  let odd = true
  let matches = []
  _.map(participants, (winLooseStats, id) => {
    if (odd) {
      odd = false
      matches.push({player_1: id})
    } else {
      odd = true
      let opponentFound = false
      matches.map(match => {
        if (!match.player_2 && !opponentFound) {
          opponentFound = true
          match.player_2 = id
        }
      })
    }
  })
  console.log('matches', matches)
  // run matches
  matches.forEach(({player_1, player_2}) => {
    const {winner, looser} = match(player_1, player_2)
    participants[winner].win++
    if (looser) {
      participants[looser].loose++
    }
  })

  // remove those, who has lost 3 times
  _.map(participants, ({win, loose}, id) => {
    if (loose > 2) {
      console.log(`Player ${id} has lose 3 times`)
      delete participants[id]
      participantsNumber--
    }
  })
  round++
  console.log(`Round ${round} complete. ${participantsNumber} players left`)
}

console.log(`3 champions: ${_.map(participants, (wl, id) => id).join(', ')}`)
const match=(a,b)=>{
如果(!a | |!b){
返回{获胜者:a | | b}
}
//模拟比赛
const winner=Math.random()>0.5?a:b
log(`Match-between${a}和${b}:${winner}wins`)
返回{winner,looser:winner==a?b:a}
}
让参与者={
//[id]:{win:Number,loose:Number}
}
让参与者人数=100
设n=0
//创建随机参与者
while(n<参与者人数){
n++
参与者[String(n)]={win:0,loose:0}
}
让四舍五入=0
while(参与者人数>3){
设奇数=真
让匹配项=[]
_.map(参与者,(winLooseStats,id)=>{
if(奇数){
奇数=假
匹配。推送({player_1:id})
}否则{
奇数=真
让opponentFound=false
matches.map(匹配=>{
如果(!match.player_2&&!opponentFound){
opponentFound=true
match.player_2=id
}
})
}
})
log('matches',matches)
//比赛
matches.forEach({player_1,player_2})=>{
const{winner,looser}=比赛(玩家1,玩家2)
参与者[获胜者].获胜++
如果(较松){
参与者[松散的]。松散的++
}
})
//删除那些已经丢失3次的
_.map(参与者,({win,loose},id)=>{
如果(松动>2){
log(`Player${id}已丢失3次`)
删除参与者[id]
参与者人数--
}
})
圆的++
log(`Round${Round}完成。${participantsumber}玩家左`)
}
log(`3 champose:${{{.map(参与者,(wl,id)=>id.join(',')}`)


每100名参与者约12轮。可以减少轮次吗?

这个问题有点模糊,但我认为你们的规则如下:

  • 任何一对球员只打一场比赛。如果A击败B,我们假设A将永远击败B
  • 我们假设一个传递性质:如果a拍B和B拍C,我们可以假设a拍C,我们不需要安排匹配来找到它

假设这是正确的,并且你有
n名
玩家,那么你可以使用一个标准来最佳地解决这个问题,从而找到赢家和第二名。要想获得第三名,你必须在没有进入决赛的两个人之间再加一场比赛。

好吧,一场100多名参赛者战斗到死亡,直到只有3人活着的比赛将满足你的要求。对于任何类似于回答的问题,你都必须提供更多的细节。这是不公平的,因为有些“玩家”可能只会失去一次机会,而他们已经失去了机会queue@HighPerformanceMark我在描述中添加了可能的解决方案。它可能会澄清所有细节,“尽可能少的比赛”在某种程度上意味着输掉第一场比赛的球员将出局。我假设一场比赛的结果不是分数,而是输赢,但这并不会导致最少的比赛。您需要定义要满足的任何其他约束。这似乎不公平:如果“弗拉维亚·佩内塔”输掉了首场比赛,它将退出下一场比赛。然而,这并不意味着“弗拉维亚·佩内塔”不能打败多米尼卡·西布尔科娃(Dominika Cibulková)。但是,如果“弗拉维亚·佩内塔”会被咬三次,那么显然不可能获得前三名中的一个,对吗?