算法将值拆分为组以使等于具有相同数值的组

时间:2017-09-29 16:36:22

标签: java android algorithm

假设我有一个带N的数组(对于这个例子N = 10)值,每个值都在1-10之间:

10
8.4
7.9
7.8
7.7
7.3
7.3
6.9
6.1
5.8

现在,我想将它们分成P组(对于这个例子P = 2),所有组都是偶数(AKA为SUM),或尽可能接近。

我已经为此写了一个算法:

 public static void mainLogic(ArrayList<Player> team) {

    Player currentPlayer = new Player();
    Player minDifPlayer = new Player();

    double minDiff = 100;

    for (int ind = 0; ind < team.size(); ind++) {
        if (team.isEmpty())
            return;
        double temp = team.get(ind).get_playeroverall();

        if (ind == team.size() - 1) {
            //if num of Player match for two teams
            if (team.size() < 18) {

                // if the teams are equals or teamA AVG small then teamB
                if (sum(teamA) <= sum(teamB)) {
                    teamA.add(currentPlayer);
                    teamB.add(minDifPlayer);
                    Results.TempArray.add(currentPlayer);
                    Results.TempArray.add(minDifPlayer);
                    team.remove(currentPlayer);
                    team.remove(minDifPlayer);
                    //if teamB AVG small then teamA
                } else if (sum(teamA) > sum(teamB)) {
                    teamB.add(currentPlayer);
                    teamA.add(minDifPlayer);
                    Results.TempArray.add(currentPlayer);
                    Results.TempArray.add(minDifPlayer);
                    team.remove(currentPlayer);
                    team.remove(minDifPlayer);
                }
                // if the teams are full, Player are subscribed to the following team
                if (teamA.size() == 6 && teamB.size() == 6) {
                    teamC.addAll(team);
                    Results.TempArray.addAll(team);
                    team.clear();
                }

                ind = 0;
                minDiff = 100;
                if (!team.isEmpty())
                    temp = team.get(ind).get_playeroverall();
            }
        }
        for (int pointer = ind + 1; pointer <= team.size() - 1; pointer++) {

            double rankToCompare = team.get(pointer).get_playeroverall();

            if (Math.abs(temp - rankToCompare) < minDiff) {
                minDiff = Math.abs(temp - rankToCompare);
                currentPlayer = team.get(ind);
                minDifPlayer = team.get(pointer);
            }
        }
    }
}

问题是该算法没有完美解决。对于上面的例子,他给了我

 10       8.4
 7.8      7.9
 7.3      7.3
 6.9      7.7
 5.8      6.1
SUM=37.8 SUM=37.4

我可以通过这种方式手动匹配它们:

 10        8.4
 7.7       7.9
 7.3       7.3
 6.9       7.8
 5.8       6.1
SUM=37.7 SUM=37.5

(我写的算法针对3组,每组6名玩家 - 当额外玩家移动到下一组时,意味着18名玩家排名靠前)

1 个答案:

答案 0 :(得分:2)

您发布的问题是NP-Hard问题,在计算机科学中称为K方式分区问题。

这个问题很少有近似解决方案和贪心解决方案。

由于这是一个众所周知的理论问题,我建议你看看Partitioning Problem