0

I am stuck with a problem and I need some help from bright minds of SO. I want to divide n players to m teams. Each player has different game abilities. Abilities are represented by positive or negative integers. A team's total ability is simply the sum of the ability scores of the people assigned to that team.

My goal is to find the minimum possible difference between the team with the maximum total ability and the team with the minimum total ability. The constraints are each player must be placed on a team and every team must have at least one member.

For example if I have the following player with abilities: [1, 2, 3, 4, 5, 6, 7] and want to form three teams. So the min possible difference between the team with the maximum total ability and the team with the minimum total ability is 1. One possible solution is:

Team 1: 1 + 3 + 6 = 10

Team 2: 2 + 7 = 9

Team 3: 4 + 5 = 9

I have tried to divide the players by using the following strategy:

1.sort the abilities

2.each time assign the remained highest ability player to the group with lowest ability until there is no players

This strategy works for some problems. Here is the code I had so far:

public int minDifference(int numTeams, int[] abilities) {
        ArrayList<ArrayList<Integer>> teams = new ArrayList<ArrayList<Integer>>();
        int[] teamSum = new int[numTeams];
        for(int i = 0; i < numTeams; i++){
            teams.add(new ArrayList<Integer>());
            teamSum[i] = 0;
        }
        Arrays.sort(abilities);
        for(int i = abilities.length - 1; i >= 0;  i--){
            int minSum = teamSum[0];
            int minNum = 0;
            for(int j = 1; j < numTeams; j++){
                if(teamSum[j] < minSum){
                    minSum = teamSum[j];
                    minNum = j;
                }
            }
            teams.get(minNum).add(abilities[i]);
            teamSum[minNum] += abilities[i];
        }
        Arrays.sort(teamSum);
        System.out.println(teamSum[numTeams - 1] - teamSum[0]);
        return teamSum[numTeams - 1] - teamSum[0];
    }

Now I am stuck. My idea is to compare two teams. Say A and B. Player Tom from A and Jerry from B. If A - B = 10, and Tom - Jerry = 3; then swap Tom and Jerry. So A - B = 4 now. And keep doing this. But it seems there are too many compares(because you also need to calculate the difference between players in two teams) and I don't know when to stop(means how can I know it is the minimum).

user2163156
  • 1
  • 1
  • 3
  • Sorry if the question is not clear. I want to divide n players to m teams and minimize the ability difference between the team with highest ability and the team with lowest ability. – user2163156 Jul 12 '13 at 07:10
  • 1
    Have you tried something yourself? If so, can you share it and explain what you need help with? SO is not a coding or algorithm service, we're not here to solve your problem, just to answer your question. – mthmulders Jul 12 '13 at 07:12
  • Show us [what you have tried](http://mattgemmell.com/2008/12/08/what-have-you-tried/) and we are able to help you. We are not code writing service (some people of us earn some money with writing code). – Uwe Plonus Jul 12 '13 at 07:19
  • *"I want .."* Tip. A question might start "How to.." & would typically end in '?'. The more clear you can make a question, the more chance it has of being answered. If that is your question, please [edit](http://stackoverflow.com/posts/17609298/edit) it into the question. – Andrew Thompson Jul 12 '13 at 07:31
  • Do you have bounds for how big the array can get? A brute force might be reasonable for smaller numbers. Otherwise this might be an optimization problem that doesn't have an "exact" algorithm. Your attempt (well, at least your description) is usually known as "hill-climbing". Here's wikipedia's reference on optimization algorithms: https://en.wikipedia.org/wiki/Optimization_algorithm#Computational_optimization_techniques. And here's a similar problem on SO: http://stackoverflow.com/questions/14120729/algorithm-to-split-an-array-into-p-subarrays-of-balanced-sum – rliu Jul 12 '13 at 08:20
  • Takee a look to [this post on StackExchange Stats](http://stats.stackexchange.com/questions/50277/minimize-the-standard-deviation-of-the-total-values-of-groups-of-items-optimiza). It doesn't provide code (in Java) but it describes algorithm to solve the problem. – Adriano Repetti Jul 12 '13 at 09:05

2 Answers2

0

I'm quite sure it's a NP problem since the decision of whether we can divide the players to 2 teams with no difference or not is subset-sum problem which belongs to NPC. Any polynomial time solution to this problem is not correct(or you can say the NP=P), so don't waste time on thinking polynomial solution and just try complete search(I meantry all m^n possible solution..), if you think it's too slow, you can try heuristic search.

Sayakiss
  • 6,878
  • 8
  • 61
  • 107
  • There might exist a reduction from subset-sum to OPs problem, but I don't think it's the obvious one. With subset-sum, all of the negative integers go to one team (say A) and all of the non-negative integers to the other team (say B). And then you'd be trying to figure out a subteam of A whose sum is equal to a subteam of B's sum (in magnitude). In this problem, you are given the restriction that each team has precisely (size of array) / (# of teams). Furthermore, you can't restrict elements of the array to only one team. Hard to be clear, but the "obvious reduction" doesn't seem to work. – rliu Jul 12 '13 at 16:57
-1

i think this way. you can add all abilities and divide it by number of teams, than try to come up with teams with total ability as close to that number as possible

MAB
  • 67
  • 12
  • Yes but can you clarify "_then try to come up with teams with total ability as close to that number as possible_"? He has the same problem as before (brute force approach or a more clever algorithm and then...which one?) – Adriano Repetti Jul 12 '13 at 08:34
  • keep 'big' list of all abilities and for each team make an list and do the following. you have desired ability for team. find in 'big' list the closest ability, delete it from 'big' list, add it into team's list, update desired ability do it recursively until desired ability = 0 or so ... do it for each team... one of possible strategies. – MAB Jul 12 '13 at 08:41
  • No, it'll make a good _choice_ only for the first team (others will be able to pick only what has not been used by predecessors). It's not the combination that will minimize differences. – Adriano Repetti Jul 12 '13 at 08:59
  • I think, that in any case this problem cant be solved efficiently, this is an heuristic approach that in some situations can give satisfactory answer – MAB Jul 12 '13 at 10:06
  • See my comment on the question and related links. Of course complexity will grow up increasing _M_ to an unacceptable level pretty soon (then some heuristic _may_ be needed). That said...heuristic can't be too raw (= it must be _good enough_, what IMO your approach is not). – Adriano Repetti Jul 12 '13 at 10:30