Ruby “生成全部”;独特的;集合的子集(非功率集)

Ruby “生成全部”;独特的;集合的子集(非功率集),ruby,erlang,set,subset,powerset,Ruby,Erlang,Set,Subset,Powerset,假设我们有一个集合s,其中包含几个子集: - [a,b,c] - [a,b] - [c] - [d,e,f] - [d,f] - [e] 我们还假设s包含六个唯一的元素:a、b、c、d、e和f 我们如何才能找到所有可能的S子集,这些子集包含S的每个唯一元素,并且只包含一次 函数/方法的结果应如下所示: [[a,b,c],[d,e,f] [[a,b,c],[d,f],[e] [[a,b],[c],[d,e,f] [[a,b],[c],[d,f],[e]. 是否有任何最佳实践或标准方法来实现这一点

假设我们有一个集合
s
,其中包含几个子集:

- [a,b,c]
- [a,b]
- [c]
- [d,e,f]
- [d,f]
- [e]
我们还假设s包含六个唯一的元素:
a、b、c、d、e
f

我们如何才能找到所有可能的
S
子集,这些子集包含
S
的每个唯一元素,并且只包含一次

函数/方法的结果应如下所示:

  • [[a,b,c],[d,e,f]
  • [[a,b,c],[d,f],[e]
  • [[a,b],[c],[d,e,f]
  • [[a,b],[c],[d,f],[e].
  • 是否有任何最佳实践或标准方法来实现这一点


    如果有一个伪代码,Ruby或Erlang示例,我将不胜感激。

    为什么不使用贪婪算法

    1) 使用子集长度对集合S进行降序排序
    2) 设i:=0
    3) 将S[i]添加到解决方案中
    4) 查找S[j],其中j>i,例如它包含的元素不在当前解决方案中
    5) 如果找不到4中描述的元素,则
    5.a)清晰的解决方案
    5.b)增加i
    5.c)如果i>S,则断开,未找到解决方案;( 5.d)转到3

    编辑
    嗯,再看一次你的帖子,得出结论,你需要一份工作。你的问题实际上不是一个划分问题,因为你需要的也被称为划分问题,但在后一种情况下,第一个解决方案被认为是最好的——你实际上想要找到所有的解决方案,这就是为什么你应该选择最好的第一个搜索策略的原因。

    这看起来像是一个经典的“回溯”练习

    • #1:将您的集合相互排序,这样回溯将不会给出两次解决方案
    • #2:当前集合=[],集合集合列表=[]
    • #3:循环遍历所有顺序标记低于集合列表中最后一个顺序标记的集合(如果集合列表为空,则为全部)。让我们把它称为set_at_hand
    • #4:如果手上的集合与当前集合没有交集
    • #4/true/1:将其合并到当前集合,同时添加到集合集合列表
    • #4/true/2:当前_集是否完成?true:将set_列表添加到正确解决方案列表中。false:递归到#3
    • #4/true/3:从当前集合和集合列表中删除手头的集合集合
    • #5:循环结束
    • #6:返回

    听起来你要找的是一个集合/阵列的集合

    执行此操作的一种方法是递归:

    • 一个1元素数组[x]只有一个分区
    • 如果x是一个形式为x=[head]+tail的数组,那么x的分区是通过获取tail的每个分区并向每个可能的分区添加head来生成的。例如,如果我们正在生成[3,2,1]的分区,那么从[2,1]的分区[[2,1]]我们可以将3添加到[2,1]中,或者作为一个单独的元素,这将为我们提供[1,2,3]所拥有的5个分区中的2个分区[[3,2,1]或[[2,1],[3]]
    ruby实现看起来有点像

    def partitions(x)
      if x.length == 1
       [[x]]
      else
        head, tail = x[0], x[1, x.length-1]
        partitions(tail).inject([]) do |result, tail_partition|
          result + partitions_by_adding_element(tail_partition, head)
        end
      end
    end
    
    def partitions_by_adding_element(partition, element)
      (0..partition.length).collect do |index_to_add_at|
        new_partition = partition.dup
        new_partition[index_to_add_at] = (new_partition[index_to_add_at] || []) + [element]
        new_partition
      end
    end
    
    生成所有子集

    def allSubsets set
        combs=2**set.length
        subsets=[]
        for i in (0..combs) do
            subset=[]
            0.upto(set.length-1){|j| subset<<set[j] if i&(1<<j)!=0}
            subsets<<subset
        end
        subsets
    end
    
    def所有子集集
    梳子=2**套长
    子集=[]
    因为我在(0..combs)做什么
    子集=[]
    0.upto(set.length-1){| j |子集看看这里:

    这是我为查找数组的幂函数集而构建的一个简单算法。

    效果很好!但我发现它对于任何等于或大于10个项都会挂起。知道为什么吗?运行分区([1,2,3,4,5,6,7,8,9,10])挂起Rubyth所涉及的集合很快就会变大-一个10项数组有115975个分区,但在我的机器上只花了几秒钟。如果你在irb中运行这个,那么它会尝试显示结果-这不是一个好主意!它实际上挂起在rails s中,在RubyMine的rspec下运行。我在Mac上运行Lion。我的这个问题实际上比这个更专业,所以我把它贴在这里: