Set Partitions

[Home]   [Puzzles & Projects]    [Delphi Techniques]   [Math topics]   [Library]   [Utilities]




Search WWW


As of October, 2016, Embarcadero is offering a free release of Delphi (Delphi 10.1 Berlin Starter Edition ).     There are a few restrictions, but it is a welcome step toward making more programmers aware of the joys of Delphi.  They do say "Offer may be withdrawn at any time", so don't delay if you want to check it out.  Please use the feedback link to let me know if the link stops working.


Support DFF - Shop

 If you shop at Amazon anyway,  consider using this link. 


We receive a few cents from each purchase.  Thanks


Support DFF - Donate

 If you benefit from the website,  in terms of knowledge, entertainment value, or something otherwise useful, consider making a donation via PayPal  to help defray the costs.  (No PayPal account necessary to donate via credit card.)  Transaction is secure.

Mensa Daily Puzzlers

For over 15 years Mensa Page-A-Day calendars have provided several puzzles a year for my programming pleasure.  Coding "solvers" is most fun, but many programs also allow user solving, convenient for "fill in the blanks" type.  Below are Amazon  links to the two most recent years.

Mensa 365 Puzzlers  Calendar 2017

Mensa 365 Puzzlers Calendar 2018

(Hint: If you can wait, current year calendars are usually on sale in January.)


Feedback:  Send an e-mail with your comments about this program (or anything else).

Search only




Given any set of distinct objects, how many ways can it be split into subsets?   Such a division is called a set partition.   More formally, a set partition of a set of distinct objects, S,  is a set of disjoint subsets whose union is S.

For example, the set {a,b,c} can be partitioned in 5 ways: 


One subset  {a,b,c}
Two subsets  {a} {b,c}
{b} {a,c}
{c} {a,b}
Three subsets   {a} {b} {c}

A set with 4 members can be partitioned in 15 ways,   5 members in 52 ways, etc.   The number of ways that a set can be partitioned is it's Bell number.  Named after Eric T. Bell, the mathematician who first studied the numbers in depth.  As a matter of curiosity, the Bell number for a set with N members, B(N),  is the sum of the number of ways that it can be partitioned into 1, 2, 3, ... N  subsets.   The number of ways that a set of size N can be partitioned into K subsets, denoted S2(N,K),  has also been named - "Stirling numbers of the second kind".   So, in general B(N)=Sumk=1 to N S2(N,k).     For example:    B(3) = S2(3,1) + S2(3,2) + S2(3,3) = 1 + 3 + 1 = 5. 

Stirling numbers of the first kind, S1(N,k), by the way represent the number of permutations of N objects that contain exactly k cycles.   A cycle describes the way that  permutations are generated from the original ordered set - a topic we'll save for another day.

The program here generates a few (up to 1000) partitions for any set size from 2 to 25.  It will also generate and display the Bell number and the Stirling 2 numbers for any set in this range.  

Generating partitions  

The idea of a restricted growth function is key to generating the partition themselves.    The restricted growth array, RG,  is a set of zero based indices specifying  to which partition each element of the set belongs.  For set size 4, for example RG=[0,0,0,0]  defines the single set partition {1,2,3,4} , RG=[0,1,1,0] represents {1,4},{2,3}  , etc.   The RG array values have the characteristic that for each i,   RG[i]<=1+max(RG[0], RG[1]... RG[i-1]).  So [0,0,0,2]  is not a valid RG array for example.   Procedure GetNextRG in unit USetPartition  does the job of generating RG values in this program.   Procedure GetNextPartition calls GetNextRG to get the values used to generate the actual partition records.

Generating  Bell numbers (number of partitions)

The number of partitions increases rapidly with set size - more than a billion for 15 items - so it's not practical to count the number of ways by actually generating them.   There is a recursive definition for Stirling numbers of the second type, therefore we can sum these as described above to get the Bell number.    Above 10 members, the recursive definition time can become long unless you have a fast computer.  The original PartitionCount procedure remains in commented form in the downloaded code, for reference.   The Stirling2 function can be called to see the distribution of partition subset sizes for any set size (again for large set sizes and older computers, this may take a few minutes).  

The alternative method  is based on a Bell triangle description found at   with this construction algorithm   "The numbers can be constructed by using the Bell Triangle, a name suggested to Martin Gardner by Jeffrey Shallit. Start with a row with the number 1.   Afterward each row begins with the last number of the previous row and continues to the right adding each number to the number above it to get the next number in the row."  Sure enough it works and it is fast.  The program will generate Bell numbers up to the limit of the 64 bit integer type, about set size 25. 

May 8, 2006: A small fix was made today to handle the partitioning of a single element set.  Of course, there is only one partition, the element itself, but the  TPartition class should return it, and now it does.   

Download source code

Download executable program

Created: November 21, 2002

Modified: May 11, 2018


  [Feedback]   [Newsletters (subscribe/view)] [About me]
Copyright 2000-2018, Gary Darby    All rights reserved.