Home

A brief excursion in clique counting

note: all software on this page released under the MIT license

update 2017-05-18: an optimized version of the source is here.

update 2017-05-20: a parallel optimized version of the source in solution format is here. You can compile with mono from the command line with

mcs -platform:x64 -r:System.Numerics Program.cs

Imagine a question like, "Given a complete graph with n nodes, how many cliques of size k are there?"

I want to discuss two different specifics of this question, one with rotation, and the other with rotation and reflection.


The first case, up to isomorphism, is easily answered with the binomial coefficient, and given by C(n,k).

Now how do you count this? A recusive program is given in this stackoverflow answer.

Alternatively, there is also an iterative solution. Each iteration essentially asks, "what is the next smallest sum of k distinct powers of 2?" Or in binary, "what is the next number with only k bits set?"

Here is an algorithm I wrote in C#. A graph is represented by an array of size n; setting a value of the array is equivalent to choosing a node. For example, [1,1,0,1,0] is a graph of five nodes, with three nodes chosen for a clique.

    // returns true if an increment occurred, otherwise returns false.
    // modifies the input array in place.
    // This function is named "Increment" but there are several noted places in code that
    // can swap "0" and "1" to change this to decrement.
    public static bool Increment(int[] arr)
    {
        // There are two cases, the easy one and the hard one.
        // The easy case just shifts the first unset digit right.
        // The hard case is when the first unset digit is in the rightmost spot.

        /*
        example array of length 6 with 3 digits set, same as C(6,3)
        5   4   3   2   1   0    // index position in array
        ---------------------
        1   1   1   0   0   0    // Increment stops here
        1   1   0   1   0   0
        1   1   0   0   1   0
        1   1   0   0   0   1
        1   0   1   1   0   0
        1   0   1   0   1   0
        1   0   1   0   0   1
        1   0   0   1   1   0
        1   0   0   1   0   1
        1   0   0   0   1   1
        0   1   1   1   0   0
        0   1   1   0   1   0
        0   1   1   0   0   1
        0   1   0   1   1   0
        0   1   0   1   0   1
        0   1   0   0   1   1
        0   0   1   1   1   0
        0   0   1   1   0   1
        0   0   1   0   1   1
        0   0   0   1   1   1     // Increment starts here
        */

        int startPos = 0;
        int carry = 0;
        int index;

        // find the first digit that's set
        for (index = 0; index < arr.Length; index++)
        {
            if (arr[index] == 0) // toggle to change direction
            {
                startPos = index;
                break;
            }
        }

        // Easy case. The digit can be shifted.
        if (startPos > 0)
        {
            arr[startPos] = 1; // toggle to change direction
            arr[startPos - 1] = 0; // toggle to change direction
            return true;
        }

        // Else, the hard case. Flip and count the digits that need to be carried.
        for (index = startPos; index < arr.Length; index++)
        {
            if (arr[index] == 0) // toggle to change direction
            {
                arr[index] = 1; // toggle to change direction
                carry++;
            }
            else
            {
                break;
            }
        }

        // Travel down the array until it's possible to carry.
        for (index = carry + 1; index < arr.Length; index++)
        {
            if (arr[index] == 0) // toggle to change direction
            {
                startPos = index;
                break;
            }
        }

        // If the end of the array was reached, it's not possible to
        // do anything. (max value for increment or min value for decrement)
        if (index >= arr.Length)
        {
            return false;
        }

        // Flip the digits "supplying" the carry
        arr[startPos] = 1; // toggle to change direction
        arr[startPos - 1] = 0; // toggle to change direction

        // Flip the digits that are carried down.
        for (index = startPos - 2; carry > 0; carry--, index--)
        {
            arr[index] = 0; // toggle to change direction
        }

        return true;
    }

The total number of times an array can be incremented from the starting value should be the same as the binomial coefficient.

In order to answer the initial question, it's necessary to discount isomorphic graphs. That is, [1,1,1,0,0] and [1,1,0,0,1] and [0,1,1,1,0] are isomorphic and shouldn't be counted more than once.

I handle this by generating a "prime" id for each graph. An id is generated by treating each index of the array as a bit; the array is then interpretted as a binary integer. A "prime" id rotates the array through one full cycle and returns the minimum id that was found for each iteration of the rotation.

When an id is first encountered, it is stored. Each rotation of the array is also stored (as its id) in a collection called a family. If an id has been encountered before, this iteration of C(n,k) is skipped.

Here's my implementation in C#

    // returns all possible families. A family contains a list of 
    // isomorphic graphs, as defined by their prime id.
    public static List<List<UInt64>> FamilyCount(int nodes, int cliqueSize)
    {
        var nodeList = new int[nodes];
        var families = new List<List<UInt64>>();
        int currentFamily = 0;
        
        // is dictionary the right data structure since the only thing
        // that matters is whether the key exists? The value isn't read ...
        var seen = new Dictionary<UInt64, int>();

        for (int i = 0; i < cliqueSize; i++)
        {
            nodeList[i] = 1;
        }

        do
        {
            currentFamily = -1;

            // the array will be modified, so leave the original unchanged.
            var copy = (new List<int>(nodeList)).ToArray();

            // will contain list of all ids found
            var iterationFamily = new List<UInt64>();

            // get prime id to determine if that has been seen before.
            var id = GetId(copy);

            if (seen.ContainsKey(id) )
            {
                continue;
            }
            
            iterationFamily.Add(id);

            // this hasn't been seen before, so it must be a new family
            currentFamily = families.Count;
            families.Add(new List<UInt64>());

            seen.Add(id, currentFamily);

            for (int i = 0; i < nodes; i++)
            {
                RotateRight(copy);
                id = AsInt(copy);
                iterationFamily.Add(id);
            }

            iterationFamily.Sort();

            foreach (var item in iterationFamily)
            {
                if (!families[currentFamily].Contains(item))
                {
                    families[currentFamily].Add(item);
                }
            }

        } while (Increment(nodeList));

        return families;
    }

This is enough to build a program that iterates through C(n,k) up to n=20. You can find the complete source here

Results. Note that results are symmetric and the table is not extended for brevity.

F(x,1) F(x,2) F(x,3) F(x,4) F(x,5) F(x,6) F(x,7) F(x,8) F(x,9) F(x,10)
F(2,x) 1
F(3,x) 1 1
F(4,x) 1 2 1
F(5,x) 1 2 2 1
F(6,x) 1 3 4 3 1
F(7,x) 1 3 5 5 3 1
F(8,x) 1 4 7 10 7 4 1
F(9,x) 1 4 10 14 14 10 4 1
F(10,x) 1 5 12 22 26 22 12 5 1
F(11,x) 1 5 15 30 42 42 30 15 5 1
F(12,x) 1 6 19 43 66 80 66 43 19 6
F(13,x) 1 6 22 55 99 132 132 99 55 22
F(14,x) 1 7 26 73 143 217 246 217 143 73
F(15,x) 1 7 31 91 201 335 429 429 335 201
F(16,x) 1 8 35 116 273 504 715 810 715 504
F(17,x) 1 8 40 140 364 728 1144 1430 1430 1144
F(18,x) 1 9 46 172 476 1038 1768 2438 2704 2438
F(19,x) 1 9 51 204 612 1428 2652 3978 4862 4862

This is also th enumber of necklaces with k black beads and n-k white beads. See http://oeis.org/A047996.

Full output for n=2..40 in csv format is available here.

The program also counts the number of ids in each family. For instance, [0,1,0,1,0,1] generates a family with only two ids, even though it will be rotated six times. The statistics gathered are simply [number of ids by number of families with that many ids]. Summing the rightmost values in each row will give the same number as above. When n and k are coprime there is only one size of family. If n is prime, all families have the same number of ids.


FamilyCount(  4,  1): [  4x    1] 
FamilyCount(  4,  2): [  2x    1] [  4x    1] 
FamilyCount(  4,  3): [  4x    1] 

FamilyCount(  5,  1): [  5x    1] 
FamilyCount(  5,  2): [  5x    2] 
FamilyCount(  5,  3): [  5x    2] 
FamilyCount(  5,  4): [  5x    1]

FamilyCount(  6,  1): [  6x    1] 
FamilyCount(  6,  2): [  3x    1] [  6x    2] 
FamilyCount(  6,  3): [  2x    1] [  6x    3] 
FamilyCount(  6,  4): [  3x    1] [  6x    2] 
FamilyCount(  6,  5): [  6x    1] 

FamilyCount(  7,  1): [  7x    1] 
FamilyCount(  7,  2): [  7x    3] 
FamilyCount(  7,  3): [  7x    5] 
FamilyCount(  7,  4): [  7x    5] 
FamilyCount(  7,  5): [  7x    3] 
FamilyCount(  7,  6): [  7x    1] 

FamilyCount(  8,  1): [  8x    1] 
FamilyCount(  8,  2): [  4x    1] [  8x    3] 
FamilyCount(  8,  3): [  8x    7] 
FamilyCount(  8,  4): [  2x    1] [  4x    1] [  8x    8] 
FamilyCount(  8,  5): [  8x    7] 
FamilyCount(  8,  6): [  4x    1] [  8x    3] 
FamilyCount(  8,  7): [  8x    1] 

FamilyCount(  9,  1): [  9x    1] 
FamilyCount(  9,  2): [  9x    4] 
FamilyCount(  9,  3): [  3x    1] [  9x    9] 
FamilyCount(  9,  4): [  9x   14] 
FamilyCount(  9,  5): [  9x   14] 
FamilyCount(  9,  6): [  3x    1] [  9x    9] 
FamilyCount(  9,  7): [  9x    4] 
FamilyCount(  9,  8): [  9x    1] 

FamilyCount( 10,  1): [ 10x    1] 
FamilyCount( 10,  2): [  5x    1] [ 10x    4] 
FamilyCount( 10,  3): [ 10x   12] 
FamilyCount( 10,  4): [  5x    2] [ 10x   20] 
FamilyCount( 10,  5): [  2x    1] [ 10x   25] 
FamilyCount( 10,  6): [  5x    2] [ 10x   20] 
FamilyCount( 10,  7): [ 10x   12] 
FamilyCount( 10,  8): [  5x    1] [ 10x    4] 
FamilyCount( 10,  9): [ 10x    1] 

FamilyCount( 11,  1): [ 11x    1] 
FamilyCount( 11,  2): [ 11x    5] 
FamilyCount( 11,  3): [ 11x   15] 
FamilyCount( 11,  4): [ 11x   30] 
FamilyCount( 11,  5): [ 11x   42] 
FamilyCount( 11,  6): [ 11x   42] 
FamilyCount( 11,  7): [ 11x   30] 
FamilyCount( 11,  8): [ 11x   15] 
FamilyCount( 11,  9): [ 11x    5] 
FamilyCount( 11, 10): [ 11x    1] 

FamilyCount( 12,  1): [ 12x    1] 
FamilyCount( 12,  2): [  6x    1] [ 12x    5] 
FamilyCount( 12,  3): [  4x    1] [ 12x   18] 
FamilyCount( 12,  4): [  3x    1] [  6x    2] [ 12x   40] 
FamilyCount( 12,  5): [ 12x   66] 
FamilyCount( 12,  6): [  2x    1] [  4x    1] [  6x    3] [ 12x   75] 
FamilyCount( 12,  7): [ 12x   66] 
FamilyCount( 12,  8): [  3x    1] [  6x    2] [ 12x   40] 
FamilyCount( 12,  9): [  4x    1] [ 12x   18] 
FamilyCount( 12, 10): [  6x    1] [ 12x    5] 
FamilyCount( 12, 11): [ 12x    1] 

FamilyCount( 13,  1): [ 13x    1] 
FamilyCount( 13,  2): [ 13x    6] 
FamilyCount( 13,  3): [ 13x   22] 
FamilyCount( 13,  4): [ 13x   55] 
FamilyCount( 13,  5): [ 13x   99] 
FamilyCount( 13,  6): [ 13x  132] 
FamilyCount( 13,  7): [ 13x  132] 
FamilyCount( 13,  8): [ 13x   99] 
FamilyCount( 13,  9): [ 13x   55] 
FamilyCount( 13, 10): [ 13x   22] 
FamilyCount( 13, 11): [ 13x    6] 
FamilyCount( 13, 12): [ 13x    1] 

FamilyCount( 14,  1): [ 14x    1] 
FamilyCount( 14,  2): [  7x    1] [ 14x    6] 
FamilyCount( 14,  3): [ 14x   26] 
FamilyCount( 14,  4): [  7x    3] [ 14x   70] 
FamilyCount( 14,  5): [ 14x  143] 
FamilyCount( 14,  6): [  7x    5] [ 14x  212] 
FamilyCount( 14,  7): [  2x    1] [ 14x  245] 
FamilyCount( 14,  8): [  7x    5] [ 14x  212] 
FamilyCount( 14,  9): [ 14x  143] 
FamilyCount( 14, 10): [  7x    3] [ 14x   70] 
FamilyCount( 14, 11): [ 14x   26] 
FamilyCount( 14, 12): [  7x    1] [ 14x    6] 
FamilyCount( 14, 13): [ 14x    1] 

FamilyCount( 15,  1): [ 15x    1] 
FamilyCount( 15,  2): [ 15x    7] 
FamilyCount( 15,  3): [  5x    1] [ 15x   30] 
FamilyCount( 15,  4): [ 15x   91] 
FamilyCount( 15,  5): [  3x    1] [ 15x  200] 
FamilyCount( 15,  6): [  5x    2] [ 15x  333] 
FamilyCount( 15,  7): [ 15x  429] 
FamilyCount( 15,  8): [ 15x  429] 
FamilyCount( 15,  9): [  5x    2] [ 15x  333] 
FamilyCount( 15, 10): [  3x    1] [ 15x  200] 
FamilyCount( 15, 11): [ 15x   91] 
FamilyCount( 15, 12): [  5x    1] [ 15x   30] 
FamilyCount( 15, 13): [ 15x    7] 
FamilyCount( 15, 14): [ 15x    1] 

FamilyCount( 16,  1): [ 16x    1] 
FamilyCount( 16,  2): [  8x    1] [ 16x    7] 
FamilyCount( 16,  3): [ 16x   35] 
FamilyCount( 16,  4): [  4x    1] [  8x    3] [ 16x  112] 
FamilyCount( 16,  5): [ 16x  273] 
FamilyCount( 16,  6): [  8x    7] [ 16x  497] 
FamilyCount( 16,  7): [ 16x  715] 
FamilyCount( 16,  8): [  2x    1] [  4x    1] [  8x    8] [ 16x  800] 
FamilyCount( 16,  9): [ 16x  715] 
FamilyCount( 16, 10): [  8x    7] [ 16x  497] 
FamilyCount( 16, 11): [ 16x  273] 
FamilyCount( 16, 12): [  4x    1] [  8x    3] [ 16x  112] 
FamilyCount( 16, 13): [ 16x   35] 
FamilyCount( 16, 14): [  8x    1] [ 16x    7] 
FamilyCount( 16, 15): [ 16x    1] 

FamilyCount( 17,  1): [ 17x    1] 
FamilyCount( 17,  2): [ 17x    8] 
FamilyCount( 17,  3): [ 17x   40] 
FamilyCount( 17,  4): [ 17x  140] 
FamilyCount( 17,  5): [ 17x  364] 
FamilyCount( 17,  6): [ 17x  728] 
FamilyCount( 17,  7): [ 17x 1144] 
FamilyCount( 17,  8): [ 17x 1430] 
FamilyCount( 17,  9): [ 17x 1430] 
FamilyCount( 17, 10): [ 17x 1144] 
FamilyCount( 17, 11): [ 17x  728] 
FamilyCount( 17, 12): [ 17x  364] 
FamilyCount( 17, 13): [ 17x  140] 
FamilyCount( 17, 14): [ 17x   40] 
FamilyCount( 17, 15): [ 17x    8] 
FamilyCount( 17, 16): [ 17x    1] 

FamilyCount( 18,  1): [ 18x    1] 
FamilyCount( 18,  2): [  9x    1] [ 18x    8] 
FamilyCount( 18,  3): [  6x    1] [ 18x   45] 
FamilyCount( 18,  4): [  9x    4] [ 18x  168] 
FamilyCount( 18,  5): [ 18x  476] 
FamilyCount( 18,  6): [  3x    1] [  6x    2] [  9x    9] [ 18x 1026] 
FamilyCount( 18,  7): [ 18x 1768] 
FamilyCount( 18,  8): [  9x   14] [ 18x 2424] 
FamilyCount( 18,  9): [  2x    1] [  6x    3] [ 18x 2700] 
FamilyCount( 18, 10): [  9x   14] [ 18x 2424] 
FamilyCount( 18, 11): [ 18x 1768] 
FamilyCount( 18, 12): [  3x    1] [  6x    2] [  9x    9] [ 18x 1026] 
FamilyCount( 18, 13): [ 18x  476] 
FamilyCount( 18, 14): [  9x    4] [ 18x  168] 
FamilyCount( 18, 15): [  6x    1] [ 18x   45] 
FamilyCount( 18, 16): [  9x    1] [ 18x    8] 
FamilyCount( 18, 17): [ 18x    1] 

FamilyCount( 19,  1): [ 19x    1] 
FamilyCount( 19,  2): [ 19x    9] 
FamilyCount( 19,  3): [ 19x   51] 
FamilyCount( 19,  4): [ 19x  204] 
FamilyCount( 19,  5): [ 19x  612] 
FamilyCount( 19,  6): [ 19x 1428] 
FamilyCount( 19,  7): [ 19x 2652] 
FamilyCount( 19,  8): [ 19x 3978] 
FamilyCount( 19,  9): [ 19x 4862] 
FamilyCount( 19, 10): [ 19x 4862] 
FamilyCount( 19, 11): [ 19x 3978] 
FamilyCount( 19, 12): [ 19x 2652] 
FamilyCount( 19, 13): [ 19x 1428] 
FamilyCount( 19, 14): [ 19x  612] 
FamilyCount( 19, 15): [ 19x  204] 
FamilyCount( 19, 16): [ 19x   51] 
FamilyCount( 19, 17): [ 19x    9] 
FamilyCount( 19, 18): [ 19x    1] 


Now for the other part of the question -- what if a graph reflection is treated the same as a rotation? The above program is simply modified to also reverse the array and look for its prime id as well. While iterating through possible cliques, each rotation is also reversed. These are then treated as being in the same family. You can find the complete source code here. Run time is about twice as long as above.

Results. Note that results are symmetric and the table is not extended for brevity.

F(x,1) F(x,2) F(x,3) F(x,4) F(x,5) F(x,6) F(x,7) F(x,8) F(x,9) F(x,10)
F(2,x) 1
F(3,x) 1 1
F(4,x) 1 2 1
F(5,x) 1 2 2 1
F(6,x) 1 3 3 3 1
F(7,x) 1 3 4 4 3 1
F(8,x) 1 4 5 8 5 4 1
F(9,x) 1 4 7 10 10 7 4 1
F(10,x) 1 5 8 16 16 16 8 5 1
F(11,x) 1 5 10 20 26 26 20 10 5 1
F(12,x) 1 6 12 29 38 50 38 29 12 6
F(13,x) 1 6 14 35 57 76 76 57 35 14
F(14,x) 1 7 16 47 79 126 133 126 79 47
F(15,x) 1 7 19 56 111 185 232 232 185 111
F(16,x) 1 8 21 72 147 280 375 440 375 280
F(17,x) 1 8 24 84 196 392 600 750 750 600
F(18,x) 1 9 27 104 252 561 912 1282 1387 1282
F(19,x) 1 9 30 120 324 756 1368 2052 2494 2494

This is sequence https://oeis.org/A052307.

Full output for n=2..40 in csv format is available here.

The family breakdown is a bit different than above.

FamilyCount(  2,  1): [  2x    1]

FamilyCount(  3,  1): [  3x    1] 
FamilyCount(  3,  2): [  3x    1] 

FamilyCount(  4,  1): [  4x    1] 
FamilyCount(  4,  2): [  2x    1] [  4x    1] 
FamilyCount(  4,  3): [  4x    1] 

FamilyCount(  5,  1): [  5x    1] 
FamilyCount(  5,  2): [  5x    2] 
FamilyCount(  5,  3): [  5x    2] 
FamilyCount(  5,  4): [  5x    1] 

FamilyCount(  6,  1): [  6x    1] 
FamilyCount(  6,  2): [  3x    1] [  6x    2] 
FamilyCount(  6,  3): [  2x    1] [  6x    1] [ 12x    1] 
FamilyCount(  6,  4): [  3x    1] [  6x    2] 
FamilyCount(  6,  5): [  6x    1] 

FamilyCount(  7,  1): [  7x    1] 
FamilyCount(  7,  2): [  7x    3] 
FamilyCount(  7,  3): [  7x    3] [ 14x    1] 
FamilyCount(  7,  4): [  7x    3] [ 14x    1] 
FamilyCount(  7,  5): [  7x    3] 
FamilyCount(  7,  6): [  7x    1] 

FamilyCount(  8,  1): [  8x    1] 
FamilyCount(  8,  2): [  4x    1] [  8x    3] 
FamilyCount(  8,  3): [  8x    3] [ 16x    2] 
FamilyCount(  8,  4): [  2x    1] [  4x    1] [  8x    4] [ 16x    2] 
FamilyCount(  8,  5): [  8x    3] [ 16x    2] 
FamilyCount(  8,  6): [  4x    1] [  8x    3] 
FamilyCount(  8,  7): [  8x    1] 

FamilyCount(  9,  1): [  9x    1] 
FamilyCount(  9,  2): [  9x    4] 
FamilyCount(  9,  3): [  3x    1] [  9x    3] [ 18x    3] 
FamilyCount(  9,  4): [  9x    6] [ 18x    4] 
FamilyCount(  9,  5): [  9x    6] [ 18x    4] 
FamilyCount(  9,  6): [  3x    1] [  9x    3] [ 18x    3] 
FamilyCount(  9,  7): [  9x    4] 
FamilyCount(  9,  8): [  9x    1] 

FamilyCount( 10,  1): [ 10x    1] 
FamilyCount( 10,  2): [  5x    1] [ 10x    4] 
FamilyCount( 10,  3): [ 10x    4] [ 20x    4] 
FamilyCount( 10,  4): [  5x    2] [ 10x    8] [ 20x    6] 
FamilyCount( 10,  5): [  2x    1] [ 10x    5] [ 20x   10] 
FamilyCount( 10,  6): [  5x    2] [ 10x    8] [ 20x    6] 
FamilyCount( 10,  7): [ 10x    4] [ 20x    4] 
FamilyCount( 10,  8): [  5x    1] [ 10x    4] 
FamilyCount( 10,  9): [ 10x    1] 

FamilyCount( 11,  1): [ 11x    1] 
FamilyCount( 11,  2): [ 11x    5] 
FamilyCount( 11,  3): [ 11x    5] [ 22x    5] 
FamilyCount( 11,  4): [ 11x   10] [ 22x   10] 
FamilyCount( 11,  5): [ 11x   10] [ 22x   16] 
FamilyCount( 11,  6): [ 11x   10] [ 22x   16] 
FamilyCount( 11,  7): [ 11x   10] [ 22x   10] 
FamilyCount( 11,  8): [ 11x    5] [ 22x    5] 
FamilyCount( 11,  9): [ 11x    5] 
FamilyCount( 11, 10): [ 11x    1] 

FamilyCount( 12,  1): [ 12x    1] 
FamilyCount( 12,  2): [  6x    1] [ 12x    5] 
FamilyCount( 12,  3): [  4x    1] [ 12x    4] [ 24x    7] 
FamilyCount( 12,  4): [  3x    1] [  6x    2] [ 12x   12] [ 24x   14] 
FamilyCount( 12,  5): [ 12x   10] [ 24x   28] 
FamilyCount( 12,  6): [  2x    1] [  4x    1] [  6x    1] [ 12x   18] [ 24x   29] 
FamilyCount( 12,  7): [ 12x   10] [ 24x   28] 
FamilyCount( 12,  8): [  3x    1] [  6x    2] [ 12x   12] [ 24x   14] 
FamilyCount( 12,  9): [  4x    1] [ 12x    4] [ 24x    7] 
FamilyCount( 12, 10): [  6x    1] [ 12x    5] 
FamilyCount( 12, 11): [ 12x    1] 

FamilyCount( 13,  1): [ 13x    1] 
FamilyCount( 13,  2): [ 13x    6] 
FamilyCount( 13,  3): [ 13x    6] [ 26x    8] 
FamilyCount( 13,  4): [ 13x   15] [ 26x   20] 
FamilyCount( 13,  5): [ 13x   15] [ 26x   42] 
FamilyCount( 13,  6): [ 13x   20] [ 26x   56] 
FamilyCount( 13,  7): [ 13x   20] [ 26x   56] 
FamilyCount( 13,  8): [ 13x   15] [ 26x   42] 
FamilyCount( 13,  9): [ 13x   15] [ 26x   20] 
FamilyCount( 13, 10): [ 13x    6] [ 26x    8] 
FamilyCount( 13, 11): [ 13x    6] 
FamilyCount( 13, 12): [ 13x    1] 

FamilyCount( 14,  1): [ 14x    1] 
FamilyCount( 14,  2): [  7x    1] [ 14x    6] 
FamilyCount( 14,  3): [ 14x    6] [ 28x   10] 
FamilyCount( 14,  4): [  7x    3] [ 14x   18] [ 28x   26] 
FamilyCount( 14,  5): [ 14x   15] [ 28x   64] 
FamilyCount( 14,  6): [  7x    3] [ 14x   33] [ 28x   90] 
FamilyCount( 14,  7): [  2x    1] [ 14x   19] [ 28x  113] 
FamilyCount( 14,  8): [  7x    3] [ 14x   33] [ 28x   90] 
FamilyCount( 14,  9): [ 14x   15] [ 28x   64] 
FamilyCount( 14, 10): [  7x    3] [ 14x   18] [ 28x   26] 
FamilyCount( 14, 11): [ 14x    6] [ 28x   10] 
FamilyCount( 14, 12): [  7x    1] [ 14x    6] 
FamilyCount( 14, 13): [ 14x    1] 

FamilyCount( 15,  1): [ 15x    1] 
FamilyCount( 15,  2): [ 15x    7] 
FamilyCount( 15,  3): [  5x    1] [ 15x    6] [ 30x   12] 
FamilyCount( 15,  4): [ 15x   21] [ 30x   35] 
FamilyCount( 15,  5): [  3x    1] [ 15x   20] [ 30x   90] 
FamilyCount( 15,  6): [  5x    2] [ 15x   33] [ 30x  150] 
FamilyCount( 15,  7): [ 15x   35] [ 30x  197] 
FamilyCount( 15,  8): [ 15x   35] [ 30x  197] 
FamilyCount( 15,  9): [  5x    2] [ 15x   33] [ 30x  150] 
FamilyCount( 15, 10): [  3x    1] [ 15x   20] [ 30x   90] 
FamilyCount( 15, 11): [ 15x   21] [ 30x   35] 
FamilyCount( 15, 12): [  5x    1] [ 15x    6] [ 30x   12] 
FamilyCount( 15, 13): [ 15x    7] 
FamilyCount( 15, 14): [ 15x    1] 

FamilyCount( 16,  1): [ 16x    1] 
FamilyCount( 16,  2): [  8x    1] [ 16x    7] 
FamilyCount( 16,  3): [ 16x    7] [ 32x   14] 
FamilyCount( 16,  4): [  4x    1] [  8x    3] [ 16x   24] [ 32x   44] 
FamilyCount( 16,  5): [ 16x   21] [ 32x  126] 
FamilyCount( 16,  6): [  8x    3] [ 16x   55] [ 32x  222] 
FamilyCount( 16,  7): [ 16x   35] [ 32x  340] 
FamilyCount( 16,  8): [  2x    1] [  4x    1] [  8x    4] [ 16x   66] [ 32x  368] 
FamilyCount( 16,  9): [ 16x   35] [ 32x  340] 
FamilyCount( 16, 10): [  8x    3] [ 16x   55] [ 32x  222] 
FamilyCount( 16, 11): [ 16x   21] [ 32x  126] 
FamilyCount( 16, 12): [  4x    1] [  8x    3] [ 16x   24] [ 32x   44] 
FamilyCount( 16, 13): [ 16x    7] [ 32x   14] 
FamilyCount( 16, 14): [  8x    1] [ 16x    7] 
FamilyCount( 16, 15): [ 16x    1] 

FamilyCount( 17,  1): [ 17x    1] 
FamilyCount( 17,  2): [ 17x    8] 
FamilyCount( 17,  3): [ 17x    8] [ 34x   16] 
FamilyCount( 17,  4): [ 17x   28] [ 34x   56] 
FamilyCount( 17,  5): [ 17x   28] [ 34x  168] 
FamilyCount( 17,  6): [ 17x   56] [ 34x  336] 
FamilyCount( 17,  7): [ 17x   56] [ 34x  544] 
FamilyCount( 17,  8): [ 17x   70] [ 34x  680] 
FamilyCount( 17,  9): [ 17x   70] [ 34x  680] 
FamilyCount( 17, 10): [ 17x   56] [ 34x  544] 
FamilyCount( 17, 11): [ 17x   56] [ 34x  336] 
FamilyCount( 17, 12): [ 17x   28] [ 34x  168] 
FamilyCount( 17, 13): [ 17x   28] [ 34x   56] 
FamilyCount( 17, 14): [ 17x    8] [ 34x   16] 
FamilyCount( 17, 15): [ 17x    8] 
FamilyCount( 17, 16): [ 17x    1] 

FamilyCount( 18,  1): [ 18x    1] 
FamilyCount( 18,  2): [  9x    1] [ 18x    8] 
FamilyCount( 18,  3): [  6x    1] [ 18x    7] [ 36x   19] 
FamilyCount( 18,  4): [  9x    4] [ 18x   32] [ 36x   68] 
FamilyCount( 18,  5): [ 18x   28] [ 36x  224] 
FamilyCount( 18,  6): [  3x    1] [  6x    2] [  9x    3] [ 18x   81] [ 36x  474] 
FamilyCount( 18,  7): [ 18x   56] [ 36x  856] 
FamilyCount( 18,  8): [  9x    6] [ 18x  124] [ 36x 1152] 
FamilyCount( 18,  9): [  2x    1] [  6x    1] [ 12x    1] [ 18x   68] [ 36x 1316] 
FamilyCount( 18, 10): [  9x    6] [ 18x  124] [ 36x 1152] 
FamilyCount( 18, 11): [ 18x   56] [ 36x  856] 
FamilyCount( 18, 12): [  3x    1] [  6x    2] [  9x    3] [ 18x   81] [ 36x  474] 
FamilyCount( 18, 13): [ 18x   28] [ 36x  224] 
FamilyCount( 18, 14): [  9x    4] [ 18x   32] [ 36x   68] 
FamilyCount( 18, 15): [  6x    1] [ 18x    7] [ 36x   19] 
FamilyCount( 18, 16): [  9x    1] [ 18x    8] 
FamilyCount( 18, 17): [ 18x    1] 

FamilyCount( 19,  1): [ 19x    1] 
FamilyCount( 19,  2): [ 19x    9] 
FamilyCount( 19,  3): [ 19x    9] [ 38x   21] 
FamilyCount( 19,  4): [ 19x   36] [ 38x   84] 
FamilyCount( 19,  5): [ 19x   36] [ 38x  288] 
FamilyCount( 19,  6): [ 19x   84] [ 38x  672] 
FamilyCount( 19,  7): [ 19x   84] [ 38x 1284] 
FamilyCount( 19,  8): [ 19x  126] [ 38x 1926] 
FamilyCount( 19,  9): [ 19x  126] [ 38x 2368] 
FamilyCount( 19, 10): [ 19x  126] [ 38x 2368] 
FamilyCount( 19, 11): [ 19x  126] [ 38x 1926] 
FamilyCount( 19, 12): [ 19x   84] [ 38x 1284] 
FamilyCount( 19, 13): [ 19x   84] [ 38x  672] 
FamilyCount( 19, 14): [ 19x   36] [ 38x  288] 
FamilyCount( 19, 15): [ 19x   36] [ 38x   84] 
FamilyCount( 19, 16): [ 19x    9] [ 38x   21] 
FamilyCount( 19, 17): [ 19x    9] 
FamilyCount( 19, 18): [ 19x    1]