Javascript 添加和删除人员的循环算法

Javascript 添加和删除人员的循环算法,javascript,algorithm,Javascript,Algorithm,好的,在这个代码笔中,我已经找到了一个循环锦标赛调度算法: var玩家=[ { playerName:'人1', }, { playerName:'人2', }, { playerName:'人3', }, { playerName:'人4', }, { playerName:'人5', }, { playerName:'人6', }, { playerName:'人7', }, { playerName:'人8', }, { playerName:'人9', }, { playerName:'

好的,在这个代码笔中,我已经找到了一个循环锦标赛调度算法:

var玩家=[
{
playerName:'人1',
},
{
playerName:'人2',
},
{
playerName:'人3',
},
{
playerName:'人4',
},
{
playerName:'人5',
},
{
playerName:'人6',
},
{
playerName:'人7',
},
{
playerName:'人8',
},
{
playerName:'人9',
},
{
playerName:'人10',
},
{
playerName:'人11',
},
{
playerName:'人12',
},
{
playerName:'人13',
},
{
playerName:'人14',
},
{
playerName:'人15',
},
{
playerName:'人16',
},
];
var numberOfRounds=players.length-1;
函数生成器unds(){
对于(i=0;i
我用它来快速约会,即使你可以和每个人约会

我的问题是: 在每一轮之后,新的人可以参加活动或离开活动(如果他们感到无聊;)

注意:迟到者不需要和每个人约会,因为他们已经错过了x轮
注2:如果有很多人离开,最好限制轮次的数量,这样人们就不需要在约会之间等待那么长的时间了

对于两部分匹配问题,如男女分开的快速约会,可以使用最大流算法

在4层中构建图形:

  • 源节点
  • 每个人一个节点
  • 每个女人一个节点
  • 汇节点T
    • 用边缘容量1完全连接第1层到第2层
    • 用边缘容量1完全连接第2层至第3层
    • 用边缘容量1完全连接第3层至第4层
    添加人员后,将其作为第2层或第3层中的新节点添加,并如上所述完全连接到相邻层

    移除人员后,移除第2层和第3层中的节点以及节点上的所有边

    在每一轮中,使用最大流算法来识别配对。圆后,将配对中涉及的第2层->第3层边的容量设置为0。这将防止相同的两个人在随后的回合中再次配对


    启发性:您可以修改最大流量算法,将日期最少或轮次最多的人排在第一位,这样,若存在奇数人,则最新的人和同一个人都不会排在第一位

    扩展:通过过滤在第2层和第3层之间添加的边集,可以实现首选项来限制潜在匹配集

    时间:绝对糟糕。可能介于O(n^3)和O(n^6)之间,具体取决于max flow实现的好坏,但谁在乎16个人呢

    github上的一些javascript max flow软件包,从未尝试过。祝你好运:


    对于任何人对任何人匹配问题,必须用更复杂的Blossom算法替换最大流算法

    与max-flow一样,该算法通过查找增广路径,然后修改其当前匹配集来迭代地细化匹配

    此算法的输入为:

    • 为每个人添加一个节点
    • 完全连接所有节点
    就像在二分体情况下一样,在每轮结束时,删除与前几轮匹配对应的所有边,以防止相同的两个人被匹配

    当一个新人加入时,添加一个节点并将其与其他人完全连接

    当人员离开时,删除其节点和所有连接的边

    这里更好地描述了Blossom算法

    快速搜索会显示此算法的几个javascript实现,您的里程可能会有所不同


    对于n个人,每个人都需要n-1轮才能与其他人约会。所以16个人,需要15轮。假设一个新人在第15轮后立即加入。然后每个人都需要和新的人约会,新的人也需要和每个人约会,但是已经没有轮次了(有吗?)。无论是谁和新人约会,都会有14个人无所事事或重复约会。你想在这个场景中发生什么?啊,是的,这就是我试图解释的,但失败了;-)如果有新人加入,则只添加一轮。这将是一个晚梳理者,所以如果在第1轮、第2轮或第3轮之后,可能更符合逻辑。在你的特殊情况下。约会已经结束了,所以他太迟了。但是如果他早一轮的话,新的一轮应该被加入,他有两次约会。哦,哇,听起来很复杂(我已经因为提到源节点而失去了你)。也许我应该忘记它,保持它的简单…哈哈哈:是的,这有点过分了!怎么样:把8张桌子排成一行,两边各放一把椅子,分成男女两组,每一轮男子向左移动一张(用环绕式)。要有人加入,他们必须加入一个空座位。如果两个人一起离开,跳过他们的桌子。如果有人离开,希望有人加入:DHi@dhakim,非常好的回应,谢谢。你认为我们可以利用它来实现这一目标吗?如果是,你能给出一个使用示例吗?在每一轮比赛后,我都在努力抽签。@David'G'Ford Fulkerson应该可以。不过我从来没用过这个包裹。库应该能够输出指定了最大流量的图形。然后,您只需检查它指定了流的边,那些在人与人之间交叉并指定了流的边就是它选择的配对。在下一轮之前,您将这些配对从起始图中删除,以防止它们在以后的回合中再次匹配。@DavidG
    var players = [
      {
        playerName: 'Person 1',
      },
      {
        playerName: 'Person 2',
      },
      {
        playerName: 'Person 3',
      },
      {
        playerName: 'Person 4',
      },
      {
        playerName: 'Person 5',
      },
      {
        playerName: 'Person 6',
      },
      {
        playerName: 'Person 7',
      },
      {
        playerName: 'Person 8',
      },
      {
        playerName: 'Person 9',
      },
      {
        playerName: 'Person 10',
      },
      {
        playerName: 'Person 11',
      },
      {
        playerName: 'Person 12',
      },
      {
        playerName: 'Person 13',
      },
      {
        playerName: 'Person 14',
      },
      {
        playerName: 'Person 15',
      },
      {
        playerName: 'Person 16',
      },
    ];
    
    var numberOfRounds = players.length - 1;
    
    function generateRounds() {
      for(i = 0; i < numberOfRounds; i++) {
        document.write('<h1 class="round">'+'Round ' + (i+1) + '</h1>');
        
        for (var j = 0; j < players.length / 2; j++) { 
          document.write('<div class="match">' + players[j].playerName + " - " + players[players.length - 1 - j].playerName +'</div>');
        }
    
        players.splice(1, 0, players[15]);
        players.pop();
      }
    }
    
    generateRounds();