Algorithm 什么算法可以计算给定集合的幂集?

Algorithm 什么算法可以计算给定集合的幂集?,algorithm,powerset,superset,Algorithm,Powerset,Superset,我希望根据起始数字列表有效地生成数字组合的唯一列表 示例startlist=[1,2,3,4,5]但是算法应该适用于[1,2,3…n] result = [1],[2],[3],[4],[5] [1,2],[1,3],[1,4],[1,5] [1,2,3],[1,2,4],[1,2,5] [1,3,4],[1,3,5],[1,4,5] [2,3],[2,4],[2,5] [2,3,4],[2,3,5] [3,4],[3,5] [3,4,5] [4,5] 注意。我不想要重复的组合,尽管我可以

我希望根据起始数字列表有效地生成数字组合的唯一列表

示例start
list=[1,2,3,4,5]
但是算法应该适用于
[1,2,3…n]

result = 

[1],[2],[3],[4],[5]
[1,2],[1,3],[1,4],[1,5]
[1,2,3],[1,2,4],[1,2,5]
[1,3,4],[1,3,5],[1,4,5]
[2,3],[2,4],[2,5]
[2,3,4],[2,3,5]
[3,4],[3,5]
[3,4,5]
[4,5]

注意。我不想要重复的组合,尽管我可以接受它们,例如在上面的示例中,我并不真正需要组合[1,3,2],因为它已经以[1,2,3]的形式出现了。

您所要求的东西有一个名称。它叫“世界杯”

谷歌搜索“幂集算法”让我想到了这一点

Ruby算法
def动力集!(套)
如果set.empty,是否返回[set]?
p=set.pop
子集=功率集!(套)
子集| subset.map{| x | x |[p]}
结束
幂集直觉 如果S=(a、b、c),则功率集是所有子集的集合 功率集={(),(a),(b),(c),(a,b),(a,c),(b,c),(a,b,c)}

第一个“技巧”是尝试递归地定义

什么是停止状态

S=()具有什么功率集

怎样才能做到这一点

将集合减少一个元素

考虑取出一个元素-在上面的示例中,取出{c}

S=(a,b)然后幂集(S)={(),(a),(b),(a,b)}

少了什么

功率集={(c)、(a,c)、(b,c)、(a,b,c)}

注意到相似之处了吗?再看看

功率集={(),(a),(b),(c),(a,b),(a,c),(b,c),(a,b,c)}

去掉任何元素

功率集={(),(a),(b),(c),(a,b),(a,c),(b,c),(a,b,c)}is

powerset(S-{c})={(),(a),(b),(a,b)}与联合

{c} U幂集(S-{c})={(c)、(a,c)、(b,c)、(a,b,c)}

powerset(S)=powerset(S-{ei})U({ei}U powerset(S-{ei}))

其中ei是S(单态)的一个元素

伪算法
  • 这台电视机是空的吗?完成(注意{}的幂集是{{})
  • 如果不是,则取出一个元素
    • 对集合的其余部分递归调用方法
    • 返回由以下项的并集组成的集:
    • 不带元素的集合的功率集(来自递归调用)
    • 同一组(即2.1),但其中的每个元素都与最初取出的元素联合

  • 只需将
    0
    计数到
    2^n-1
    并根据计数的二进制表示形式打印数字。
    1
    表示您打印该数字,
    0
    表示您不打印该数字。例如:

    set is {1, 2, 3, 4, 5}
    count from 0 to 31:
    count = 00000 => print {}
    count = 00001 => print {1} (or 5, the order in which you do it really shouldn't matter)
    count = 00010 => print {2}
            00011 => print {1, 2}
            00100 => print {3}
            00101 => print {1, 3}
            00110 => print {2, 3}
            00111 => print {1, 2, 3}
            ...
            11111 => print {1, 2, 3, 4, 5}
    

    与hobodave的答案相同,但迭代更快(在Ruby中)。它还适用于
    数组
    集合

    def Powerset(set)
        ret = set.class[set.class[]]
        set.each do |s|
            deepcopy = ret.map { |x| set.class.new(x) }
            deepcopy.map { |r| r << s }
            ret = ret + deepcopy
        end
        return ret
    end
    
    def动力装置(设置)
    ret=set.class[set.class[]
    每件事|
    deepcopy=ret.map{| x | set.class.new(x)}
    deepcopy.map{| r | r来自OP的评论(复制编辑):

    这个例子是我实际操作的简化形式。数字是具有属性“Qty”的对象,我想对每个可能的组合的数量求和,然后选择使用数量之和
    N
    在某些其他边界内的大多数对象的组合,例如
    x

    你所面临的是一个优化问题。你所假设的是,解决这个优化问题的正确方法是将它分解为一个枚举问题(这是你所要求的),然后是一个过滤问题(你大概知道怎么做)

    你还没有意识到的是,这种解决方案只适用于(a)理论分析,或(b)非常小的
    n
    值。你要求的枚举是
    n
    中的指数,这意味着你最终得到的结果在实践中运行时间太长


    因此,找出如何提出您的优化问题,写一个新问题,并编辑此问题以指向它。

    递归和迭代解决方案,以计算方案中的功率集。但尚未完全测试

    (define (power_set set)
          (cond 
            ((empty? set) (list '()))
            (else
             (let ((part_res (power_set (cdr set))))
               (append (map (lambda (s) (cons (car set) s)) part_res) part_res)))))
    
    (define (power_set_iter set)
      (let loop ((res '(())) (s set))
        (if (empty? s)
            res
            (loop (append (map (lambda (i) (cons (car s) i)) res) res) (cdr s)))))
    
    下面是一个递归解决方案,它类似于已经发布的解决方案。 我没有设法使用“set”Python类型来表示集合集。Python在尝试像“s.add(set())”这样的表达式时说“集合对象是不可损坏的”

    另请参见

    def generatePowerSet(s,niceSorting=True):
    “”“生成给定集的电源集。”。
    实现了给定的集合以及集合的返回集合
    作为列表。
    “niceSorting”选项通过增加子集大小对功率集进行排序。
    """
    导入副本
    def setCmp(a、b):
    “”“比较两个集合(实现为列表)以获得良好的排序”“”
    如果len(a)len(b):
    返回1
    其他:
    如果len(a)==0:
    返回0
    其他:
    如果ab:
    返回1
    其他:
    返回0
    #将集合“s”的电源集合“ps”初始化为空集合
    ps=列表()
    如果len=0:
    ps.append(list())
    其他:
    #生成“psx”:sx的功率集,
    #它是“s”,没有选择的元素“x”
    sx=复制。复制(s)
    x=sx.pop()
    psx=发电机功率集(sx,False)
    #包括“psx”到“ps”
    ps.extend(psx)
    #将包含“x”的任何集合包括在“ps”中
    #通过将“x”添加到“sx”的任何子集,可获得此类包含集
    对于psx中的y:
    yx=复制。复制(y)
    yx.追加(x)
    ps.append(yx)
    如果需要排序:
    ps.sort(cmp=setCmp)
    返回ps
    断言generatePowerSet([])=[[]]
    断言generatePowerSet(['a'])==[[],['a']]
    断言generatePowerSet(['a',b'])==[[],['a'],['b'],['a',b']]
    断言generatePowerSet(['a','b','c']
    
    def generatePowerSet(s, niceSorting = True):
        """Generate power set of a given set.
    
        The given set, as well as, return set of sets, are implemented
        as lists.
    
        "niceSorting" optionnaly sorts the powerset by increasing subset size.
        """
        import copy
    
        def setCmp(a,b):
            """Compare two sets (implemented as lists) for nice sorting"""
            if len(a) < len(b):
                return -1
            elif len(a) > len(b):
                return 1
            else:
                if len(a) == 0:
                    return 0
                else:
                    if a < b:
                        return -1
                    elif a > b:
                        return 1
                    else:
                        return 0
    
        # Initialize the power set "ps" of set "s" as an empty set                    
        ps = list()
    
        if len(s) == 0:
            ps.append(list())
        else:
    
            # Generate "psx": the power set of "sx", 
            # which is "s" without a chosen element "x"
            sx = copy.copy(s)
            x = sx.pop()
            psx = generatePowerSet(sx, False)        
    
            # Include "psx" to "ps"      
            ps.extend(psx)
    
            # Include to "ps" any set, which contains "x"
            # Such included sets are obtained by adding "x" to any subset of "sx"
            for y in psx:
                yx = copy.copy(y)
                yx.append(x)
                ps.append(yx)
    
        if niceSorting:
            ps.sort(cmp=setCmp)      
    
        return ps
    
    assert generatePowerSet([]) == [[]]
    
    assert generatePowerSet(['a']) == [[], ['a']]
    
    assert generatePowerSet(['a', 'b']) == [[], ['a'], ['b'], ['a', 'b']]
    
    assert generatePowerSet(['a', 'b','c']) == [[], 
                                                ['a'], ['b'], ['c'], 
                                                ['a', 'b'], ['a', 'c'], ['b', 'c'],
                                                ['a', 'b', 'c'] ]
    
    assert generatePowerSet(['a', 'b','c'], False) == [ [], 
                                                        ['a'], 
                                                        ['b'], 
                                                        ['a', 'b'], 
                                                        ['c'], 
                                                        ['a', 'c'], 
                                                        ['b', 'c'], 
                                                        ['a', 'b', 'c'] ]
    
    print generatePowerSet(range(4), True)
    
    def power(a)
     (0..a.size).map {|x| a.combination(x).to_a}.flatten(1)
    end