You are on the Home/Excel/Excel Tips/Power Set page
Google
Web This Site

Powerset, Subset, and Combinations & Permutations

Introduction to sets, subsets, and the power set

This serves as a brief introduction to the subject of sets, subsets, power sets, and combinations & permutations.  By its very focus it is not meant to be thorough but more like a refresher.  For more search www.google.com, mathworld.wolfram.com, or www.wikipedia.org.

A set is the name for a collection of some number of elements.  Typically, the elements of the collection are not ordered amongst themselves and multiplicity (multiple entries) is ignored.  An example of a set containing the first four letters of the alphabet is A={a,b,c,d}.  Membership is denoted by a � A.  Since elements are not ordered, {a,b,c,d} is the same set as {c,a,d,b}.  By some conventions the empty element j is considered to be a member of every set.  The empty set, a set containing no elements is typically denoted by {} or F.

A subset, B, of a set, A, is a collection of elements such that each element in B is also a member of A. Conversely, A is the superset of B.  B is said to be a proper subset, denoted by B � A, if A contains elements not present in B.  Otherwise, one writes B � A.  Examples of subsets of the set {a,b,c,d} are {a,b}, {c,d}, and {b,c,d}.  Two extreme examples are the empty set B={j} and the set B={a,b,c,d} containing all elements in A.

The number of subsets each containing r elements from a set containing n elements is given by n!/[r!(n-r)!] where x! is the factorial of x given by 1*2*3...*(x-1)*x.  The corresponding Excel function is COMBIN.

The power set of a set A is the set containing all possible subsets of A including the empty subset.  It contains 2n elements where n is the number of elements in A.  It is typically denoted by P(A) or 2A.  Note that each element of a power set is a set in itself.  For example, the power set of the set A={a,b,c,d} is the set P(A)={{}, {a}, {b}, {c}, {d}, {a,b}, {a,c}, {a,d}, {b,c}, {b,d}, {c,d}, {a,b,c}, {a,b,d}, {a,c,d}, {b,c,d}, {a,b,c,d}}.

Introduction to combinations and permutations

A combination is a collection of r elements without regard to order taken from a collection of n elements.  Consequently, a combination is the same as a subset of size r.  Consequently, the number of possible combinations is given by n!/[r!(n-r)!] or the Excel function COMBIN.

A permutation is a collection of r elements from a collection of n elements keeping track of their order.  The number of permutations without repetition of an element is given by n!/(n-r)! and with repetition is given by nr.

Visual Basic for Applications code

The code below supports 4 public entry points (createSubset, createPowerSet, createPermutations, and createCombinations) for use by other code and 4 user defined functions or UDFs (UDFSubset, UDFPowerSet, UDFPermutations, and UDFCombinations).  In its current form the code does not handle data errors gracefully and may either fault or return erroneous results.  Also note that the functions createCombinations and UDFCombinations are added simply for the sake of completeness.  They are pass through functions and call the functions createSubset and UDFSubset respectively and are otherwise completely untested.

Option Explicit
Option Base 0
    Private Function NbrElements(Arr) As Integer
       On Error Resume Next
       NbrElements = UBound(Arr) - LBound(Arr) + 1
        End Function
    Private Function fixInput(Arr)
        If Not (TypeOf Arr Is Range) Then
            fixInput = Arr
        ElseIf Arr.Rows.Count > 1 Then
            fixInput = Application.WorksheetFunction.Transpose(Arr.Value)
        Else
            fixInput = Arr.Value
            End If
        End Function
    Private Function createOutput(Arr)
        If Not (TypeOf Application.Caller Is Range) Then
            createOutput = Arr
        ElseIf Application.Caller.Rows.Count > 1 Then
            createOutput = Application.WorksheetFunction.Transpose(Arr)
        Else
            createOutput = Arr
            End If
        End Function
Private Sub aSubset(Arr, CurrIdx, NbrItems, ByVal Delim As String, _
        ByVal PreString As String, ByRef Rslt)
    Dim i As Integer
    If NbrItems = 0 Then
        If PreString = "" Then Rslt(UBound(Rslt)) = PreString _
        Else Rslt(UBound(Rslt)) = Left(PreString, Len(PreString) - Len(Delim))
        ReDim Preserve Rslt(UBound(Rslt) + 1)
    Else
        For i = CurrIdx To NbrElements(Arr) - NbrItems + LBound(Arr)
            aSubset Arr, i + 1, NbrItems - 1, Delim, _
                PreString & Arr(i) & Delim, Rslt
            Next i
        End If
    End Sub
Public Function createSubset(Arr, NbrItems As Integer, Delim As String)
    Dim Rslt
    ReDim Rslt(0)
    aSubset Arr, LBound(Arr), NbrItems, Delim, "", Rslt
    ReDim Preserve Rslt(UBound(Rslt) - 1)
    Debug.Assert NbrElements(Rslt) = _
        Application.WorksheetFunction.Combin(NbrElements(Arr), NbrItems)
    createSubset = Rslt
    End Function
Public Function createPowerSet(Arr, Delim As String)
    Dim i As Integer, j As Integer, DestIdx As Integer, _
        Rslt, aSubset
    ReDim Rslt(0): DestIdx = 0
    For i = 0 To NbrElements(Arr)
        aSubset = createSubset(Arr, i, Delim)
        ReDim Preserve Rslt(UBound(Rslt) + NbrElements(aSubset))
        For j = LBound(aSubset) To UBound(aSubset)
            Rslt(DestIdx) = aSubset(j)
            DestIdx = DestIdx + 1
            Next j
        Next i
    ReDim Preserve Rslt(UBound(Rslt) - 1)
    createPowerSet = Rslt
    End Function
    
Private Sub AllPermutations(SrcData As Variant, ByVal RepetitionsOK As Boolean, _
        AlreadyUsed() As Boolean, ByVal RsltSize As Integer, _
        ByVal CurrentRslt, ByRef RsltArr(), Delim As String)
    If NbrElements(CurrentRslt) = RsltSize Then
        If NbrElements(RsltArr) = 0 Then ReDim RsltArr(0) _
        Else ReDim Preserve RsltArr(UBound(RsltArr) + 1)
        RsltArr(UBound(RsltArr)) = Join(CurrentRslt, Delim)
        Exit Sub
        End If
    Dim I As Integer
    If NbrElements(CurrentRslt) = 0 Then ReDim CurrentRslt(0) _
    Else ReDim Preserve CurrentRslt(UBound(CurrentRslt) + 1)
    For I = LBound(SrcData) To UBound(SrcData)
        If RepetitionsOK Then
            CurrentRslt(UBound(CurrentRslt)) = SrcData(I)
            AllPermutations SrcData, RepetitionsOK, AlreadyUsed, RsltSize, CurrentRslt, RsltArr, Delim
        ElseIf AlreadyUsed(I) Then
        Else
            AlreadyUsed(I) = True
            CurrentRslt(UBound(CurrentRslt)) = SrcData(I)
            AllPermutations SrcData, RepetitionsOK, AlreadyUsed, RsltSize, CurrentRslt, RsltArr, Delim
            AlreadyUsed(I) = False
            End If
        Next I
    End Sub

Public Function createPermutations(Arr As Variant, ByVal RsltSize As Integer, _
        ByVal RepetitionsOK As Boolean, ByVal Delim As String)
        'Arr, though declared as a variant should be an array.
    Dim CurrentRslt(), RsltArr(), AlreadyUsed() As Boolean
    ReDim AlreadyUsed(UBound(Arr))
    AllPermutations Arr, RepetitionsOK, AlreadyUsed, RsltSize, CurrentRslt, RsltArr, Delim
    createPermutations = RsltArr
    End Function
Public Function createCombinations(Arr, NbrItems As Integer, Delim As String)
    createCombinations = createSubset(Arr, NbrItems, Delim)
    End Function
Public Function UDFSubset(Arr, NbrItems As Integer, Delim As String)
    Arr = fixInput(Arr)
    UDFSubset = createOutput(createSubset(Arr, NbrItems, Delim))
    End Function
Public Function UDFPowerSet(Arr, Delim As String)
    Arr = fixInput(Arr)
    UDFPowerSet = createOutput(createPowerSet(Arr, Delim))
    End Function
Public Function UDFPermutations(Arr, RsltSize As Integer, _
        Optional RepetitionsOK As Boolean = True, Optional Delim As String = ",")
    Arr = fixInput(Arr)
    UDFPermutations = createOutput(createPermutations(Arr, RsltSize, RepetitionsOK, Delim))
    End Function
Public Function UDFCombinations(Arr, NbrItems As Integer, _
        Optional Delim As String = ",")
    UDFCombinations = UDFSubset(Arr, NbrItems, Delim)
    End Function

 

Myrna Larson has also shared code on this subject.  For her take on the subject, see http://groups.google.com/group/microsoft.public.excel.worksheet.functions/browse_frm/thread/8ac4a84b7df1ff97/5deaecfc5da1db8d 

For more on newsgroups see Outlook Express & Newsgroups