Given this input: [1,2,3,4]
I\'d like to generate the set of spanning sets:
[1] [2] [3] [4]
[1] [2] [3,4]
[1] [2,3] [4]
[1] [3] [2,4]
[1,2] [3] [4]
[1,3]
I think the following method is the best way to generate them for the euler problem, as you can replace the return value with the number of prime spanning subsets, and it will be trivial to do the multiplication (especially with memoization):
GenerateSubsets(list)
partitions = { x | x is subset of list and x contains the lowest element of list }
foreach (parition in partitions)
if set == list
yield { partition }
else
yield { partition } x GenerateSubsets(list - part)
The key part is to make sure that the recursive side always has the leftmost element, this way, you don't get duplicates.
I have some messy C# code that does this:
IEnumerable>> GenerateSubsets(List list)
{
int p = (1 << (list.Count)) - 2;
List lhs = new List();
List rhs = new List();
while (p >= 0)
{
for (int i = 0; i < list.Count; i++)
if ((p & (1 << i)) == 0)
lhs.Add(list[i]);
else
rhs.Add(list[i]);
if (rhs.Count > 0)
foreach (var rhsSubset in GenerateSubsets(rhs))
yield return Combine(lhs, rhsSubset);
else
yield return Combine(lhs, null);
lhs.Clear();
rhs.Clear();
p -= 2;
}
}
IEnumerable> Combine(List list, IEnumerable> rest)
{
yield return list;
if (rest != null)
foreach (List x in rest)
yield return x;
}