2017-05-12 9 views
0

Ich nehme ein 2d-Array, das etwa wie [[player1, 10], [player2, 8]] aussieht, aber mit etwa 12 Spielern. Ich bin zufrieden genug mit der Sortierung, die ich gehört habe, außer dass TeamA immer die "erste Wahl" des besseren Spielers erhält. Ich habe Mühe, einen Weg zu finden, TeamB den besseren Spieler jedes Mal zu geben. Unten ist der Code, der "gut genug" funktioniert.Teilen Array von Zahlen in 2 ausgeglichenen Arrays

data = [["player1", 10]. ["player2", 8], ["player3", 7], ["player4", 9]]; 
var teamA = []; 
var teamB = []; 

var remaining = []; 

for (item in data) { 
    remaining.push(data[item].slice()); 
} 

for (i in data) { 
    var max = 0; 
    var selection = [,]; 
    var index = -1; 

    for (k in remaining) { 
    if (remaining[k][1] > max) { 
     selection = remaining[k]; 
     max = remaining[k][1]; 
     index = k; 
    } 
    } 
    remaining.splice(index, 1); 

    if (i % 2 == 0) { 
    teamA.push(selection); 
    } else { 
    teamB.push(selection); 
    } 
} 

Dies führt zu teamA: [["player1, 10],["player2", 8]] und teamB: [["player4", 9],["player3", 7]] Was würde ich es vorziehen player2 und Spieler3 wechseln Teams. Folgendes habe ich versucht.

In meinem Gehirn sollte dies gut funktioniert haben, aber wow tat es nicht! Ich landete mit 9 Spielern auf TeamB und 3 auf TeamA. Ich habe mit verschiedenen Varianten dieses Ansatzes ohne Glück getüftelt.

Irgendwelche Zeiger?

EDIT: Zur Verdeutlichung kann angenommen werden, dass der Datensatz unsortiert kommen wird und dass die Länge des Datensatzes immer gerade ist. Es wird keine Mannschaft mit mehr Spielern als die andere geben.

+0

Haben Ihre Spielerdaten in sortierter Reihenfolge ankommen? (sortiert nach Spielerpunkten) – thenormalsquid

+0

Sollten die Teams _exaktly_ sein, auch in Bezug auf die Anzahl der Spieler oder ist es in Ordnung für Team A, 3 Spieler und Team B 4 zu haben? – thenormalsquid

+0

@ Thien-BachHuynh Siehe bearbeiten für die Antwort. – jtsmith1287

Antwort

0

Ich habe Ihren Code so bearbeitet, dass er zuerst für TeamA wählt, dann wählt er 2 für TeamB, dann 2 für TeamA und so weiter.

var data = [ 
    ["player1", 10], 
    ["player2", 8], 
    ["player3", 7], 
    ["player4", 9], 
    ["player5", 5], 
    ["player6", 6] 
]; 
var teamA = []; 
var teamB = []; 

var remaining = []; 

for (item in data) { 
    remaining.push(data[item].slice()); 
} 

var turnA = false; 
var counterA = 0, 
    counterB = 0; 
for (i in data) { 
    var max = 0; 
    var selection = [, ]; 
    var index = -1; 

    for (k in remaining) { 
     if (remaining[k][1] > max) { 
      selection = remaining[k]; 
      max = remaining[k][1]; 
      index = k; 
     } 
    } 
    remaining.splice(index, 1); 

    // add first player to teamA and continue 
    if (i == 0) { 
     teamA.push(selection); 
     continue; 
    } 

    if (turnA) { 
     teamA.push(selection); 
     counterA++; 
    } else { 
     teamB.push(selection); 
     counterB++; 
    } 

    if (turnA && counterA == 2) { 
     counterA = 0; 
     turnA = false; 
    } else if (!turnA && counterB == 2) { 
     counterB = 0; 
     turnA = true; 
    } 
} 
0

Also, die Strategie, die Sie nehmen wollen, ist die Partition Problem, wie hier beschrieben: https://en.wikipedia.org/wiki/Partition_problem

Sie im Grunde die Summe der beiden Teams nehmen will, basierend auf ihren Spielern Partituren, vergleichen die Summe, und weisen Sie den aktuellen Spieler der Mannschaft mit der niedrigeren Punktzahl zu.

Zuerst sortieren wir die Playerdaten.

Beim ersten Durchgang wählen wir nach dem Zufallsprinzip ein Team aus, um den besten Spieler zuzuweisen. Wenn wir den Rest des Player-Pools durchlaufen, folgen wir dem Algorithmus, der im Partitionsproblem beschrieben wurde.

Ich schrieb etwas aus sehr schnell als ein Beispiel für das Partitionsproblem in Aktion: https://codepen.io/thenormalsquid/pen/Lymjbb?editors=0001

// stack overflow answer 


var data = [["player1", 10], ["player2", 8], ["player3", 7], ["player4", 9]]; 
var teamA = []; 
var teamB = []; 
var selectionProbability = 0.5; 

var remaining = []; 

data.sort(function(playerA, playerB){ 
    if(playerA[1] < playerB[1]) { 
    return 1; 
    } 

    if(playerA[1] > playerB[1]) { 
    return -1; 
    } 

    return 0; 
}); 

var sum = function(team) { 
    if (team.length === 0) { 
    return 0; 
    } 
    var i, 
     s = 0; 
    for(i = 0; i < team.length; i++) { 
    s += team[i][1]; 
    } 
    return s; 
}; 

var chooseTeam = function() { 
    if(Math.random() < selectionProbability) { 
    return 'teamA'; 
    } 
    return 'teamB'; 
}; 


function assignTeams() { 
    var i; 
    for(i = 0; i < data.length; i++) { 
    var sumA = sum(teamA), 
     sumB = sum(teamB); 
    // first pass, we'll have a 50/50 chance 
    // of placing the best player in either team A or team B 

    if (i === 0) { 
     var chosenTeam = chooseTeam(); 
     if (chosenTeam === 'teamA') { 
     teamA.push(data[i]); 
     } else { 
     teamB.push(data[i]); 
     } 
    } else if (sumA < sumB) { 
     teamA.push(data[i]); 
    } else { 
     teamB.push(data[i]); 
    } 
    } 
} 

function addPlayerToHtml(player, teamId) { 
    var li = document.createElement('li'), 
     text = document.createTextNode(player[0] + ' ' + player[1]); 
    li.appendChild(text); 
    document.getElementById(teamId).appendChild(li); 
} 

var button = document.getElementById('assignPlayers'); 
button.addEventListener('click', function(){ 
    assignTeams(); 

    teamA.forEach(function(player){ 
    addPlayerToHtml(player, 'teamA'); 
    }); 

    teamB.forEach(function(player){ 
    addPlayerToHtml(player, 'teamB'); 
    }); 

}); 
Verwandte Themen