我做了一个使用k-sub算法的函数(从n个元素集合生成大小为k的所有子集)。我正在迭代它n次以创建所有大小的所有子集(即powerset)。
为什么我已经有了生成powerset的方法时使用此功能?因为我希望在子集的长度增加的情况下生成子集。
for(int k = 0; k <= n; k++){
recursiveSelectSubset(){
if(k == n){
for(int i = 0; i < n; i++){
subset[i] = true;
}
}
if(k == 0){
for(int i = 0; i < n; i++){
subset[i] = false;
}
}
if(k > 0 && k < n){
subset[n-1] = true;
recursiveSelectSubset(subset, n-1, k-1, isminimum, io);
subset[n-1] = false;
recursiveSelectSubset(subset, n-1, k, isminimum, io);
}
}
}
现在该函数被调用了n次,所以n就在那里。但是recurciveSelectSubset函数的复杂性是什么?
我觉得这个函数产生了大小为k的所有子集,所以就像nCk一样。其复杂度为O(n ^ k)。现在它运行k的所有可能值从1到n我们可以说,这个片段的最终复杂度是O(n ^(n + 1))
这就是我计算recursiveSelectSubset的复杂性的方法。 为了生成大小为k = 0的所有子集,它将花费n ^ 0。为了生成大小为k = 1的所有子集,它将花费n ^ 1。这种方式生成大小为k = n的子集,它将花费n ^ n。总时间为n ^ 0 + n ^ 1 + .... + n ^ n = n ^(n + 1)。
但是再次怀疑,为了生成大小为k = n的子集,它应该花费不变的时间吗?不是n ^ n。所以这样我的计算出错了。但是根据nCk,可能需要n ^ n = n ^ 0 = 1.那么如何为k的所有值加总呢?
那么正确的复杂性是什么?
P.S 即可。如果我的分析错了,我想澄清它是怎么回事?
答案 0 :(得分:0)
经过一些冲浪和讨论后,我找到了一个答案,我将在此处发布以供将来帮助。
recursiveSelectSubset()将计算nCk并花费时间n ^ k。正在调用此函数k = 0到n。
所以它所花费的总时间是所有recurseiveSelectSubset()调用所用时间的总和。
n ^ 0 + n ^ 1 + n ^ 2 + .... + n ^ n
这实际上是二项式系数的总和,它总计为2 ^ n。 (here)
上述函数的总时间复杂度为2 ^ n。