查找整数的不等分区的有效方法

时间:2012-04-07 12:09:23

标签: php algorithm integer combinatorics data-partitioning

我有一个整数的分区,我只想要那些所有值都不相等的分区。例如,3的分区是{1,1,1,1},{2,2},{3,1},{1,1,2}和{4}。因此,所需的不等分区是{3,1}和{4},因为它们不包含相等的元素。 我用于查找所有分区的代码如下所示。我可以过滤分区以获得所需的结果,但我想要一些有效的方法来查找所有分区,其中没有相同的术语,而没有找到所有分区。我搜索了网络和stackoverflow,但没有任何说明我面临的问题。每个想法都表示赞赏。感谢。

function total_partitions_of_a_number($n) {# base case of recursion: zero is the sum of the empty list
if(!$n) return array(array()); # return empty array

# modify partitions of n-1 to form partitions of n
foreach(total_partitions_of_a_number($n-1) as $p) { # recursive call
 $a[] = array_merge(array(1), $p); # "yield" array [1, p...]
 if($p && (count($p) < 2 || $p[1] > $p[0])) { # p not empty, and length < 2 or p[1] > p[0]
   ++$p[0]; # increment first item of p
   $a[] = $p; # "yield" p
 }
}
return $a; # return all "yielded" values at once
}

1 个答案:

答案 0 :(得分:2)

所以你只想要任何给定组件出现不超过一次的分区?递归很简单。

将其简化为求解N的分区的问题,使得集合中的元素不大于某个值a(a最初将为N.)现在,分区中出现或者不出现。根据这一点,您将递归地求解(N-a)的分区,使得没有元素大于a-1,并且对于N的分区,使得没有成员大于a-1。

在任何一种情况下,递归都很好,并且当不再可能解决问题时将终止,因此,当a *(a + 1)/ 2&lt; N.当然,当*(a + 1)/ 2 = N时,您也可以快速终止递归,因为解决方案是唯一的。