首页 > 解决方案 > 基于技能指数从 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,
                });
            }

标签: javascriptalgorithmsortingmath

解决方案


首先,对于您的示例,只有 252(10 选择 5)可能的结果。所以尝试所有这些(蛮力)很容易完成。

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


推荐阅读