我怎样才能找到给定列表的分区?

时间:2012-12-12 23:35:04

标签: algorithm recursion sml ml partition-problem

如何找到整数列表的所有分区?我需要使用递归的算法,因为我将在SML中实现它。我需要算法,我会自己做编码。我错误地编写了用于查找子集的代码,而且我没有太多时间用于此

SML有点类似pascal所以你得到格式的悬念我会用factorial写的例如就像这个有趣的fuc x =如果x< 0然后0如果x = 1则其他x其他x *(fac x- 1)

提前致谢

4 个答案:

答案 0 :(得分:1)

The partition problem是一个已知的NP-Hard问题(因此没有已知的多项式解决方案),可以使用穷举搜索来解决,该搜索很好地用递归编写。

伪代码(尝试做类似ML的伪代码,希望它有帮助和明确):

partition([],A,B): #base clause
   if (sum(A) == sum(B)):
        print (A,B) # this is a partition
partition(list, A,B):
   e <- head(list)
   partition(tail(list),e :: A,B)
   partition(tail(list),A, e :: B)

(如果我没记错e :: A正在ML中添加一个元素到A的开头,如果我记得错误,请随时纠正它。

答案 1 :(得分:1)

查看finding all the subsets。基本上在每个排列迭代中,您可以通过从当前子集的并集中减去整个集合来获得分区的其他部分。

答案 2 :(得分:1)

如果你有一组S {S1,...,Sn}的k分区,比如{P1,...,Pk},你可以生成kS ⋃ {Sn+1} k分区:{ / p> 在{1 ... k}

{P1,..., Pi-1, Pi ⋃ {n+1}, Pi+1,... Pk}

i

加上(k + 1) - 分区P ⋃ {k+1}

将这些分区称为P。很容易证明从{1,...,n}的两个不同分区生成的所有分区集都是不相交的,并且{1,...,n+1}的每个分区都是从{1,...,n}的某个分区生成的。

我认为这足以使问题的递归解决方案显而易见。

为了验证,{1,...,n}的分区数是B(n),其中B是贝尔号,(Sloane A000110)< / p>

答案 3 :(得分:1)

从您对amit的回复来看,您似乎在寻找:

fun partitions [] = []
  | partitions [x] = [[[x]]]
  | partitions (x::xs) =
    let
       val zsss = partitions xs
    in
       map (fn zss => [x]::zss) zsss @
       map (fn zs::zss => (x::zs)::zss) zsss
    end

修改:抱歉,我误解了您之前的示例partition [1,2,3] = [[[1,2,3]],[[1],[2,3]],[[1,2],[3]],[[1],[2],[3]]],即有序分区。

以下是您实际问题的解决方案(我认为):

fun extensions x [] = []
  | extensions x (xs::xss) =
    ((x::xs)::xss) :: map (fn zss => xs::zss) (extensions x xss)

fun partitions [] = [[]]
  | partitions (x::xs) =
    List.concat (map (fn zss => ([x]::zss) :: extensions x zss) (partitions xs))