GuyShoham
GuyShoham

Reputation: 39

algorithm splitting values into groups to make equals groups with same amount of values

lets say I have an array with N (for this example N=10) values, each value is between 1-10:

10
8.4
7.9
7.8
7.7
7.3
7.3
6.9
6.1
5.8

now, I want to split them into P groups (for this example P=2), which all the groups will be even (AKA their SUM), or as close as possible.

I already wrote an algorithm for that:

 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);
            }
        }
    }
}

The problem is that the algorithm didn't worked out perfectly. for the same example above he gave me

 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

which I can manually match them better this way:

 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

(The algorithm I wrote is aimed to 3 groups of 6 players each - means 18 players top, when the extra players move to the following group)

Upvotes: 1

Views: 1381

Answers (1)

Avishek Bhattacharya
Avishek Bhattacharya

Reputation: 6974

The problem you posted is a NP-Hard problem and it is called K way Partitioning problem in computer science.

There are few approximate solution and greedy solution for the problem.

Since it is an well known theoretical problem, I would suggest you to take a look Partitioning Problem.

Upvotes: 3

Related Questions