获得在JavaScript中的所有有效组合组合、有效、JavaScript

2023-09-11 02:45:50 作者:忘却,你的我爱你。

我觉得我的标题是不正确的这个问题,但因为英语不是我的母语,我不能一个更好的方法找出该题我的问题。

I think my title is not correct for this issue but since english is not my mother tongue i couldn't figure out a better way to title my problem.

所以我有不同的球员有几个特性:

So what i have is different Players with a few properties:

Player_one.name = "A";
Player_two.name = "B";
Player_three.name = "C";
Player_four.name = "D";

玩家也有属性:

Players also have property:

Player_one.canPlay = ["B","D"];
Player_two.canPlay = ["A","D"];
Player_three.canPlay = ["A","C"];
Player_four.canPlay = ["B","D"]
//note that this is example and may not be accurate right now

属性canPlay显示了谁的球员可以玩。

Property canPlay shows with who player can play with.

现在球员也有物业称为placeInTable这说明他们目前的位置,例如位置的一个,两个或三个等。

Now players also have property called "placeInTable" which shows their current spot, for example position one, two or three etc.

我想实现的是检查是否有可能使从每个canPlay阵列组合,让每一个玩家能够在本轮与其他玩。万一有几种可能的选择,例如,如果播放器1可以用播放机2和3和游戏仍然可与每个人然后玩家与较高的placeInTable将被选择为对手被播放播放

What i would like to achieve is to check whether it is possible to make combinations from every canPlay array so that every player is able to play with another in the current round. In case there are several possible options, for example, if player one can play with player two and three and games still could be played with everyone then the player with higher "placeInTable" will be selected for an opponent.

要总结我的想法了是,我试图创建一个瑞士制表,适当管理下一场比赛。算法应检查每个canPlay每个球员创造的组合,这将导致一种方式,每个球员都能够与其他玩,如果可供多种选择的游戏会选择首先根据placeInTable最好的对手。

To sum my idea up is that i'm trying to create a swiss system table which manages the next games properly. Algorithm should check every canPlay for each player and create combinations which would result in a way that every player is able to play with another and if several options for games are available it will choose the best opponent first according to "placeInTable".

是我到目前为止,完成的是,我有一个算法,该算法将从头开始检查表中,如果玩家不能与其他的较低的一个玩会被选中。虽然我目前的算法是错误的,如果长度为1和长度2玩家都玩过彼此因为算法不知道该怎么办。因此,对于我将添加两个上的球员从中算法崩溃,目前长度为1和长度2让球员长度为3和长度-4将被添加和canPlay支票将跑。

What i've done so far is that i have an algorithm which will start checking the table from the beginning, if player can't play with another the lower one will be selected. Although my current algorithm is faulty since if the length-1 and length-2 players have played with each other the algorithm does not know what to do. So for that i'll add two upper players from which the algorithm crashes, currently length-1 and length-2 so the players length-3 and length-4 will be added and canPlay check will be ran.

我希望我的描述,这个问题是不是太误导,是可以理解的,真正的大荣誉的人谁能够提供帮助。

I hope my description for this problem was not too misleading and could be understood and really big kudos to someone who is able to help.

如果有任何问题,我会高兴地介绍更多关于这个问题的。

If any questions i'd be happy to describe more about this issue.

编辑没有。 1:

我忘了补充一点,在瑞士制两名球员不能与对方打一次,他们已经打了对方。这就是为什么我有canPlay并在第一轮canPlay数组长度可以在第五或第六个也可能是非常小的。

I forgot to add that in Swiss System two players can't play with each other once they've already played with each other. That's why i have canPlay and in first round the canPlay array length may be longer and in fifth or sixth it may be really small.

关于答案,建议,如果能与B和B可以玩用C打那么A可以用C打则没有,这是不正确的想法。更好地理解可以用一个例子来进行。

About answer which suggested that if A can play with B and B can play with C then A can play with C then no, it's not correct idea. Better understanding could be made with an example.

比方说,有可能的组合,如:

Let's say there are possible combinations like:

A vs B
C vs D
//and
A vs D
B vs C

现在以这种方式每一位玩家都能与所有其他播放器上播放,但有两个选择。现在,如果表去该玩家A有现货1,游戏者B点2,队员C即期3和玩家D点4那么就应该选择第一个选项,因为球员在表中较高的地方应该放在一起。

Now in such manner every player can play with every other player but there's two options. Now if the table goes that player A has spot 1, player B spot 2, player C spot 3 and player D spot 4 then it should choose the first option because players in higher place in table should be placed together.

有可能是当然是第三个选项,玩家A对球员C和;&安培;玩家B对玩家D,但我离开了现在。如果将有第三个选择则仍然是第一个会被选中,因为它把高点在一起。

There could be of course a third option, player A vs player C && player B vs player D but i left it out right now. IF there would be third option then still the first one would be selected since it places the higher spots together.

编辑没有。 2:

function reastaArray(){
var newArr = jQuery.extend(true,[],playerLst); //copy of original players
var original = jQuery.extend(true,[],playerLst);
var inPlay = []; //siia hakkame lisama
var firstRound = true;
var visitedCount = 1;
var i = 0;
var count = 0;
while (newArr.length != 0){
    //this goes on until there are players left in playerList
    count = i;
    hereiam = false;
    if (inPlay.length % 2 == 0){ //if the players in play are even amount then the first one gets pushed without a check
        inPlay.push(newArr[i]);
        newArr.splice(i,1);
    }
    else{ //now we need to search for opponent
        var lastEl = inPlay[inPlay.length-1];
        var element = newArr[i];
        var played = hasPlayed(element,lastEl); //true/false, can we play with last element in inPlay, if it's true then while cycle begins
        while (played == true){
            count += 1;
            if (count == newArr.length){ //if we've reached at the end of the newArr and still haven't found an opponent
                //take in last played games into new array
                takeLast(inPlay,newArr);
                for (var y = 0; y<visitedCount;y++){
                    takeLast(inPlay,newArr);
                    takeLast(inPlay,newArr);
                }
                canWePlayNow(newArr);
                //populize canPlay-s.

                //IDEA FROM STACK

                var combinations = findCombinations(newArr);
                console.log("possible combinations");
                combinations.forEach(function(comb) {
                console.log(comb);
                });
                console.log(findBest(combinations,newArr));
                visitedCount += 1;


            }
            else{
                element = newArr[count];
                played = hasPlayed(element,lastEl);
            }
        }
        if (hereiam == false){
        inPlay.push(element);
        newArr.splice(count,1);
        }


    }
}
return inPlay;
}

function canWePlayNow(newArr){
for (var i = 0; i<newArr.length;i++){
    var player = newArr[i];
    player.canPlay = [];
    var hasPlayed = player.playedNames;
    for (var j = i+1; j<newArr.length;j++){
        playerFromPlayed = newArr[j];
        var inArr = isInArray(hasPlayed,playerFromPlayed.name);
        if (inArr == false){
            player.canPlay.push(playerFromPlayed.name);
        }
    }
}
}

组合阵列可以更好地工作,现在我测试它:

The combination array could work better, right now as i tested it does:

由于从图所示,第一轮的计算方法太好了,现在第二轮的输入值,第三次的运算打乱了:它可以放在一起5vs6; 1vs4和2vs3,但是你提供的这个算法是pretty的已近,你能不能给一个进一步研究,以检查出了什么问题?

As seen from image, first round is calculated great, now second round values are entered and third round calculation messes up: It could put together 5vs6 ; 1vs4 and 2vs3, but this algorithm you provided is pretty close already, could you give a further look to check out what's wrong?

编辑NO 3:

通过进一步检查它看起来像它仍然做得不对。如从下面的正确的结果图像看到应1和; 2和5比3,虽然图所示游戏1vs5和放大器; 3vs2,这不应该是结果

With further inspection it seems like it's still doing something wrong. As seen from image below the correct result should be 1 & 2 and 5 vs 3 although next games shown are 1vs5 & 3vs2, which shouldn't be result.

输入为阵是谁已经就已经一轮免费的或表V玩家。您发布的算法是不变的。

The input for the array were Players who've had already one round of free or as in table "V". The algorithm you posted is unchanged.

由于从控制台看到的,我上面指出的另一种选择是组合,但它没有选择。任何想法?

As seen from console, the other option which i pointed out above is in combinations but it's not selected. Any ideas?

编辑没有4:

增加了新的形象!

function findBest(combinations, players) {
  if(combinations.length === 0) throw new Error();
  var koht = {};
  function score(comb) {
    return comb.reduce(function(score, pair) {
      //console.log("New calc:");
      //console.log(score+koht[pair[0]]*koht[pair[1]]);
      return score + koht[pair[0]] * koht[pair[1]];
    }, 0);
  };
  players.forEach(function(p) {
    koht[p.name] = p.koht;
  });
  var best = combinations[0];
  combinations.slice(1).forEach(function(comb) {
    console.log(score(comb) + " = combs & best = "+score(best));
    console.log("Checked combs: ");
    console.log(comb);
    if(score(comb) > score(best)) {
        best = comb;
    }
  });
  console.log("Returned array: (best)");
  console.log(best);
  return best;
}

新增登录到KOHT

推荐答案

下面是一些code显示,其中每个球员得到发挥所有可能的组合。然后,它会尝试查找玩家在高点preferring配对最好的一个。

Here is some code that displays all possible combinations in which each player gets to play. It then tries to find the best one by preferring pairings of players in high spots.

function findCombinations(players) {
  var combinations = [];

  function removePlayer(a, name) {
    for(var i = 0; i < a.length; i++) {
      if(a[i].name === name) return a.slice(0, i).concat(a.slice(i+1));
    }
    return a;
  }

  function find(players, comb) {
    if(players.length === 0) {
      combinations.push(comb);
      return;
    };
    var player = players[0];
    player.canPlay.forEach(function(other) {
      var newPlayers = removePlayer(players, other);
      if(newPlayers !== players && other !== player.name) {
        find(newPlayers.slice(1), comb.concat([[player.name, other]]));
      }
    });
  }

  find(players, []);
  return combinations;
}

function findBest(combinations, players) {
  if(combinations.length === 0) throw new Error();
  var placeInTable = {};
  function score(comb) {
    return comb.reduce(function(score, pair) {
      return score + placeInTable[pair[0]] * placeInTable[pair[1]];
    }, 0);
  };
  players.forEach(function(p) {
    placeInTable[p.name] = p.placeInTable;
  });
  var best = combinations[0];
  combinations.slice(1).forEach(function(comb) {
    if(score(comb) > score(best)) best = comb;
  });
  return best;
}

var p1 = {name: "A", canPlay: ["B", "D", "C"], placeInTable: 1},
    p2 = {name: "B", canPlay: ["A", "D"], placeInTable: 2},
    p3 = {name: "C", canPlay: ["A", "C", "D"], placeInTable: 3},
    p4 = {name: "D", canPlay: ["B", "D", "C"], placeInTable: 4};

var players = [p1, p2, p3, p4],
    combinations = findCombinations(players);

console.log("possible combinations");
combinations.forEach(function(comb) {
  console.log(comb);
});

console.log("\nbest:");
console.log(findBest(combinations, players));