7

The Stirling number of the second kind is the number of ways to partition a set of $n$ objects into $k$ non-empty subsets. In Mathematica, this is implemented as StirlingS2. How can I enumerate all the sets? Ideally I would like to get a list of lists, where each list contains $k$ lists.

The question Partition a set into subsets of size k seems relevant.

Juho
  • 1,825
  • 1
  • 18
  • 32

2 Answers2

10

This is faster than the Combinatorica function:

KSetP[{}, 0] = {{}};
KSetP[s_List, 0] = {};
KSetP[s_List, k_Integer] /; k > Length@s = {};
KSetP[s_List, k_Integer] /; k > 0 :=
 Block[{ikf, s1 = s[[1]]},
  ikf[set_] := Array[MapAt[#~Prepend~s1 &, set, #] &, Length@set];
  Join[
   Prepend[#, {s1}] & /@ KSetP[Rest@s, k - 1],
   Join @@ ikf /@ KSetP[Rest@s, k]
  ]
 ]

(r1 = KSetPartitions[Range@12, 4]) // Timing // First

(r2 = KSetP[Range@12, 4])          // Timing // First
1.529

1.139

The output is in a different order but it is equivalent:

Sort[Sort /@ r1] === Sort[Sort /@ r2]

True

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • I think r1 = KSetPartitions needs to be renamed, as my output does not recognise the name? – apg May 21 '19 at 15:36
  • 1
    @AlexanderKartun-Giles Sorry, I forgot to include Needs["Combinatorica`"] in my code; if you load that package first does the comparison work as expected? – Mr.Wizard May 24 '19 at 04:38
7
<< Combinatorica`
KSetPartitions[{a, b, c}, 2]
(*
  {{{a}, {b, c}}, {{a, b}, {c}}, {{a, c}, {b}}}
*)

 StirlingS2[3, 2]
 (* 3 *)
Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453