Javascript 基于skillindex从10人列表中组成两个团队的算法

Javascript 基于skillindex从10人列表中组成两个团队的算法,javascript,algorithm,sorting,math,Javascript,Algorithm,Sorting,Math,我正试图想出一个算法,检查球员名单中所有可能的组合,让两支5人的球队在总的skillIndex上有尽可能接近的差异。到目前为止,我提出了以下令人筋疲力尽的排列方式: 我想知道是否有更好的方法得出一个结果,根据skillIndex建议5个最佳团队组合。你们知道什么是解决这个问题的有效方法吗 我的最终目标是拥有两支球队,其中一名球员只能在一支球队中。两支球队的技能指数尽可能接近对方 我现在的方法是找到所有可能的阵列组合,将这个阵列一分为二,这样我就有了两个团队。然后计算两个数组的skillindex

我正试图想出一个算法,检查球员名单中所有可能的组合,让两支5人的球队在总的
skillIndex
上有尽可能接近的差异。到目前为止,我提出了以下令人筋疲力尽的排列方式:

我想知道是否有更好的方法得出一个结果,根据
skillIndex
建议5个最佳团队组合。你们知道什么是解决这个问题的有效方法吗

我的最终目标是拥有两支球队,其中一名球员只能在一支球队中。两支球队的技能指数尽可能接近对方

我现在的方法是找到所有可能的阵列组合,将这个阵列一分为二,这样我就有了两个团队。然后计算两个数组的skillindex并比较它们之间的差异。如果差别是{ const presentPlayers=[ {name:'a',skillIndex:100}, {name:'b',skillIndex:100}, {name:'c',skillIndex:90}, {name:'d',skillIndex:25}, {name:'e',skillIndex:60}, {name:'f',skillIndex:80}, {name:'g',skillIndex:70}, {name:'h',skillIndex:60}, {name:'i',skillIndex:50}, {name:'j',skillIndex:50}, ]; 常量getDifference=(a,b)=>{ 返回Math.abs(a-b); }; 函数置换(数组){ 函数p(数组,临时){ 让我; 设x; 如果(!array.length){ 让team1Index=0; 让team2Index=0; 常数一半=温度长度/2; 常数组1=温度拼接(0,一半); 常数组2=温度拼接(-一半); 团队1.forEach((玩家)=>{ team1Index+=parseFloat(player.skillIndex,10); }); 团队2.forEach((玩家)=>{ team2Index+=parseFloat(player.skillIndex,10); }); 常量差异=获取差异(团队1指数,团队2指数); 如果(差值==5){ log({team1,team2}); 调试器; } 结果:推送(温度); } 对于(i=0;i 所以现在我主要根据你们的建议提出了这个解决方案。我运行此代码252次:

            for (let i = 0; i < presentPlayers.length; i++) {
                const player = presentPlayers[i];
                players.push(player);
            }
            for (let i = players.length - 1; i > 0; i--) {
                const j = Math.floor(Math.random() * i);
                const temp = players[i];
                players[i] = players[j];
                players[j] = temp;
            }
            let team1Index = 0;
            let team2Index = 0;
            const half = players.length / 2;
            const team1 = players.splice(0, half);
            const team2 = players.splice(-half);
            team1.forEach((player) => {
                team1Index += parseFloat(player.skillIndex, 10);
            });
            team2.forEach((player) => {
                team2Index += parseFloat(player.skillIndex, 10);
            });
            const difference = getDifference(team1Index, team2Index);
            const sortedTeam1 = team1.sort((a, b) => {
                return b.skillIndex - a.skillIndex;
            });
            const sortedTeam2 = team2.sort((a, b) => {
                return b.skillIndex - a.skillIndex;
            });
            if (difference < 10) {
                proposedTeams.push({
                    sortedTeam1,
                    sortedTeam2,
                    difference,
                    team1Index,
                    team2Index,
                    goalSkill,
                });
            }
for(设i=0;i0;i--){
常数j=数学地板(数学随机()*i);
const temp=玩家[i];
玩家[i]=玩家[j];
玩家[j]=临时工;
}
让team1Index=0;
让team2Index=0;
const half=players.length/2;
const team1=玩家。拼接(0,一半);
const team2=玩家。拼接(-half);
团队1.forEach((玩家)=>{
team1Index+=parseFloat(player.skillIndex,10);
});
团队2.forEach((玩家)=>{
team2Index+=parseFloat(player.skillIndex,10);
});
常量差异=获取差异(团队1指数,团队2指数);
const sortedTeam1=team1.sort((a,b)=>{
返回b.skillIndex-a.skillIndex;
});
const sortedTeam2=team2.sort((a,b)=>{
返回b.skillIndex-a.skillIndex;
});
如果(差值<10){
提议的团队({
分类团队1,
分类团队2,
区别,,
团队1索引,
团队2索引,
射门得分,
});
}

首先,对于您的示例,只有252(10选择5)个可能的结果。因此,尝试所有这些(暴力)是很容易做到的


在更一般的情况下,您可以运行递归方法,在每个级别上为团队分配一个人,并检查可以为分配下一个人做什么。将获得的最佳(最接近的)sumOfAllSkillIndex/2值以及谁加入了哪个团队保存在全局变量中。

这可能不是绝对最平衡的,但每次都非常接近,而且非常快

const presentPlayers=[
{name:'a',skillIndex:100},
{name:'b',skillIndex:100},
{name:'c',skillIndex:90},
{name:'d',skillIndex:25},
{name:'e',skillIndex:60},
{name:'f',skillIndex:80},
{name:'g',skillIndex:70},
{name:'h',skillIndex:60},
{姓名:'i',skillIndex:45},
{name:'j',skillIndex:50},
{name:'k',skillIndex:100},
{name:'l',skillIndex:60},
{name:'m',skillIndex:75},
{name:'n',skillIndex:35},
];
功能分配(玩家){
const sorted=players.sort((a,b)=>b.skillIndex-a.skillIndex);
//拥有前两名技能最高的玩家
让team_a=[sorted.shift()];
让team_b=[sorted.shift()];
//开始跟踪每个团队的总技能
让得分=团队得分[0].skillIndex;
let score_b=团队_b[0]。skillIndex;
//一次检查两个
//假设数组总是可以被二整除
while(sorted.length>0){
设a=sorted.shift()
设b=sorted.shift()
让高,让低;
//找出哪个更高/更低
如果(a.skillIndex>=b.skillInd
            for (let i = 0; i < presentPlayers.length; i++) {
                const player = presentPlayers[i];
                players.push(player);
            }
            for (let i = players.length - 1; i > 0; i--) {
                const j = Math.floor(Math.random() * i);
                const temp = players[i];
                players[i] = players[j];
                players[j] = temp;
            }
            let team1Index = 0;
            let team2Index = 0;
            const half = players.length / 2;
            const team1 = players.splice(0, half);
            const team2 = players.splice(-half);
            team1.forEach((player) => {
                team1Index += parseFloat(player.skillIndex, 10);
            });
            team2.forEach((player) => {
                team2Index += parseFloat(player.skillIndex, 10);
            });
            const difference = getDifference(team1Index, team2Index);
            const sortedTeam1 = team1.sort((a, b) => {
                return b.skillIndex - a.skillIndex;
            });
            const sortedTeam2 = team2.sort((a, b) => {
                return b.skillIndex - a.skillIndex;
            });
            if (difference < 10) {
                proposedTeams.push({
                    sortedTeam1,
                    sortedTeam2,
                    difference,
                    team1Index,
                    team2Index,
                    goalSkill,
                });
            }
[
  { name: 'a', skillIndex: 100 },
  { name: 'c', skillIndex: 90 },
  { name: 'f', skillIndex: 80 },
  { name: 'g', skillIndex: 70 },
  { name: 'l', skillIndex: 60 },
  { name: 'i', skillIndex: 45 },
  { name: 'd', skillIndex: 25 }
]
A total: 470
[
  { name: 'b', skillIndex: 100 },
  { name: 'k', skillIndex: 100 },
  { name: 'm', skillIndex: 75 },
  { name: 'e', skillIndex: 60 },
  { name: 'h', skillIndex: 60 },
  { name: 'j', skillIndex: 50 },
  { name: 'n', skillIndex: 35 }
]
B total: 480
>>>>>>>>>>>>>>
[
  { name: 'b', skillIndex: 100 },
  { name: 'c', skillIndex: 90 },
  { name: 'f', skillIndex: 80 },
  { name: 'g', skillIndex: 70 },
  { name: 'l', skillIndex: 60 },
  { name: 'i', skillIndex: 45 },
  { name: 'd', skillIndex: 25 }
]
A total: 470
[
  { name: 'a', skillIndex: 100 },
  { name: 'k', skillIndex: 100 },
  { name: 'm', skillIndex: 75 },
  { name: 'e', skillIndex: 60 },
  { name: 'h', skillIndex: 60 },
  { name: 'j', skillIndex: 50 },
  { name: 'n', skillIndex: 35 }
]
B total: 480
>>>>>>>>>>>>>>
[
  { name: 'a', skillIndex: 100 },
  { name: 'k', skillIndex: 100 },
  { name: 'f', skillIndex: 80 },
  { name: 'g', skillIndex: 70 },
  { name: 'l', skillIndex: 60 },
  { name: 'i', skillIndex: 45 },
  { name: 'd', skillIndex: 25 }
]
A total: 480
[
  { name: 'b', skillIndex: 100 },
  { name: 'c', skillIndex: 90 },
  { name: 'm', skillIndex: 75 },
  { name: 'e', skillIndex: 60 },
  { name: 'h', skillIndex: 60 },
  { name: 'j', skillIndex: 50 },
  { name: 'n', skillIndex: 35 }
]
B total: 470
>>>>>>>>>>>>>>
[
  { name: 'a', skillIndex: 100 },
  { name: 'c', skillIndex: 90 },
  { name: 'm', skillIndex: 75 },
  { name: 'g', skillIndex: 70 },
  { name: 'l', skillIndex: 60 },
  { name: 'i', skillIndex: 45 },
  { name: 'd', skillIndex: 25 }
]
A total: 465
[
  { name: 'b', skillIndex: 100 },
  { name: 'k', skillIndex: 100 },
  { name: 'f', skillIndex: 80 },
  { name: 'e', skillIndex: 60 },
  { name: 'h', skillIndex: 60 },
  { name: 'j', skillIndex: 50 },
  { name: 'n', skillIndex: 35 }
]
B total: 485
>>>>>>>>>>>>>>
[
  { name: 'a', skillIndex: 100 },
  { name: 'c', skillIndex: 90 },
  { name: 'f', skillIndex: 80 },
  { name: 'e', skillIndex: 60 },
  { name: 'l', skillIndex: 60 },
  { name: 'i', skillIndex: 45 },
  { name: 'd', skillIndex: 25 }
]
A total: 460
[
  { name: 'b', skillIndex: 100 },
  { name: 'k', skillIndex: 100 },
  { name: 'm', skillIndex: 75 },
  { name: 'g', skillIndex: 70 },
  { name: 'h', skillIndex: 60 },
  { name: 'j', skillIndex: 50 },
  { name: 'n', skillIndex: 35 }
]
B total: 490
>>>>>>>>>>>>>>
[
  { name: 'a', skillIndex: 100 },
  { name: 'c', skillIndex: 90 },
  { name: 'f', skillIndex: 80 },
  { name: 'g', skillIndex: 70 },
  { name: 'h', skillIndex: 60 },
  { name: 'i', skillIndex: 45 },
  { name: 'd', skillIndex: 25 }
]
A total: 470
[
  { name: 'b', skillIndex: 100 },
  { name: 'k', skillIndex: 100 },
  { name: 'm', skillIndex: 75 },
  { name: 'e', skillIndex: 60 },
  { name: 'l', skillIndex: 60 },
  { name: 'j', skillIndex: 50 },
  { name: 'n', skillIndex: 35 }
]
B total: 480
>>>>>>>>>>>>>>
[
  { name: 'a', skillIndex: 100 },
  { name: 'c', skillIndex: 90 },
  { name: 'f', skillIndex: 80 },
  { name: 'g', skillIndex: 70 },
  { name: 'l', skillIndex: 60 },
  { name: 'j', skillIndex: 50 },
  { name: 'd', skillIndex: 25 }
]
A total: 475
[
  { name: 'b', skillIndex: 100 },
  { name: 'k', skillIndex: 100 },
  { name: 'm', skillIndex: 75 },
  { name: 'e', skillIndex: 60 },
  { name: 'h', skillIndex: 60 },
  { name: 'i', skillIndex: 45 },
  { name: 'n', skillIndex: 35 }
]
B total: 475
>>>>>>>>>>>>>>
[
  { name: 'a', skillIndex: 100 },
  { name: 'c', skillIndex: 90 },
  { name: 'f', skillIndex: 80 },
  { name: 'g', skillIndex: 70 },
  { name: 'l', skillIndex: 60 },
  { name: 'i', skillIndex: 45 },
  { name: 'n', skillIndex: 35 }
]
A total: 480
[
  { name: 'b', skillIndex: 100 },
  { name: 'k', skillIndex: 100 },
  { name: 'm', skillIndex: 75 },
  { name: 'e', skillIndex: 60 },
  { name: 'h', skillIndex: 60 },
  { name: 'j', skillIndex: 50 },
  { name: 'd', skillIndex: 25 }
]
B total: 470
>>>>>>>>>>>>>>
0 1 2 3 4 5 6 7 8 9  indices
0 1   3 4     7      one half selected
    2     5 6   8 9  other half is the rest without the first selected