通过列表的分区,我的意思是列表元素的一组子集,使得任何不同的子集对的交集是空的,并且所有子集的并集等于原始列表。
例如,如果我的输入列表是{1,π,x}
,那么我想要一个返回
{ {{1},{π},{x}}, {{1,π},{x}}, {{1,x},{π}}, {{1},{x,π}}, {{1,π,x}} }
答案 0 :(得分:12)
使用http://mathforum.org/advanced/robertd/bell.html
中的改编代码BellList[1] = {Needs["Combinatorica`"]
comb = SetPartitions[{a, b, c, d, e}]
};
BellList[n_Integer?Positive] := Join @@
(ReplaceList[#,
{{b___, {S__}, a___} :> {b, {S, n}, a},
{S__} :> {S, {n}}}
] & /@ BellList[n - 1])
s = {a, b, c, d, e};
bell = BellList@Length@s /. n_Integer :> s[[n]]
或者,不出所料,Combinatorica包已经具有此功能(SetPartitions)!
Complement[bell, comb] == {}
Sort@bell == Sort@comb
(* Both of the above return True *)
检查它们是否都返回相同的结果(但顺序不同)
{{1}}
答案 1 :(得分:2)
我会从集合的Powerset开始(使用Subsets[x]
),然后过滤掉集合Union[x]
不是原始集合的那些。
有点慢,但我发现它很直观。