4

I have a list of names.

I want to partition this list into groups of a specified size. All groups should be equal to or less than the specified size, with an equal as possible group size across the groups, and as close to the specified size as possible.

What algorithm (Java-esque pseudo code if possible please!) determines the most appropriate group sizes?

For example:

List contains 13 names - max team size 3. Output (group sizes): 3, 3, 3, 2, 2

List contains 13 names - max team size 4. Output: 4, 3, 3, 3

List contains 31 names - max team size 5. Output: 5, 5, 5, 4, 4, 4, 4

List contains 31 names - max team size 6. Output: 6, 5, 5, 5, 5, 5

List contains 31 names - max team size 10. Output: 8, 8, 8, 7

3
  • 1
    Is this homework? What have you tried? Commented Jan 12, 2012 at 14:31
  • 1
    1,1,1,1,1,1,1,1,1,1,1,1,1 also has max 3 items in each group and the group sizes are more equal than in your example. Commented Jan 12, 2012 at 14:39
  • 3
    The expected output is not clear. For example, what's the output for: List contains 31 names - max team size 10 Commented Jan 12, 2012 at 14:50

4 Answers 4

4

It's pretty straightforward. You calculate the result of N div M and add 1 to have the correct number of arrays (N is the list length and M the max team size), then you iterate on all arrays to add an item until you run out of items

example : 43 names, max team number 4 => 43 mod 4 + 1 = 11, remains 3. so 11 arrays (10 with 4 and 1 with 3)

Sign up to request clarification or add additional context in comments.

2 Comments

You probably meant div, not mod, because 43 mod 4 is 3, not 10 (mod means remainder, not integer division). Also +1 would not work if M divides N without a remainder. You need to do (N+M-1) div M to get the result you are looking for.
I think this answer was so obvious in it's simplicity, that I overlooked it as the solution. :)
2

I'm not going to write code for this, but

  1. If the list size is a multiple of the max team size, divide by team size to get the number of groups, all of max size, and stop.
  2. Integer-divide the list size by the max team size, then add one. That's the number of groups.
  3. Subtract the list size from that next higher multiple; that's the number of teams that are one less than the max size.

This obviously only works for inputs that are close to working out; it fails if the max team size is large compared to the size of the list.

Comments

2

If the number of items in the list is N and the max number of items in sublist is K, the solution of your problem comes from solving a Linear Diophantine Equation

K*x + (K-1)*y = N

with additional constraints

x > 0
y >= 0

Where x is the number of sublists of the exact size K, and y is the number of sublists of length K-1.

EDIT : Because of the coefficients to the equation are always off by one from each other, the solution is rather straightforward:

int m = (N+K-1)/K;
int x = N - (K-1)*m; // Number of "full" lists
int y = K*M - N;     // Number of off-by-one lists

Example 1:

N = 31, K = 5
m = (31+5-1)/5 = 7
x = 31 - (5-1)*7 = 3 // 3 lists of 5 items
y = 5*7 - 31 = 4     // 4 lists of 4 items

Example 2:

N = 32, K = 4
m = (32+4-1)/4 = 8
x = 32 - (4-1)*8 = 8 // 8 lists of 4 items
y = 4*8 - 32 = 0     // no lists of 3 items

Look up an algorithm for solving linear Diophantine equations on the net - it is not that complicated, if you understand Euclidean algorithm well. The number of solutions of the equation without constraints is infinite, but once you add the constraints, you should get a single solution.

1 Comment

I think the algorithm changes somewhat based on the example with a list of 31, max size of 10.
0
public class Q {
public static void q(int size, int maxTeamSize) {
    int numOfTeams = size / maxTeamSize;
    int mod = size % maxTeamSize;
    numOfTeams += (mod > 0) ? 1 : 0;
    System.out.print("\n(" + size + ":" + maxTeamSize + ")");
    for (int i = 0; i < numOfTeams; i++) {
        System.out.print(" " + (size / numOfTeams + ((i < mod) ? 1 : 0)));
    }
}

public static void main(String[] args) {
    q(13, 3);
    q(12, 4);
    q(31, 5);
    q(31, 6);
}
}

1 Comment

This is a neat algorithm but results in more groups of a smaller number. I am aiming at getting as many groups as close as possible to the max team size as possible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.