【问题标题】:Analyzing an exponential recursive function分析指数递归函数
【发布时间】:2014-03-18 01:46:01
【问题描述】:

我正在尝试计算以下的复杂度 指数递归函数。

isMember() 和 isNotComputed() 函数减少了数量 递归调用。

这段代码的输出是一组 A[], B[] 打印在 递归函数调用的初始部分。

对于为此开发递归关系的任何意见,我们将不胜感激 这将导致对该程序进行分析的问题。

如果没有函数 isMember()、isNotComputed(),这段代码的复杂度为 O(2^N)。根据经验(使用上述两个函数),这段代码的复杂度为 O(|N^2||L|)。其中 L 是递归调用的次数,即生成的结果。

我正在尝试尽可能准确地计算此代码的复杂性,以便我可以将其效率与一组其他性质相似的算法进行比较。

void RecuriveCall(int A[], int ASize, short int B[], int BSize, 
              int y, short int level) { 
    int C[OBJECTSIZE]; 
    short int D[ATTRIBUTESIZE]; 
    int CSize, DSize; 
    PrintResult( A,ASize, B, BSize);                                                                         
    for (int j=y; j<n; j++) {                                                  
        if (! isMember(j, B, BSize)) {                                      
            function1(C,CSize,A,ASize,j);                             
            function2(D,DSize,C, CSize);                                 
            if (isNotComputed(B, BSize, D, DSize, j)) {                                                                                     
                RecursiveCall(C, CSize,D, DSize, j+1, level+1); 
            }      

        } 
    } 

}    

// Complexity - O(log N) - Binary Search
bool isMember(int j,short int B[], int BSize) { 
    int first, mid, last; 
    first = 0; 
    last = BSize-1; 

    if (B[first] == j || B[last] == j) { 
        return true; 
    } 

    mid = (first+last)/2; 
    while (first <= last) { 
        if (j == B[mid]) { 
            return true; 
        } 
        else if (j < B[mid])  
            last = mid-1; 
        else
            first = mid+1; 
        mid = (first+last)/2; 
    } 
    return false; 
}
// complexity - O(N)
bool isNotComputed(short int B[], int BSize, short int D[], int DSize,int j) { 
    if (j==0) { 
        return true; 
    } 

    int r = 0; 
    while (r<BSize && B[r]<j && r<DSize && D[r]<j) { 
        if (B[r] != D[r]) { 
            return false; 
        } 
        r=r+1; 
    } 
    // Now we can check if either B[] or D[] has extra elements which are < j 
    if (r<BSize && r < DSize && B[r]>=j && D[r] >=j) {// we know it is okay 
        return true; 
    } 
    if (r==BSize && r==DSize) {  
        return true; 
    } 
    if (r==BSize && r<DSize && D[r] >=j) {  
        return true; 
    } 
    if (r==DSize && r<BSize && B[r] >=j) { 
        return true; 
    } 
    return false; 
} 


// Complexity - O(N)
void function1(int C[],int &CSize,int A[] ,int ASize,int j) { 
    int tsize = 0; 
    for (int r=0;r<ASize;r++) 
        if (I[A[r]][j]==1) 
            C[tsize++] = A[r]; 
    CSize = tsize; 
} 

// Complexity - O(|N||G|) - G - number of objects
void function2(short int B[], int &BSize,int A[], int ASize) { 
   int i,j; 
   int c=0; 
    // Iterate through all attributes 
   for (j = 0; j < MAXATTRIBUTES; ++j) { 
      // Iterate through all objects 
      for (i = 0; i < ASize; ++i)  
         if (!I[A[i]][j]) 
            break; 
      if (i == ASize)  
         B[c++] = j; 
   } 
   BSize = c; 
}

void main() {
   n = MAXATTRIBUTES;
   for (int r=0; r<MAXOBJECTS; r++) 
       A[r] = r; 
   ASize = MAXOBJECTS; 
   function2(B, BSize, A, ASize); 

   RecursiveCall(A, ASize,B, BSize, 0, 0); 
}

“mohamed ennahdi el idrissi”给出的答案解决了如何开发递归关系。

如何将函数 isMember() 和 isNotComputed() 函数合并到这个函数中。本质上,这些显着减少了递归调用的数量。有没有办法引入概率函数来表示它们?即 P(f(n))xRecCall(n-1)。我已经看到计算了一些算法的复杂性,例如为 O(N^2.48)。你是怎么得出这样的价值观的?

【问题讨论】:

  • 你想到了什么?它在哪里失败/工作?
  • 能否提供isMember和isNotComputed的来源?我们可以假设 function1 和 function2 是 O(1),但是前一个函数的结果对于理解整体复杂性至关重要。
  • 谢谢亚历杭德罗。如果我忽略 isMember() 和 isNotComputed() 方法,则代码的复杂度为 O(2^N)。然而在实践中,这个算法运行在 O(N^2)。
  • 谢谢胡安。我已经包含了其他功能的代码。感谢任何输入。顺便说一下,算法计算形式概念(形式概念分析)。
  • 谢谢。 n = 最大属性;我已经更新了代码,它被用作全局变量,这不是一个好习惯。

标签: algorithm recursion complexity-theory time-complexity asymptotic-complexity


【解决方案1】:

我已尝试将以下重复关系调整到您的代码中,请参见以下步骤:

其中n = MAXATTRIBUTES(常量)和m = ASize

【讨论】:

  • 非常感谢。我会通过你的解决方案。
  • 您好 Ennnahdi,请快速检查一下。即使我们忽略 function1() 和 function2(),时间复杂度也不会是 O(2^N) 或 O(N!)。见[链接]stackoverflow.com/questions/5363619/…
  • 嗨,TRecCall(y+1) 不应该在解决方案第一行的 sigma 内。
  • 你是对的,它应该在sigma里面,但是它应该乘以一些概率函数,因为它是在两个条件下执行的。对于前面的问题,我需要重新计算以断言它是 O(2^N) 或 O(N!)。
猜你喜欢
  • 1970-01-01
  • 2012-08-29
  • 2016-05-10
  • 2015-03-04
  • 1970-01-01
  • 2016-03-13
  • 1970-01-01
  • 2017-10-13
  • 2016-02-18
相关资源
最近更新 更多