查找算法的指令数

时间:2018-10-13 20:36:03

标签: algorithm time-complexity complexity-theory

给出此算法(a> 0,b> 0):

while(a>=b){
   k=1;
   while(a>=k*b){
      a = a - k*b;
      k++;
   }
}

我的问题:我必须找到该算法的时间复杂度,要做到这一点,我必须找到指令数量,但找不到。有没有办法找到这个数字,如果没有,我如何找到它的时间复杂度?

我所做的事情:首先,我尝试查找第一个循环的迭代次数,并找到了一个模式:a_i = a-(i(i + 1)/ 2) * b其中,i是迭代次数。我已经花了几个小时对其进行了一些操作,但是找不到任何相关的东西(我发现了奇怪的结果,例如q²<= a / b

1 个答案:

答案 0 :(得分:3)

您已经正确计算出内部循环的第a次迭代后的i的值是:

enter image description here

a_j0是第a外循环开始时j的值。内循环的停止条件是:

enter image description here

可以解决二次不等式

enter image description here

因此,内部循环大约为O(sqrt(a_j0 / b))a next 起始值满足:

enter image description here

大致缩放为sqrt(2b * a_j0)。准确地计算时间复杂度将非常繁琐,因此让我们从此处开始应用上述近似值:

enter image description here

a_n代替a_j0,其中t_n是内部循环的运行时间–当然,总的时间复杂度只是t_n的总和。请注意,第一项由n = 1给出,并且a的输入值定义为a_0

在直接解决此重复项之前,请注意,由于第二项t_2已经与第一项t_1的平方根成比例,因此后者在总和中占所有其他项的作用。

  

因此,总时间复杂度仅为 O(sqrt(a / b))


更新:数值测试。

请注意,由于a值的所有变化都与b成比例,并且所有循环条件也与b成比例,因此可以对该函数进行“归一化“ ,只需设置b = 1并仅更改a

JavaScript测试功能,它测量内部循环执行的次数:

function T(n)
{
   let t = 0, k = 0;
   while (n >= 1) {
      k = 1;
      while (n >= k) {
          n -= k;
          k++; t++;
      }
   }
   return t;
}

sqrt(n)T(n)的图:

enter image description here

令人信服的直线,确认时间复杂度的确是一半。