ความซับซ้อนของเวลาของอัลกอริทึม Sieve of Eratosthenes


96

จากWikipedia:

ความซับซ้อนของอัลกอริทึมคือ O(n(logn)(loglogn))การดำเนินการแบบบิต

คุณมาถึงจุดนั้นได้อย่างไร?

ความซับซ้อนรวมถึงloglognคำที่บอกฉันว่ามีsqrt(n)ที่ไหนสักแห่ง


สมมติว่าฉันใช้ตะแกรงกับตัวเลข 100 ตัวแรก ( n = 100) โดยสมมติว่าการทำเครื่องหมายตัวเลขเป็นแบบผสมต้องใช้เวลาคงที่ (การใช้อาร์เรย์) จำนวนครั้งที่เราใช้mark_composite()จะเป็นดังนี้

n/2 + n/3 + n/5 + n/7 + ... + n/97        =      O(n^2)                         

และเพื่อหาตัวเลขที่สำคัญถัดไป (เช่นการกระโดด7ข้ามจากตัวเลขทั้งหมดที่มีหลายรายการ5) O(n)จำนวนของการดำเนินงานจะเป็น

O(n^3)ดังนั้นความซับซ้อนจะเป็น คุณเห็นด้วยไหม?


5
ฉันไม่รู้เกี่ยวกับส่วนที่เหลือ (ตอนนี้ฉันรู้สึกแย่เกินไปสำหรับสมองที่ง่วงเกินไป) แต่รากที่สองเกิดจากข้อเท็จจริงที่ว่าถ้าจำนวนไม่มีตัวหารน้อยกว่ารากที่สองของมันก็จะเป็นไพรม์ นอกจากนี้ฉันเพิ่งเรียนรู้ว่า loglog (n) หมายถึงมีรากที่สอง ดี.
R.Martinho Fernandes

13
loglog (n) การอยู่ที่นั่นหมายความว่ามี sqrt (n) อยู่ที่ไหนสักแห่ง? (@Martinho: ทำไมคุณถึงพูดว่าคุณ "เพิ่งเรียนรู้สิ่งนี้") การวิเคราะห์ที่แท้จริงไม่เกี่ยวข้องกับรากที่สองใด ๆ !
ShreevatsaR

คำตอบ:


121
  1. n / 2 + n / 3 + n / 5 + … n / 97 ของคุณไม่ใช่ O (n) เนื่องจากจำนวนพจน์ไม่คงที่ [แก้ไขหลังการแก้ไขของคุณ: O (n 2 ) ขอบเขตบนหลวมเกินไป] ขอบเขตบนหลวมคือ n (1 + 1/2 + 1/3 + 1/4 + 1/5 + 1/6 + ... 1 / n) (ผลรวมของส่วนกลับของทุกหมายเลขได้ถึง n) ซึ่งเป็น O (n log n): ดูจำนวนฮาร์มอนิ ขอบเขตบนที่เหมาะสมกว่าคือ n (1/2 + 1/3 + 1/5 + 1/7 + ... ) นั่นคือผลรวมของไพรม์ซึ่งกันและกันถึง n ซึ่งก็คือ O (n log log n) (ดูที่นี่หรือที่นี่ )

  2. "ค้นหาตัวเลขที่สำคัญต่อไป" บิตเป็นเพียง O (n) โดยรวมตัดจำหน่าย - คุณจะย้ายไปข้างหน้าเพื่อหาหมายเลขถัดไป n ครั้งเดียวในทั้งหมดไม่ต่อขั้นตอน ดังนั้นส่วนทั้งหมดของอัลกอริทึมนี้ใช้เวลาเพียง O (n)

ดังนั้นการใช้สองสิ่งนี้คุณจะได้ขอบเขตบนของ O (n log log n) + O (n) = O (n log log n) การดำเนินการทางคณิตศาสตร์ หากคุณนับการดำเนินการบิตเนื่องจากคุณกำลังจัดการกับตัวเลขถึง n จึงมีเกี่ยวกับ log n บิตซึ่งเป็นที่ที่ปัจจัยของ log n เข้ามาให้การดำเนินการบิต O (n log n log n)


สำหรับส่วนหนึ่งของปัญหาคุณกำลังพิจารณาถึงความซับซ้อนแบบไม่แสดงอาการ สำหรับส่วนอื่น ๆ คุณกำลังพิจารณาค่าคอมมิชชั่นแบบตัดจำหน่าย ฉันสับสน.
Crisron

2
@crisron ปัญหาคืออะไร? ไม่ใช่กรณีที่ "asymptotic complexity" และ "amortized complexity" เป็นสองประเภทที่เหมือนกัน การตัดจำหน่ายเป็นเพียงเทคนิคสำหรับการนับบางสิ่งอย่างรอบคอบมากขึ้นซึ่งอาจเกิดขึ้นได้กับความซับซ้อนแบบไม่แสดงอาการ
ShreevatsaR

ทั้งหมดนี้ในขณะที่ฉันเคยคิดว่าพวกเขาแตกต่างกัน ขอบคุณที่ชี้แจง
Crisron

1
@ShreevatsaR ทำไมเราถึงคำนวณผลรวมของอนุกรมฮาร์มอนิกได้ไม่เกิน n เทอม เราไม่ควรคำนวณเพียงไม่เกิน sqrt (n) เทอม? ให้คำตอบเป็น theta ของ n (loglogsqrt (n)) การดำเนินการทางคณิตศาสตร์? นอกจากนี้วิกิพีเดียยังบอกว่าความซับซ้อนของอวกาศคือ O (n) นั่นไม่ควรเป็นทีต้าของ n เพราะเราต้องการอาร์เรย์ขององค์ประกอบ n ไม่ว่าในกรณีใด ๆ ?
a_123

@ s_123 ใช่คุณสามารถคำนวณได้ไม่เกิน√nเทอม แต่ไม่ได้สร้างความแตกต่างในการวิเคราะห์แบบไม่แสดงอาการ (หรือแม้แต่ความแตกต่างในทางปฏิบัติอย่างมีนัยสำคัญในเวลาทำงาน) เนื่องจาก log (√x) = (1/2) log x สำหรับ x ใด ๆ ดังนั้นΘ (n log log √n) = Θ (n log log n) สำหรับคำถามอื่นของคุณใช่ความซับซ้อนของช่องว่างคือΘ (n) ซึ่งก็คือ O (n) เช่นกันโดยทั่วไปจะใช้ O () เพื่อระบุว่าคุณกำลังระบุขอบเขตบนแทนที่จะพูดว่าΘ () เพื่อระบุ นั่นคือขอบเขตล่างเช่นกัน (โดยเฉพาะอย่างยิ่งเมื่อขอบเขตล่างชัดเจนเหมือนอยู่ที่นี่)
ShreevatsaR

7

ความซับซ้อนรวมถึงคำ loglogn บอกฉันว่ามี sqrt (n) ที่ไหนสักแห่ง

เก็บไว้ในใจว่าเมื่อคุณพบว่ามีจำนวนที่สำคัญPในขณะที่ sieving คุณไม่เริ่มข้ามปิดตัวเลขที่ตำแหน่งปัจจุบันของคุณ + P; P^2ที่จะเริ่มต้นข้ามปิดตัวเลขที่ จำนวนทวีคูณที่Pน้อยกว่าทั้งหมดP^2จะถูกขีดฆ่าด้วยจำนวนเฉพาะก่อนหน้า


10
คำกล่าวนี้เป็นความจริงในตัวมันเอง แต่ไม่มีผลต่อข้อความที่ยกมาซึ่งตัวเองไม่มีประโยชน์ ไม่ว่าเราจะเริ่มจากpหรือp^2ความซับซ้อนก็เหมือนกัน (ด้วยอาร์เรย์การเข้าถึงโดยตรง) SUM (1/p) {p<N} ~ log (log N)คือเหตุผล
Will Ness

6
  1. ห่วงภายในไม่n/iทำตามขั้นตอนที่iเป็นนายก => sum(n/i) = n * sum(1/i)ความซับซ้อนทั้งเป็น ตามที่ประสานชุดสำคัญที่sum (1/i)ที่เป็นนายกรัฐมนตรีi log (log n)โดยรวม, O(n*log(log n)).
  2. ฉันคิดว่าวงบนสามารถปรับให้เหมาะสมได้โดยการแทนที่nด้วยsqrt(n)ความซับซ้อนของเวลาโดยรวมจะO(sqrt(n)loglog(n)):
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;
        }
    }    
}

2
ไม่แทนที่ n ด้วย sqrt (n) ทำให้เป็น ~ n log log (sqrt n) ซึ่งยังคงเป็น ~ n log log n และ isprimeเป็นการใช้ชื่อที่ไม่ถูกต้อง
Will Ness

-1

ดูคำอธิบายข้างต้นวงในคือผลรวมฮาร์มอนิกของจำนวนเฉพาะทั้งหมดจนถึง sqrt (n) ดังนั้นความซับซ้อนที่แท้จริงของคือ O (sqrt (n) * log (log (sqrt (n))))


2
ไม่ถูกต้อง. เราทำเครื่องหมายตลอดทางไปที่ N: N / 2 + N / 3 + N / 5 + N / 7 + N / 11 + ... = N (1/2 + 1/3 + 1/5 + 1/7 + 1/11 + ... ) ~ N log (sqrt N) ~ N log log N.
Will Ness
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.