Time complexity of Sieve of Eratosthenes algorithm
维基百科:
The complexity of the algorithm is
O(n(logn)(loglogn)) bit operations.
你是怎么到那里的?
复杂性包括loglogn这个术语,这告诉我在某个地方有一个sqrt(n)。
假设我在前100个数字上运行筛子(EDOCX1,2),假设将数字标记为复合时间(数组实现),我们使用EDCOX1×3的次数将是类似的。
1
| n/2 + n/3 + n/5 + n/7 + ... + n/97 = O(n^2) |
为了找到下一个质数(例如,去掉所有5的倍数后跳到7),操作的次数将是O(n)。
因此,复杂性将是O(n^3)。你同意吗?
- 我不知道剩下的部分(对我现在昏昏欲睡的大脑来说太数学了),但是平方根是因为如果一个数没有小于平方根的除数,它就是素数。另外,我刚知道loglog(n)意味着有一个平方根。很好。
- 那里的Logg(n)意味着某处有一个平方(n)?(@martinho:你为什么说你"刚学会这个"?实际分析不涉及任何平方根!
你的N/2+N/3+N/5+…N/97不是O(N),因为项的数目不是常数。[编辑后编辑:o(n2)上界太宽松]宽松上界为n(1+1/2+1/3+1/4+1/5+1/6+…1/n)(所有数字的倒数之和,最大为n),即o(n logn):见谐波数。一个更合适的上界是n(1/2+1/3+1/5+1/7+……),它是素数倒数之和,最大为n,即o(n对数n)。(请参见此处或此处。)
"查找下一个质数"位总体上仅为O(N),摊销-您将继续查找下一个数字,总共仅为N次,而不是每个步骤。所以整个算法只需要O(n)。
因此,使用这两个函数,可以得到O(n log log n)+O(n)=O(n log log n)算术运算的上界。如果您计算位操作,因为您处理的是最多n个数字,那么它们有大约logn位,这就是logn的因子出现的地方,给出o(n logn logn)位操作。
- 对于问题的一部分,您考虑的是渐进复杂性。另一方面,您正在考虑摊销竞争性。我搞糊涂了。
- @Crisron有什么问题?"渐进复杂性"和"摊余复杂性"不是同一事物的两种不同类型。摊销只是一种更为仔细地计算某些东西的技术,这种技术可能恰好是渐进复杂性。
- 所有这些我都认为它们是不同的。谢谢你的澄清。
- @什里瓦察,为什么我们要计算到n项的调和级数之和?我们不应该只计算sqrt(n)项吗?以n(loglogsqrt(n))算术运算的theta给出答案?另外,维基百科说空间的复杂性是O(n)。这不应该是n的θ吗,因为在任何情况下我们都需要n个元素的数组?
- @S是的,你可以计算到√n项,但它在渐近分析中没有区别(甚至在运行时间中没有显著的实际差别),因为任何x的对数(√x)=(1/2)对数x。所以,任何x的对数(n对数√n)=完成(n对数n)。对于你的另一个问题,空间的复杂度是π(n),也就是O(n):通常使用O()来表示你指定的是上界,而不是用π()来表示它也是下界(特别是当下界很明显的时候,如这里所示)。
- @什里瓦察,谢谢:)
- @什里瓦察,哦..你怎么在这里输入theta的符号?
- @s_:-)完成是一个Unicode字符;我只是从其他地方复制粘贴它,但您也可能找到一个键盘布局,您可以用它输入这个字符。你也会发现我的答案很有帮助:o,Ω,和θ的区别是什么?
- @什里瓦察,好的……谢谢:)
- @Shrevatsar不应该将每个筛选步骤都限定为$sqrt(n)$以使您实际上可以将主$n$替换为$sqrt n$?您只需要检查倍数,直到您达到sqrt(n)$
- @香蕉你可以停在√N(而不是N),但这没有什么区别:运行时间是(N/2+N/3+……+n/p)算术运算,其中p是小于√n的最大素数(而不是n),但该和仍渐近于n对数对数n,就像您在n处停止一样(见上文"3月25日16日21:57"的注释)。
- @为什么分子是n?对于每一个素数等于或等于p,我需要把P的倍数除掉,所以我会说运行时间是(p/ 2 +p/ 3 +…+p/p)=p log log p。
- 然后你只会发现素数达到P,而不是N。例如,考虑n=1000,因此p=31。同时考虑893=19和215的事实;47不是素数。现在,如果你不把所有的19倍乘以893或更高,你就无法知道893不是素数。
- ShreevatsaR,当然,谢谢你让我找出这个老问题来解决这个愚蠢的问题。
- @巴纳奇一点也不蠢,我也时常感到困惑:—)
That the complexity includes the loglogn term tells me that there is a sqrt(n) somewhere.
请记住,当你在筛选时发现一个质数P,你不会在你当前位置+P开始划掉数字;你实际上会在P^2开始划掉数字。P小于P^2的所有倍数将被以前的质数所抵消。
- 这句话本身是真的,但与所引用的本身没有优点的话没有关系。无论我们是从p还是p^2开始,其复杂性都是相同的(对于直接访问阵列)。原因是SUM (1/p) {p。
内环执行n/i步,其中i是prime=>整个复杂性是sum(n/i) = n * sum(1/i)。根据主谐波系列,其中i是prime的sum (1/i)是log (log n)。在合计,O(n*log(log n))。
我认为可以通过用sqrt(n)替换n来优化上环,因此O(sqrt(n)loglog(n))的总体时间复杂度如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void isprime(int n)
{
int prime[n],i,j,count1=0;
for(i=0;i<n;i++)
{
prime[i]=1;
}
prime[0]=prime[1]=0;
for(i=2;i<=n;i++)
{
if(prime[i]==1)
{
printf("%d",i);
for(j=2;(i*j)<=n;j++)
prime[i*j]=0;
}
}
} |
- 不,用sqrt(n)替换n使之成为~n个log log(sqrt n),它仍然是~n个loglog n。在这里使用isprime绝对是错误的名称。
请看上面的解释,内环是所有素数的调和和,直到qRT(n)。因此,O(Sqt(n)*log(log(qRT(n)))的实际复杂性
- 请在您的帖子中添加更多代码。
- 错了。我们一直标记到n:n/2+n/3+n/5+n/7+n/11+…=n(1/2+1/3+1/5+1/7+1/11+…)~n日志(sqrt n)~n日志n。