javascript - 基于技能指数从 10 人列表中组成两个团队的算法
问题描述
我正在尝试提出一种算法,该算法检查球员列表中所有可能的组合,并组成两支 5 人的球队,总人数可能相差最接近skillIndex
。到目前为止,我已经想出了以下令人筋疲力尽的排列:
我想知道是否有更好的方法来得出一个基于skillIndex
. 你们知道什么是解决这个问题的有效方法吗?
我的最终目标是拥有两支球队,其中一名球员只能在一支球队中。并且团队有一个尽可能接近彼此的技能指数。
我现在的方法是找到数组的所有可能组合,将这个数组分成两半,这样我就有了两个团队。然后计算两个数组的skillindex并比较它们之间的差异。如果差值 <= 5,则打印生成的团队。
所以一个硬性要求是,拥有相同数量的球员的球队由不同的球员组成,因此我需要多种选择。
const permutate = () => {
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 },
];
const getDifference = (a, b) => {
return Math.abs(a - b);
};
function permutation(array) {
function p(array, temp) {
let i;
let x;
if (!array.length) {
let team1Index = 0;
let team2Index = 0;
const half = temp.length / 2;
const team1 = temp.splice(0, half);
const team2 = temp.splice(-half);
team1.forEach((player) => {
team1Index += parseFloat(player.skillIndex, 10);
});
team2.forEach((player) => {
team2Index += parseFloat(player.skillIndex, 10);
});
const difference = getDifference(team1Index, team2Index);
if (difference === 5) {
console.log({ team1, team2 });
debugger;
}
result.push(temp);
}
for (i = 0; i < array.length; i++) {
x = array.splice(i, 1)[0];
p(array, temp.concat(x));
array.splice(i, 0, x);
}
}
const result = [];
p(array, []);
return result;
}
console.log(permutation(presentPlayers));
};
所以现在我主要根据你们的提示提出了这个解决方案。我运行此代码 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,
});
}
解决方案
首先,对于您的示例,只有 252(10 选择 5)可能的结果。所以尝试所有这些(蛮力)很容易完成。
在更一般的情况下,您可以运行递归方法,在每个级别您将一个人分配给一个团队,并检查可以为下一个人分配做什么。将您获得的最佳(最接近)值sumOfAllSkillIndex/2
以及谁在哪个团队中保存在一个全局变量中。
推荐阅读
- python - 如何从训练有素的 pytorch 模型中获得置信度分数
- python - 从 pandas df 中提取有用信息到字典
- c# - 如何使用 EF Core 为 TEntity 设置外键可选
- youtube - 点评:更新给了403 禁止权限不足
- javascript - 从 DOM 中删除元素后如何再次显示它?
- html - 使用 css 创建行加载动画
- python - 为子文件夹脚本导入父文件夹 python 脚本(请不要使用 sys.path 解决方法)
- python - 在破折号/绘图python中的两行中显示多项目符号图表
- r - 使用 Rollapply 返回 Coefficient 和 Rsquare
- php - session_set_save_handler 和 $register_shutdown = false