An algorithm to calculate probability of a sum of the results happening

Let's say that f(a, b, n, x) represents the number of ways you can select n numbers between a and b, which sum up to x.

Then notice that:

f(a, b, n, x) = f(0, b-a, n, x-n*a)

Indeed, just take one way to achieve the sum of x and from each of the n numbers subtract a, then the total sum will become x - n*a and each of them will be between 0 and b-a.

Thus it's enough to write code to find f(0, m, n, x).

Now note that, all the ways to achieve the goal, such that the last number is c is:

f(0, m, n-1, x-c)

Indeed, we have n-1 numbers left and want the total sum to be x-c. Then we have a recursive formula:

f(0,m,n,x) = f(0,m,n-1,x) + f(0,m,n-1,x-1) + ... + f(0,m,n-1,x-m)

where the summands on the right correspond to the last number being equal to 0, 1, ..., m

Now you can implement that using recursion, but this will be too slow.

However, there is a trick called memoized recursion, i.e. you save the result of the function, so that you don't have to compute it again (for the same arguments).

The memoized recursion will have complexity of O(m * n), because that's the number of different input parameters that you need to compute and save.

Once you have computed the count you need to divide by the total number of posiblities, which is (m+1)*n to get the final probability.


First of all, you do not need to worry about the range being from a to b. You can just subtract a*x from y and pretend the range goes from 0 to b-a. (Because each item contributes at least a to the sum... So you can subtract off that a once for each of your x items.)

Second, note that what you are really trying to do is count the number of ways of achieving a particular sum. The probability is just that count divided by a simple exponential (b-a+1)^x.

This problem was covered by "Ask Dr. Math" around a decade ago:

http://mathforum.org/library/drmath/view/52207.html

His formulation is assuming dice numbered from 1 to X, so to use his answer, you probably want to shift your range by a-1 (rather than a) to convert it into that form.

His derivation uses generating functions which I feel deserve a little explanation. The idea is to define a polynomial f(z) such that the coefficient on z^n is the number of ways of rolling n. For a single 6-sided die, for example, this is the generating function:

z + z^2 + z^3 + z^4 + z^5 + z^6

...because there is one way of rolling each number from 1 to 6, and zero ways of rolling anything else.

Now, if you have two generating functions g(z) and h(z) for two sets of dice, it turns out the generating function for the union of those sets is just the product of g and h. (Stare at the "multiply two polynomials" operation for a while to convince yourself this is true.) For example, for two dice, we can just square the above expression to get:

z^2 + 2z^3 + 3z^4 +4z^5 + 5z^6 + 6z^7 + 5z^8 + 4z^9 + 3z^10 + 2z^11 + z^12

Notice how we can read the number of combinations directly off of the coefficients: 1 way to get a 2 (1*z^2), 6 ways to get a 7 (6*z^7), etc.

The cube of the expression would give us the generating function for three dice; the fourth power, four dice; and so on.

The power of this formulation comes when you write the generating functions in closed form, multiply, and then expand them again using the Binomial Theorem. I defer to Dr. Math's explanation for the details.