产生n或k以下的所有n组分

时间:2015-02-12 01:31:31

标签: java algorithm

我需要计算一个非常奇怪的函数,我在java中有一个复杂的递归。在递归的某个时刻,我需要使用n的每个成分进行一些计算,使用k或更少的部分。

换句话说,我需要能够准确地获取每个合成一次并存储它,以便我可以对它进行一些操作,从中获取一个数字,将其添加到计数器然后继续下一个作文。我正在使用java,你知道我该怎么做吗?

作为一个例子,考虑一种算法,该算法在查看大小为k的所有n个组合时计算大小为5的部分的次数。

2 个答案:

答案 0 :(得分:1)

这是在python中,我相信你可以很容易地在Java中使用它。

由于您需要唯一的分区 - 也就是说,您认为(1, 4)(4. 1)是同一个分区 - 因此按顺序生成组件很方便。按顺序生成它们会稍微简单一些。

这意味着如果我们生成了第一个j组件(j < k),则生成的最后一个组件为p,到目前为止生成的组件总和为{{1 (s),然后我们可以使用s < n的任何分区结束,其中最小大小为n - s的{​​{1}}组件不会超过k - j

换句话说,我们想要一个三参数递归函数。但是当我们找到分区时,我们还需要考虑在递归底部我们做了什么。在python中,我们只能s,但在其他语言中,我们可以通过递归传递函数,并在分区上调用函数。这可能是Java或C ++中最简单的解决方案,所以我将以这种方式对python解决方案进行建模。它还使用了一个固定长度的数组,它有点unpythonic但在Java中可能会更好。

仔细分析递归将显示如何从一个向量迭代到下一个向量。但那是值得怀疑的,恕我直言。

yield

分区计数增长很快。有(如果上面没有错误)596,763个分区,k = 7,n = 100;其中150,224包括至少一个5号组件。

供参考,原始python(3.3+),使用# v: vector of size k # k: max parts # (redundant: it's len(v)) # i: number of parts already in the vector # n: elements left to partition # s: minimum size of next part # (redundant: it's v[i - 1] unless i = 0, in which case it's 1) # act(v, i): action to call with vector and number of parts # Invariants: s <= n; i < k def genpart_helper(v, k, i, n, s, act): # We can always use everything which is left v[i] = n; act(v, i + 1) # If there is more than one part left, and we have # at least the twice the minimum number of elements left, # we can recurse if i + 1 < k: # This is python for: "for (int j = n/2; j >= s; --j)" for j in range(n // 2, s - 1, -1): v[i] = j genpart_helper(v, k, i + 1, n - j, j, act) # The top-level call. Checks the invariant, creates the vector, # and calls the recursive function def genparts(n, k, act): if k <= n and k >= 1: genpart_helper([0]*k, k, 0, n, 1, act)

yield

答案 1 :(得分:0)

如果它是一个递归功能,你需要......我有一个想法,但你必须先尝试编码。在这里,我们希望您先尝试,当您有疑虑时,请发布问题。然而...

我认为这个问题的关键是找到一个基本情况,就像“给定一个k长度的数组填充1 s,add 1到每个位置,直到当你n的职位时,你得到sum up all。例如:

找到n = 5的长度k = 3的成分。

  • findCompositions(3,5)
    • 创建长度为1的新数组。
    • 用1的
    • 填写
    • 在每个位置添加一个,直到每个位置总计5个。
    • 这里是递归发生的地方,您必须找到一种方法来存储您创建的数组(具有1个位置的数组),将其恢复为1并再添加一个位置,以便现在您有2个位置。
    • 即。你需要一个辅助方法findCompositions_rec(k,n,arr,result),其中k将递归地从1变为k。 Arr会随着时间的推移而变化,第一次会有1个位置,然后是2个,然后是3个......然后是k个。结果将是一个长度为[k,k]的矩阵,其中包含您在每次递归调用中创建的所有数组。