Search code examples
algorithmtheory

What is the best way to distribute n forms in c categories between u users?


I have asked this question in cstheory too

I have a form distribution problem. There is n forms in c categories (each form in 1 category). And there is u users, which each user can receive forms from at least one category (but maybe more than one category).

The goal is to distribute forms between users, so each user receive the same amount of forms. I prefer to equally use categories.

For example:

If categories are:

C1 : 20 forms

C2 : 3 forms

C3 : 8 forms

C4 : 2 forms

And users are:

U1 with access to C1 and C2

U2 with access to C2

U3 with access to C3

U4 with access to C1 and C3

U5 with access to C2 and C4

The answer should be:

U1: 1 x C1 + 1 x C2 | 2 x C1 (preferred)

U2: 2 x C2

U3: 2 x C3

U4: 1 x C1 + 1 x C3 | 2 x C1 (preferred) | 2 x C3

U5: 2 x C4

And 23 forms remains.

Do you have any suggestion on how can I write such algorithm?

There could be a second question, which in that some Categories have a SHOULD CONTRIBUTE option. Which if set, all remaining forms in that category will distribute between users who have access to that. for example if C1 have this option enabled, the answer should be:

U1: 1 x C1 + 1 x C2 + 9 C1

U2: 2 x C2

U3: 2 x C3

U4: 2 x C3 (to minimize remaining forms in C3 category) + 10 C1

U5: 2 x C4

and remaining forms would be 0 in C1, 0 in C2, 4 in C3 and 0 in C4.

I think its kinda Bin Packing algorithm, but I am not sure and I don't know how to solve it! :(

Note: The above answers are not best answers, these are just what I think!


Solution

  • It seems to me that if you fix a number N of forms per user and ask the question: can we give N forms to each user? then you can turn this into a http://en.wikipedia.org/wiki/Maximum_flow_problem problem, where each user can receive flow/forms from their subset of categories, and there is an outflow of capacity N from each user. Also, if you can solve this problem for N you can solve it for all lesser values of N.

    So you could solve the first problem by running max-flow lg (maximum N) times, using a binary chop to find out what the best possible value of N is. Since you can solve it by max flow, you can also solve it by linear programming. Doing it this way, perhaps just for the critical value of N, might allow you to favour some assignments over others, or perhaps to see where there are neighbouring feasible solutions, and then see if you can mix them to use categories equally.

    Example - Create a source, and link it to each of the categories Ci, with the capacity of the link being the number of forms available in that category, so C1 gets a link from the source of capacity 20. Create links with their source's capacity between users and categories, where the user has access to the category, so U1 gets links to C1 and C2, but U2 only gets a link to C2. Now create links of capacity N from each user to a single sink. If there is an assignment of forms to users that gives every user N forms, then this will produce a maximum flow that fills every link from user to sink, and you can look at the flows between users and categories to see how to assign forms. You could start off with N = 3, because user 2 only has access to a total of 3 forms, so the answer can't be greater than that. That won't work because you have said the right answer has N = 2, so the max flow won't fill all the N=3 capacity links. So your program tries again at 3/2 = 1, and finds a solution - you have provided a solution for N = 2, so there must be one for N = 1. Now the program knows there is a solution for N = 1 but not one for N = 3 so it tries one halfway between at N = (1 + 3) / 2 = 2, and finds your solution. There is one for N = 2 but not for N = 3 so the N = 2 solution is the best you can do.