Summing over Partitions

One idea is to use BooleanCountingFunction and SatisfiabilityInstances. First, a helper function that creates a list of n variables and a boolean expression asserting that all or none of the variables are true (in other words, each member k of your list is represented by k boolean variables):

g[n_] := With[{v = Table[Unique[], n]},
    {v, BooleanCountingFunction[{{0, n}}, n] @@ v}
]

This helper function is mapped over each element of your list. Then, a BooleanCountingFunction is created that is true when the target number of variables are true. Finally, SatisfiabilityInstances is used to find variables that satisfy the individual boolean expressions and the BooleanCountingFunction. Here's some code that finds the counts and the instances:

counts[v_, t_] := Module[{vv=g/@v, len, var, bool, i},
    var = Flatten[vv[[All, 1]]];
    len = Length @ var;
    bool = BooleanCountingFunction[{t}, len] @@ var && And @@ vv[[All, 2]];
    SatisfiabilityCount[bool, var]
]

instances[v_, t_] := Module[{vv=g/@v, len, var, bool, i},
    var = Flatten[vv[[All, 1]]];
    len = Length @ var;
    bool = BooleanCountingFunction[{t}, len] @@ var && And @@ vv[[All, 2]];
    i = Thread[var->#]& /@ SatisfiabilityInstances[bool, var, All];
    Boole[vv[[All, 1, 1]] /. i]
]

Example:

SeedRandom[1];
l = RandomInteger[{1, 10}, 50];

counts[l, 10] //AbsoluteTiming
res = instances[l, 10]; //AbsoluteTiming

{0.010638, 70934}

{28.4981, Null}

Check:

Tally[res . l]

{{10, 70934}}

Finding the instances is unfortunately rather slow.


Clear["Global`*"]

f[list_ /; Length[list] > 0, k_Integer?Positive] := Module[{x, var},
  var = Array[x, Length[list]];
  var /. Solve[{list.var == k, 0 <= var <= 1} // Flatten, var, Integers]]

SeedRandom[1]

list = RandomInteger[{1, 10}, 50]

(* {2, 5, 1, 8, 1, 1, 9, 7, 1, 5, 2, 9, 6, 2, 2, 2, 4, 3, 2, 7, 1, 3, 7, 5, 6, \
5, 4, 1, 2, 4, 6, 4, 1, 4, 3, 4, 10, 6, 2, 6, 3, 4, 10, 2, 1, 5, 5, 2, 6, 3} *)

k = 10;

sol = f[list, k];

Verifying the solutions,

And @@ (#.list == k & /@ sol)

(* True *)

There are too many solutions to look at

Length@sol

(* 70934 *)

Looking at the non-zero entries of the first ten solutions along with the corresponding list elements

(Transpose[{list, #}] & /@ sol[[1 ;; 10]]) /. {_, 0} :> Nothing

(* {{{5, 1}, {2, 1}, {3, 1}}, {{5, 1}, {2, 1}, {3, 1}}, {{5, 1}, {5, 1}}, {{1, 
   1}, {6, 1}, {3, 1}}, {{2, 1}, {2, 1}, {6, 1}}, {{2, 1}, {5, 1}, {3, 
   1}}, {{2, 1}, {5, 1}, {3, 1}}, {{2, 1}, {1, 1}, {5, 1}, {2, 1}}, {{2, 
   1}, {1, 1}, {5, 1}, {2, 1}}, {{10, 1}}} *)