Algorithm to generate spanning set

后端 未结 5 1822
粉色の甜心
粉色の甜心 2021-02-20 12:19

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]         


        
5条回答
  •  野性不改
    2021-02-20 12:57

    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;
        }
    

提交回复
热议问题