假设我们有一个包含几个子集的集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示例,我将不胜感激。
答案 0 :(得分:3)
听起来你正在寻找的是一组/数组的partitions。
这样做的一种方法是递归地:
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
答案 1 :(得分:1)
为什么不使用贪婪算法?
1)排序集S使用子集长度
下降
2)让我:= 0
3)将S [i]添加到解决方案中
4)找到S [j]其中j>我所包含的元素不在当前的解决方案中
5)如果你找不到4中描述的元素那么
5.a)明确的解决方案
5.b)增加i
5.c)如果我> | S |然后休息,找不到解决方案;(
5.d)转到3
修改强>
嗯,再读一遍你的帖子,得出你需要Best-First search的结论。您的问题实际上不是分区问题,因为您需要的内容也称为Change-making problem,但在后一种情况下,第一个解决方案被视为最佳解决方案 - 您实际上想要找到所有解决方案,这就是您的原因你应该采用最好的搜索策略方法吗?
答案 2 :(得分:0)
这似乎是一种经典的“回溯”练习。
答案 3 :(得分:0)
生成所有子集
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