需要知道以下代码的最坏情况的复杂性,如果您能提供解决问题的步骤,将不胜感激。我在想答案n ^ 3logn,但不确定。
int complexity(int n)
int i,j,c
for(i=1; i < n; i=i*3)
for(j=n; j < n*n; j++)
c++
for(i=c; i > 0; i--)
if(random(0...999) > 0)
for(j=0; j < 3*n; j++)
c++
else
for(j=2*n*n; j > 0; j--)
c++
return c
答案 0 :(得分:2)
让我们看一下第一个嵌套循环
for(i=1; i < n; i=i*3)
for(j=n; j < n*n; j++)
c++
外部循环运行log(n)
次[对数为3,但底数变化乘以一个不会影响渐近复杂性的常数],内部循环运行n^2
次,因此在此循环之后{ {1}}。
第二个循环:
c = n^2 * log(n)
在最坏的情况下,for(i=c; i > 0; i--)
if(random(0...999) > 0)
for(j=0; j < 3*n; j++)
c++
else
for(j=2*n*n; j > 0; j--)
c++
情况总是会发生,因此我们可以将其修改为
else
外部循环发生for(i=c; i > 0; i--)
for(j=2*n*n; j > 0; j--)
c++
次,即c
,内部循环将O(n^2 * log(n))
递增c
,因此2*n^2
递增{{1 }},加上初始值,我们得出c
(以及整体复杂度)在2 * n^2 * n^2 * log(n)
答案 1 :(得分:1)
我希望我不仅为您做功课。将来,我建议您显示到目前为止的思维过程,而不仅仅是最终答案。
让我们一次来看一下这段代码。
int complexity(int n)
int i,j,c
for(i=1; i < n; i=i*3)
for(j=n; j < n*n; j++)
c++
因此,在外循环中,我从1变为n,但每次将其增加三倍。这意味着它将在log_3(n)循环后完成。更改日志基数只是一个常量因素,与计算复杂性无关,因此我们可以说log(n)。
内部循环的j从n变为n ^ 2。 O(n ^ 2-n)= O(n ^ 2),因为较低的功率被较高的功率相形见quad(即线性二次方矮)。
因此,综上所述,第一部分的计算复杂度为O(n ^ 2 logn)。现在让我们看第二部分。
for(i=c; i > 0; i--)
if(random(0...999) > 0)
for(j=0; j < 3*n; j++)
c++
else
for(j=2*n*n; j > 0; j--)
c++
return c
现在,由于外循环的初始化取决于c,我们需要知道c是什么。在前两个嵌套循环中,c每次都会增加,因此c的值与n ^ 2 logn成正比。因此,外部循环将运行O(n ^ 2 logn)次。
对于内部循环,请记住,我们始终在考虑最坏的情况。因此,随机数生成器有点让人误解:计算两个j循环的计算复杂度,并假设最坏的情况总是发生。
第一个j循环从0到3n,即O(n)。第二个j循环从2n ^ 2变为0,即O(n ^ 2)。由于第二种情况更糟,因此我们假定它总是会发生(即使这种情况不太可能发生)。因此,内部循环为O(n ^ 2)。
将两个嵌套循环相乘,得到O(n ^ 2 logn x n ^ 2)= O(n ^ 4 logn)。
最后,请记住,我们必须看到两个部分中的哪个占主导地位。第一部分是O(n ^ 2 logn),第二部分是O(n ^ 4 logn),因此我们需要O(n ^ 2 logn + n ^ 4 logn)。后一项显然占主导地位,因此最终答案是O(n ^ 4 logn)。
希望这会有所帮助。请询问是否不清楚。
p.s。当前的最高答案指出c将为〜n ^ 3/3。因为我每次都三倍,这是不正确的;它将是n ^ 2 log_3(n)。否则他们的工作是正确的。
答案 2 :(得分:0)
解决此问题的方法是制定一个公式,该公式给出c
作为n
的函数。 (我们可以将c++
个操作的数量用作操作总数的代理。)
在这种情况下,random
函数意味着您无法获得确切的公式。但是您可以计算出两个公式,一个用于random
始终返回零的情况,另一个用于random
总是返回> 0的情况。
您如何计算公式?数学!
提示:最坏的情况将是我上面提到的两种情况之一。 (当然是哪个?复杂度最差的一个!)