📜  算法样本问题套装3 |时序分析

📅  最后修改于: 2021-04-25 01:02:28             🧑  作者: Mango

问题1: T(n)的渐近边界是什么?

  1. θ(n * log(n))
  2. θ(n 2 )
  3. θ(n)
  4. θ(n * log 2 (n))
  5. θ(n 2 * log 2 (n))

答:3
说明:要找到合适的上下边界,首先想到的一种方法是将sigma表示法扩展为单个术语,在其中可以检测到某些模式。这样,它有助于定义一些可以接受的上下边界,并且它们的组合可能会导致可能的解决方案。

关于指定这些边界,有一些提示如下:

  • 很明显,对于任何大于√的k n ,每个log k n应该小于log √ n n = 2,而大于log n n =1。在数学语言中:
    1. 对于k>√的UPPER边界的提示。 n

       \forall k \geq \sqrt{n},  log_{k}n \leq log_{\sqrt{n}}n = 2

       \Rightarrow \sum_{i=[\sqrt{n}]}^{ n } log_{i}n \leq \sum_{i=[\sqrt{n}]}^{ n } 2

    2. 对于k>√的LOWER边界的提示n

       \forall k \geq \sqrt{n},  log_{k}n \geq log_{n}n = 1

       \Rightarrow \sum_{i=[\sqrt{n}] + 1}^{ n } log_{i}n \geq \sum_{i=[\sqrt{n}] + 1}^{ n } 1

  • 除此之外,随着对数底数的增加,其值减小。因此,由第一个sigma的扩展引起的项均不能大于第一个ter,log 2 n,也不能小于最后一个,即log √。 n n;换句话说
    1. 关于UPPER边界的另一个提示,但这一次是k <&Sqrt; n

       \forall k \leq \sqrt{n},  log_{k}n \leq log_{2}n

       \Rightarrow  \sum_{i=2}^{  [\sqrt{n}] } log_{i}n \leq  \sum_{i=2}^{  [\sqrt{n}] } log_{2}n

    2. 关于下界的另一个提示,但是这次是k <&Sqrt; n

       \forall k \leq \sqrt{n},  log_{k}n \geq log_{\sqrt{n}}n = 2

       \Rightarrow \sum_{i=2}^{  [\sqrt{n}] } log_{i}n \geq  \sum_{i=2}^{  [\sqrt{n}] } 2

遵循以下提示即可:

  1. 下边界:

     \sum_{i=2}^{n} log_{i}n  =  \sum_{i=2}^{  [\sqrt{n}] } log_{i}n +  \sum_{i=[\sqrt{n}]+1}^{n} log_{i}n

     \leq  \sum_{i=2}^{  [\sqrt{n}] } log_{2}n +  \sum_{i=[\sqrt{n}]+1}^{n} 2

     =  ([\sqrt{n}] - 1) * log_{2}n +  (n - [\sqrt{n}]) * 2

     \approx  2 * n + \sqrt{n} * (log_{2}n - 2) - log_{2}n

     \Rightarrow T(n) \in O( 2 * n + \sqrt{n} * (log_{2}n - 2) - log_{2}n ) = O( n )

  2. 上限:

     \sum_{i=2}^{n} log_{i}n  =  \sum_{i=2}^{  [\sqrt{n}] } log_{i}n +  \sum_{i=[\sqrt{n}]+1}^{n} log_{i}n

     \geq  \sum_{i=2}^{  [\sqrt{n}] } log_{[\sqrt{n}]}n +  \sum_{i=[\sqrt{n}]+1}^{n} 1

     =  ([\sqrt{n}] - 1) * 2 +  (n - [\sqrt{n}]) * 1

     \approx  n  + \sqrt{n} - 2

     \Rightarrow T(n) \in \Omega(n + \sqrt{n} - 2) = \Omega( n )

到目前为止得出的结果表明,T(n)的增长不能超过O(n),也不能小于&ohm;(n);。因此,T(n)的渐近复杂度阶为:

 T(n) \in \Theta(n)

问题2:给定程序的运行时间顺序是什么?

C PROGRAM: Input n of type integer
  for(i= 2; i
  1. θ(n)
  2. θ(n * log(n))
  3. θ(n 2 )
  4. θ(n * log 2 log(n))
  5. θ(n 2 * log 2 (n))

答:1

说明:每行的运行时间分别如下所示:

  1. 第一行代码t 1 (n)为:
    for(i = 2; i //运行(n – 2)次;所以这条线的时间复杂度是θ(n)
  2. 第二条代码行t 2 (n)为:
    对于(j = 1;Ĵ登录2 N +登录3 N + … +日志N-1 N =ΣlogI N&中;根据本文上一个问题的Θ(n)in(请参阅问题1)
  3. 第三条代码行t 3 (n)为:
    //一条代码行Θ(1) ::内部循环,因此它的排序时间与上一行的Θ(n)相同

程序的总时间复杂度T(n)是每行t i (n)的总和,i = 1..3,如下所示:

 T(n) \in \Theta( n ) + \Theta( n ) + \Theta( n ) = \Theta( n )

问题3:给出以下递推方程T(n)。为了具有T(n)&in ;,多少个建议的g i (n),i = 1..5,函数是可以接受的。当f(n)= g i (n)时θ(f(n))?

  1. 1个
  2. 2个
  3. 3
  4. 4
  5. 5

答:2
说明:掌握定理及其扩展对轻松解决此问题有很大帮助。主定理的一般形式可以表示为:

 T(n) = a* T( \frac{n}{b}) + f(n), \forall a\geq 1, b > 1

为了使用主定理,需要看到具有特定“ a”,“ b”和“ f(n)”的给定问题满足该定理的那种情况的条件。主定理的三种情况及其条件是:

  • 情况1:发生这种情况时,递归树是繁重的工作(拆分/重组问题的工作因子问题而相形见)。)

      \forall \epsilon>0, f(n)  \leq  n^{log_{b}{a-  \epsilon}  } \Rightarrow  T(n)  \in   \theta (n^{lob_{b}{a}})

  • 情况2:当拆分/重组问题的工作可与子问题相提并论时,就会发生这种情况。

     f(n) \in \theta( n^{log_{b}{a}} * (log(n))^{k}) \Rightarrow  T(n)  \in \theta( n^{log_{b}{a}} *(log(n))^{k+1} )
     \forall k \geq 0

  • 情况3:这种情况发生在递归树是根密集型的情况下(拆分/重组问题的工作主导着子问题)。

     \forall \epsilon>0, f(n) \geq n^{log_{b}{a + \epsilon}  } \Rightarrow  T(n)  \in   \theta (f(n))

主定理的广义第二种情况,即所谓的高级主定理,处理所有k值。它说:

  •  \forall k > -1,

     f(n) \in \theta( n^{log_{b}{a}} * (log(n))^{k}) \Rightarrow  T(n)  \in \theta( n^{log_{b}{a}} *(log(n))^{k+1} )

  •  k = -1,

     f(n) \in \theta( n^{log_{b}{a}} * (log(n))^{-1}) \Rightarrow  T(n)  \in \theta( n^{log_{b}{a}} *log(log(n)) )

  •  \forall k < -1,

     f(n) \in \theta( n^{log_{b}{a}} * (log(n))^{k}) \Rightarrow  T(n)  \in \theta( n^{log_{b}{a}} )

这个问题的答案是主定理的第三种情况,其中T(n)等于Θ(f(n));因此,为了使T(n)=θ(f(n)),n log b a与f(n)之间应存在多项式差“ε”;因此,函数g 1 (n)和g 2 (n)满足Master定理的第三种情况。为它们找到的“ε”的值分别是1和0.01。

问题4:对于该多输入变量程序,哪个选项描绘了一个真实的渐近分析,同时对输入和输出的相对增长有深入的了解(先验知识),例如m&in;。 Θ(n)?

C PROGRAM: inputs m and n of type integer 
  for(i= 1; i<= n; i=i+1) : n
   for(j = 1; j <= m; j= j * 2)
    for(k = 1; k <= j; k= k+1)
     \\ A code line of Θ(1)
  1. θ(n * m *(m + 1)/ 2)
  2. θ(n * m + n * log 2 (m))
  3. θ(m 3 )
  4. θ(n 2 )
  5. θ(n 2 * log 2 (n))

答:4

说明:为了根据输入n和m,T(n,m)计算程序的时间复杂度,第一步是获得每条线的运行时间t i (n,m),如下所示:

  1. for(i = 1; i <= n; i = i + 1) //运行n次

     t_{1}(n, m) \in \Theta(n)

  2. for(j = 1; j <= m; j = j * 2) //重复log 2 (m)次,它在另一个循环中,将其相乘n次

     t_{2}(n, m) \in \Theta ( n * log(m) )

  3. for(k = 1; k <= j; k = k + 1) //运行2 + 4 + 8 +…+ 2 log(m)

     2 + 4 + 8 + \ldots + 2^{log(m)} = 2* (2^{log(m)} - 1) = 2*m - 2

    这也在外部循环(第一个“ for”循环)内部,该循环本身迭代n次

     t_{3}(n, m) \in \Theta ( m * n )

  4. \\代码行Θ(1)与上一行Θ(m * n)相同

     t_{4}(n, m) \in \Theta ( m * n )

该程序的总运行时间顺序为:

 T(n, m) \in  \sum_{i=1}^{4} \Theta ( t_{i}(n, m) ) \Rightarrow

 T(n, m) \in  \Theta(n) + \Theta(n* log(m)) + \Theta(n*m) + \Theta(n*m) = \Theta(n*m)

根据给定的先验知识,它甚至可以进一步简化,即m&in;。 Θ(n)或n&in; Θ(米):

 T(n, m) \in \Theta(n^{2}) or \Theta(m^{2})

问题5:有一个整数矢量,称为V [],其长度为“ N”。
对于特定问题(程序),给定Σi = 1 N | V [i] | =P。
以下代码段的时间复杂度是多少? [不用说,P也是整数]

Tmp = -1;
  For r= 1 to N
   For S = 1 to V[r]
    Tmp = Tmp + 20;
  1. O(N + 2 * N * P)
  2. O(N * P)
  3. O(N 2 )
  4. O(P 2 )
  5. O(2 * P + N)

答:5
说明:每行将执行的时间数及其总时间复杂度如下所示:

Tmp = -1; //θ(1)
对于r = 1到N // N次;所以它是θ(N)
对于S = 1到V [r] //不能大于| V [r] |时代因此总次数为O(Σr = 1 N | V [r] |)= O(P)
Tmp = Tmp + 20; //与上一行O(P)相同

为了找到给定程序的时间复杂度,需要牢记三个事实:

  1. 每个V [r]都可以采用任何整数值(甚至为零或负数),但这并不重要,因为所有负值都不会导致在C等编程语言中不执行第二个循环。但是,在编程语言中,它允许倒数(或迭代)负数,但算法的分析不取决于编程语言,而分析仅基于算法本身。可以肯定地说的是问题中给出的信息;因此,精明的操作是考虑| V [r] |的绝对值。并使用O()表示法来摆脱卡住的情况。否则,必须说程序的运行时间至少等于执行第一个循环所需的时间,即Ω(N)
  2. 尽管该程序的运行时间顺序似乎并不依赖于两个变量,但是没有更多的信息可用于比较P和N;这需要进一步的分析。因此,渐近复杂度取决于P和N的值;换句话说,有T(N,P)个复杂度函数而不是T(N)。
  3. O()表示法定义的边界比&theta()表示法指定的紧密边界更宽松。因此,θ()和O()的和为O()类型。在这个问题中,程序的总时间复杂度是所有代码行复杂度的总和,即θ(1)+θ(N)+ O(P)+ O(P) ,属于集合O(2 * P + N + 1)或O(2 * P + N)。

考虑到上述所有因素,一个渐近复杂度可以为T(N,P)∈O(2 * | P | + N);但是,变量的系数在渐近分析的最后一步并不重要,因为它们都属于同一组复杂度函数,并且复杂度也可以表示为O(| P | + N)。

来源:

  1. 伊朗大学考试的汇编(包括一些摘要,修改和翻译)