Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distribution of balls into 'bins with given capacities' using Dynamic Programming

I was wondering how to solve such a problem using DP.

Given n balls and m bins, each bin having max. capacity c1, c2,...cm. What is the total number of ways of distributing these n balls into these m bins.

The problem I face is

  1. How to find a recurrence relation (I could when the capacities were all a single constant c).
  2. There will be several test cases, each having its own set of c1,c2....cm. So how would the DP actually apply for all these test cases because the answer explicitly depends on present c1,c2....cm, and I can't store (or pre-compute) the answer for all combinations of c1,c2....cm.

Also, I could not come up with any direct combinatoric formula for this problem too, and I don't think one exists too.

like image 791
Andrew Avatar asked Oct 05 '11 14:10

Andrew


2 Answers

You can define your function assuming the limits c[0], c[1], ... c[m-1] as fixed and then writing the recursive formula that returns the number of ways you can distribute n balls into bins starting at index k. With this approach a basic formula is simply

def solutions(n, k):
    if n == 0:
        return 1  # Out of balls, there's only one solution (0, 0, 0, 0 ... 0)
    if k == m:
        return 0  # Out of bins... no solutions
    total = 0
    for h in xrange(0, min(n, c[k])+1): # from 0 to c[k] (included) into bin k
        total += solutions(n - h, k + 1)
    return total

then you need to add memoization (this will be equivalent to a DP approach) and some other optimizations like e.g. that if n > c[k] + c[k+1] + c[k+2] + ... then you know there are no solutions without the need to search (and you can precompute the partial sums).

like image 166
6502 Avatar answered Oct 21 '22 23:10

6502


  1. There exists a combinatoric formula for this problem. The problem of finding the solutions to your problem is equivalent to finding the number of solutions of the equation
    x1 + x2 + x3 + ... + xm = n
    where xi < ci
    Which is equivalent to finding the cofficient of x^n in the following equation
    (1+x+..x^c1)(1+x+..+x^c2)...(1+x+...+x^cm)

  2. The recursion for this equation is pretty simple
    M(i,j) = summation(M(i-1, j-k)) where 0<= k <= cj M(i,j) = 0 j <= 0 M(i,1) = i given for every 1= 1 M(i,j) is the number of ways of distributing the j balls in first i bins.

For the Dynamic Programming part Solve this recursion by Memoization, You will get your DP Solution automatically.

like image 35
gibraltar Avatar answered Oct 21 '22 23:10

gibraltar