1
$\begingroup$

I have a number $N$ (for example $N=64$).

Is there any algorithm to find all the feasible ways for writing the number $N$ as a sum of $M$ positive numbers?

(For example $M=16$) --- Repetition is allowed.

$n_1 + n_2 + n_3 + ... + n_{16} = 64$
$n_i \ge 1$

$\endgroup$
3
  • $\begingroup$ and the order counts, or you are considering combinations with repetitions ? and in every case : a 4 lines recursive function will do the trick $\endgroup$
    – reuns
    Commented May 17, 2016 at 5:00
  • 2
    $\begingroup$ The question about order is important, as this will distinguish between integer compositions and integer partitions. There are fewer of the latter, but the former is easier to count. $\endgroup$ Commented May 17, 2016 at 5:10
  • $\begingroup$ Order is important! $\endgroup$
    – Amin
    Commented May 17, 2016 at 5:24

4 Answers 4

4
$\begingroup$

This is the subset-sum problem -- it is NP-Complete, hence although there are certainly algorithms for it, none are necessarily "fast" in general (possibly for special cases of the problem though).

The most common approach is dynamic programming.

EDIT: while Wikipedia is unnecessarily general, as usual, the subset sum problem usually refers to OP's problem (i.e. restricted to positive integers) and is well-studied with several known solutions, such as dynamic programming. All of the following links give dynammic programming solutions to the subset sum problem when the restriction is to the positive integers.

http://algorithms.tutorialhorizon.com/dynamic-programming-subset-sum-problem/ http://www.cs.dartmouth.edu/~ac/Teach/CS105-Winter05/Notes/nanda-scribe-3.pdf https://www.cs.cmu.edu/~ckingsf/class/02713-s13/lectures/lec15-subsetsum.pdf https://cseweb.ucsd.edu/classes/wi12/cse202-a/lecture7-final.pdf

Moreover, as also described in Cormen et al., and Kleinberg and Tardos, the Subset Sum problem refers to the restriction to the case of positive integers only. OP's $M$ constraint can be implemented easily by choosing a proper set of integers ($M$ copies of all integers less than or equal to $N-1$ will be sufficient, although strictly more than necessary).

Also all of the other answers given below just give pseudo-code for the dynamic programming solutions without explaining the provenance or the reasoning behind those choices. The links above, in contrast, explain the theory behind the idea in detail and how to specifically apply it to the subset sum problem, while retaining enough generality to allow OP to figure out how to fill in the details relevant for the implementation of their specific case.

$\endgroup$
1
  • 1
    $\begingroup$ Dear @William, thanks very much for your answer. But I didn't get it very well! In my case, I want to get the all possibilities of M positive integers equal to N. In fact, I should write the code in MATLAB. $\endgroup$
    – Amin
    Commented May 17, 2016 at 11:14
3
$\begingroup$

This is the stars and bars problem. Imagine a line of $64$ stars and $63$ candidate bars between them. Pick $15$ of those bars to be real and read off the groupings. There are ${64 \choose 15}=122131734269895$ To make the list, there are many algorithms on the web to generate the combinations of $15$ choices out of $63$. For example, you can use the fact that ${63 \choose 15}={62 \choose 14}+{62 \choose 15}$, where the first are combinations that include the first bar (and hence have $1$ as the first summand) and the second are those that do not have the first bar (so the first summand is greater than $1$). This suggests a recursive algorithm.

$\endgroup$
2
$\begingroup$
function partitionCombination(N,m,p) {
    if (N == 0) print(p);
    else {
      L = p.length;
      for (i = m; i >= 1; i--) {
        p[L] = i;
        partitionCombination(N-i,i,p);
      }
      p.length = L;
    } 
}

 function partitionOrderCounts(N,p) {
    if (N == 0) print(p);
    else {
      L = p.length;
      for (i = N; i >= 1; i--) {
        p[L] = i;
        partitionOrderCounts(N-i,p);
      }
      p.length = L;
    } 
}
partitionCombination(8,8,[]);
partitionOrderCounts(8,[]);
$\endgroup$
2
$\begingroup$

You can use a recursive algorithm to iterate through the solutions, but there is an easy way to count them. The amount of non negative solutions to \begin{equation} x_1 + x_2 + \cdots + x_n = a \end{equation} is $a + n - 1 \choose n - 1$ or equivalently $a + n - 1 \choose a$. Since we want integer solutions, let $y_k = x_k + 1$. Each $y_k$ is now an integer. Re writing the top equation \begin{align} y_1 - 1 + y_2 - 1 + \cdots + y_n - 1 &= a\\ y_1 + y_2 + \cdots + y_n &= a + n \end{align} which still has $a + n - 1 \choose n - 1$ solutions. Let $a + n = N$ and $n = M$, then the equation \begin{equation} x_1 + x_2 + \cdots + x_M =N \end{equation} has $N - 1 \choose M - 1$ solutions.

$\endgroup$
1
  • $\begingroup$ Thanks dear @Jeevan for your answer. besides the number of possible ways, I need an algorithm to find those set of numbers. $\endgroup$
    – Amin
    Commented May 17, 2016 at 5:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .