如何计算此素数查找器算法的T(N)

时间:2015-04-27 11:41:26

标签: algorithm big-o complexity-theory

此算法查找低于N

的所有素数
var f = function(n){
    var primes = [2];  //1
    var flag; //1
    for(var i=3; i<n; i+=2){  // ( from 3 to n-1 ) / 2
        flag = true; //1
        var startI = 0; // 1
        for(var y=primes[startI]; y<=Math.sqrt(i); y=primes[++startI]){ // ???
            if(i%y === 0) // 1
                flag = false; // 1
        }
        if(flag) // 1
            primes.push(i); // 1
    }
    return primes; // 1
}

到目前为止,我的分析已经完成,直到第一个循环,我不知道如何处理第二个总和(使用primes.lengthMath.sqrt的那个)。

  

T(n)= 1 + 1 +总和((1 + 1 + ??奇怪的总和???),从i = 3到n -1)/ 2 + 1 + 1

我理解如何分析直到第二个嵌套循环,我怀疑它是围绕log(N)或类似的东西,但我想知道迭代的确切数量..

问题:

  • 如何处理在内存中使用数组进行迭代的那种循环?
  • 如果无法获得确切的数字,我怎样才能得到一个好的近似值?

感谢任何帮助(链接到类似案例,书籍等)。

1 个答案:

答案 0 :(得分:7)

内循环遍历sqrt(i)以下所有素数的数组。 所以你必须计算该数组中的元素数量。对于素数数组,您必须使用π(i)的近似值,即i以下的素数。

您可以按x/ln(x)或(更好)li(x)来估算它们。更多details here

对于分析,x/ln(x)会更容易。

总得到(假设n = 2k+1

T(n) = T(n-2) + O(sqrt(n)/( (1/2)⋅ln(n) )) = O( Σi = 1,...,k 2⋅sqrt(2⋅i+1)/ln(2⋅i+1) )

你从内部for循环中得到递归公式,它遍历低于sqrt(n)(近似为sqrt(n)/( (1/2)⋅ln(n) ))的素数数组,以及你需要做的工作,由T(n-2)代表。

也许你可以简化这个。我不想从你那里获得乐趣:)

提示:也许您可以使用积分来得到总和的近似值。但我认为没有“好”的方式来写下来。

如果你忘了1/ln(i) - 部分,你可以看到 T(n) ∈ o(n3/2)T(n) ∈ ω(n)。也许你可以做得更好。

正如@vib所提到的,你可以获得更严格的上限O(n3/2/ln(n))。但请注意sqrt(n)/ln(n)只是低于sqrt(n)的素数的近似值。因此,您可以通过更好的近似获得更好的界限。由于此近似值未提供π(n)的确切值,因此无法表示此算法在Θ(n3/2/ln(n))中运行。