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


103

ฉันมีปัญหาในการตัดสินใจว่าความซับซ้อนของเวลาของอัลกอริธึมตัวส่วนร่วมที่ยิ่งใหญ่ที่สุดของยูคลิดคืออะไร อัลกอริทึมนี้ในรหัสหลอกคือ:

function gcd(a, b)
    while b ≠ 0
       t := b
       b := a mod b
       a := t
    return a

มันน่าจะขึ้นอยู่กับและข ความคิดของฉันคือความซับซ้อนของเวลาคือ O (a% b) ถูกต้องหรือไม่ มีวิธีเขียนที่ดีกว่านี้ไหม


14
ดู Knuth TAOCP เล่ม 2 - เขาให้ข้อมูลที่ครอบคลุม แค่ FWIW เกร็ดเล็ก ๆ น้อย ๆ : มันไม่ได้สัดส่วนกับa%b. กรณีที่เลวร้ายที่สุดคือเมื่อใดaและbเป็นหมายเลขฟีโบนักชีติดต่อกัน
Jerry Coffin

3
@JerryCoffin หมายเหตุ: หากคุณต้องการพิสูจน์ว่ากรณีที่เลวร้ายที่สุดคือตัวเลข Fibonacci ในลักษณะที่เป็นทางการมากขึ้นให้พิจารณาการพิสูจน์ขั้นตอนที่ n ก่อนการยุติจะต้องมีขนาดใหญ่อย่างน้อยเท่ากับ gcd คูณจำนวนฟีโบนักชีที่ n ด้วยการเหนี่ยวนำทางคณิตศาสตร์
Mygod

คำตอบ:


77

เคล็ดลับอย่างหนึ่งในการวิเคราะห์ความซับซ้อนของเวลาของอัลกอริทึมของ Euclid คือทำตามสิ่งที่เกิดขึ้นจากการทำซ้ำสองครั้ง:

a', b' := a % b, b % (a % b)

ตอนนี้ a และ b จะลดลงทั้งคู่แทนที่จะเป็นเพียงตัวเดียวซึ่งทำให้การวิเคราะห์ง่ายขึ้น คุณสามารถแบ่งออกเป็นกรณี:

  • เล็ก ๆ A: 2a <= b
  • เล็ก ๆ B: 2b <= a
  • เล็ก A: 2a > bแต่a < b
  • เล็ก B: 2b > aแต่b < a
  • เท่ากัน: a == b

ตอนนี้เราจะแสดงให้เห็นว่าทุกกรณีลดผลรวมa+bลงอย่างน้อยหนึ่งในสี่:

  • เล็ก: b % (a % b) < aและ2a <= bเพื่อให้bลดลงโดยในครึ่งอย่างน้อยเพื่อให้a+bลดลงอย่างน้อย25%
  • จิ๋ว B: a % b < bและ2b <= aเพื่อให้aลดลงโดยในครึ่งอย่างน้อยเพื่อให้a+bลดลงอย่างน้อย25%
  • ขนาดเล็ก A: bจะกลายเป็นb-aซึ่งน้อยกว่าที่b/2ลดลงอย่างน้อยa+b25%
  • ขนาดเล็ก B: aจะกลายเป็นa-bซึ่งน้อยกว่าที่a/2ลดลงอย่างน้อยa+b25%
  • เท่ากับ: a+bลดลงไป0ซึ่งจะเห็นได้ชัดลดลงอย่างน้อยa+b25%

ดังนั้นในการวิเคราะห์กรณีขั้นตอนทุกคู่ลดลงอย่างน้อยa+b 25%มีจำนวนครั้งสูงสุดนี้สามารถเกิดขึ้นได้ก่อนที่จะถูกบังคับให้ลดลงต่ำกว่าa+b 1จำนวนรวมของขั้นตอน ( S) จนกระทั่งเราตี 0 (4/3)^S <= A+Bต้องตอบสนอง ตอนนี้ใช้งานได้:

(4/3)^S <= A+B
S <= lg[4/3](A+B)
S is O(lg[4/3](A+B))
S is O(lg(A+B))
S is O(lg(A*B)) //because A*B asymptotically greater than A+B
S is O(lg(A)+lg(B))
//Input size N is lg(A) + lg(B)
S is O(N)

ดังนั้นจำนวนการวนซ้ำจึงเป็นเชิงเส้นในจำนวนหลักอินพุต สำหรับตัวเลขที่พอดีกับการลงทะเบียน cpu มันสมเหตุสมผลที่จะจำลองการทำซ้ำโดยใช้เวลาคงที่และแสร้งทำเป็นว่าเวลาทำงานทั้งหมดของ gcd เป็นแบบเส้นตรง

แน่นอนว่าหากคุณกำลังจัดการกับจำนวนเต็มจำนวนมากคุณต้องคำนึงถึงข้อเท็จจริงที่ว่าการดำเนินการโมดูลัสภายในการวนซ้ำแต่ละครั้งไม่มีต้นทุนคงที่ โดยประมาณแล้วรันไทม์ที่ไม่แสดงอาการทั้งหมดจะเป็น n ^ 2 เท่าของปัจจัยโพลีโลการิ ธ มิก บางอย่างเช่น n^2 lg(n) 2^O(log* n) . ปัจจัยโพลีโลการิ ธ มิกสามารถหลีกเลี่ยงได้โดยใช้gcd ไบนารีแทน


คุณช่วยอธิบายได้ไหมว่าทำไม "b% (a% b) <a" ได้โปรด?
Michael Heidelberg

3
@MichaelHeidelberg x % yไม่ได้มากกว่าและต้องน้อยกว่าx yดังนั้นa % bที่มากที่สุดaบังคับb % (a%b)จะต่ำกว่าสิ่งที่เป็นที่มากที่สุดและดังนั้นจึงเป็นเรื่องโดยรวมน้อยกว่าa a
Craig Gidney

@ Cheersandhth. -Alf คุณพิจารณาความแตกต่างเล็กน้อยในคำศัพท์ที่ต้องการว่า "ผิดอย่างร้ายแรง" หรือไม่? แน่นอนฉันใช้คำศัพท์ CS; มันเป็นคำถามเกี่ยวกับวิทยาศาสตร์คอมพิวเตอร์ ไม่ว่าฉันจะชี้แจงคำตอบว่า "จำนวนหลัก"
Craig Gidney

@CraigGidney: ขอบคุณที่แก้ไข ตอนนี้ฉันรับรู้ปัญหาการสื่อสารจากบทความ Wikipedia มากมายที่เขียนโดยนักวิชาการที่บริสุทธิ์ ลองพิจารณาสิ่งนี้: เหตุผลหลักในการพูดถึงจำนวนหลักแทนที่จะเขียนแค่ O (log (min (a, b)) ตามที่ฉันทำในความคิดเห็นของฉันคือการทำให้สิ่งต่างๆเข้าใจง่ายขึ้นสำหรับคนที่ไม่ใช่คณิตศาสตร์หากไม่มีสิ่งนั้น ข้อกังวลเพียงแค่เขียน "บันทึก" เป็นต้นนั่นคือจุดประสงค์ของจำนวนตัวเลขเพื่อช่วยเหลือผู้ที่ถูกท้าทายเมื่อคุณตั้งชื่อแนวคิดนี้ว่า "ขนาด" และมีคำจำกัดความที่อื่นและอย่าพูดถึง "บันทึก" ที่ ท้ายที่สุดคุณปิดบังแทนที่จะช่วย
ไชโยและ hth - Alf

ย่อหน้าสุดท้ายไม่ถูกต้อง หากคุณสรุปอนุกรมเหลื่อมที่เกี่ยวข้องคุณจะพบว่าความซับซ้อนของเวลาเป็นเพียง O (n ^ 2) แม้ว่าคุณจะใช้อัลกอริทึมการแบ่งเวลากำลังสองของหนังสือเรียนก็ตาม
Emil Jeřábek

29

วิธีที่เหมาะสมในการวิเคราะห์อัลกอริทึมคือการกำหนดสถานการณ์ที่เลวร้ายที่สุด กรณีที่เลวร้ายที่สุดของ Euclidean GCD เกิดขึ้นเมื่อมีส่วนเกี่ยวข้องกับ Fibonacci Pairs void EGCD(fib[i], fib[i - 1])โดยที่ i> 0.

ตัวอย่างเช่นลองเลือกกรณีที่เงินปันผลเป็น 55 และตัวหารคือ 34 (จำไว้ว่าเรายังคงจัดการกับตัวเลข fibonacci)

ป้อนคำอธิบายภาพที่นี่

ดังที่คุณสังเกตเห็นการดำเนินการนี้มีค่าใช้จ่ายในการทำซ้ำ 8 ครั้ง (หรือการโทรซ้ำ)

ลองใช้หมายเลข Fibonacci ที่ใหญ่กว่านี้คือ 121393 และ 75025 เราสังเกตได้ที่นี่เช่นกันว่าต้องใช้เวลาวนซ้ำ 24 ครั้ง (หรือเรียกซ้ำ)

ป้อนคำอธิบายภาพที่นี่

คุณยังสามารถสังเกตได้ว่าการทำซ้ำแต่ละครั้งจะให้หมายเลขฟีโบนักชี นั่นเป็นเหตุผลที่เรามีการดำเนินการมากมาย เราไม่สามารถได้ผลลัพธ์ที่คล้ายกันเฉพาะกับตัวเลข Fibonacci แน่นอน

ดังนั้นความซับซ้อนของเวลาจะถูกแทนด้วย Oh ขนาดเล็ก (ขอบเขตบน) คราวนี้ ขอบเขตล่างคือโอเมก้า (1) โดยสัญชาตญาณเช่นกรณีของ 500 หารด้วย 2 เป็นต้น

มาแก้ความสัมพันธ์การเกิดซ้ำ:

ป้อนคำอธิบายภาพที่นี่

เราอาจจะพูดแล้วว่ายุคลิด GCD สามารถทำให้เข้าสู่ระบบ (XY) การดำเนินงานที่มากที่สุด


2
ฉันคิดว่าการวิเคราะห์นี้ไม่ถูกต้องเนื่องจากฐานขึ้นอยู่กับอินพุต
หวังว่าจะเป็นประโยชน์ใน

คุณพิสูจน์ได้หรือไม่ว่าฐานอ้างอิงแสดงถึงปัญหา
Mohamed Ennahdi El Idrissi

1
ฐานคืออัตราส่วนทองคำอย่างเห็นได้ชัด ทำไม? เนื่องจากต้องใช้ขั้นตอนพิเศษเพียงขั้นตอนเดียวในการคำนวณ nod (13,8) เทียบกับ nod (8,5) สำหรับค่า x คงที่ถ้า y <x ประสิทธิภาพกรณีที่แย่ที่สุดคือ x = fib (n + 1), y = fib (n) ตรงนี้ y ขึ้นอยู่กับ x เราจึงดู x ได้เท่านั้น
Stepan

17

มีรูปลักษณ์ที่ดีที่นี้บนเป็นบทความวิกิพีเดีย

มันยังมีพล็อตความซับซ้อนที่ดีสำหรับคู่ค่า

O(a%b)มันไม่ได้เป็น

เป็นที่ทราบกันดีว่า (ดูบทความ) จะไม่ทำขั้นตอนมากกว่าห้าเท่าของจำนวนหลักในจำนวนที่น้อยกว่า (ln b)ดังนั้นจำนวนสูงสุดของขั้นตอนการเติบโตเป็นตัวเลขของตัวเลข ต้นทุนของแต่ละขั้นตอนก็จะเพิ่มขึ้นตามจำนวนหลักดังนั้นความซับซ้อนจึงถูกผูกไว้โดยO(ln^2 b)ที่ b คือจำนวนที่น้อยกว่า นั่นคือขีด จำกัด สูงสุดและเวลาจริงมักจะน้อยกว่า


อะไรnแทน?
IVlad

@IVlad: จำนวนหลัก ฉันได้ชี้แจงคำตอบแล้วขอบคุณ
JoshD

สำหรับอัลกอริทึมของ OP การใช้ดิวิชั่น (จำนวนเต็มใหญ่) (และไม่ใช่การย่อย) ในความเป็นจริงมีบางอย่างเช่น O (n ^ 2 log ^ 2n)
Alexandre C.

@Alexandre C .: n = ln bเก็บไว้ในใจ ความซับซ้อนปกติของโมดูลัสสำหรับ int ขนาดใหญ่คืออะไร? ใช่หรือไม่ (log n log ^ 2 log n)
JoshD

@ JoshD: มันเป็นอย่างนั้นฉันคิดว่าฉันพลาด log n เทอมความซับซ้อนสุดท้าย (สำหรับอัลกอริทึมที่มีการหาร) คือ O (n ^ 2 log ^ 2 n log n) ในกรณีนี้
Alexandre C.

13

ดูที่นี่ .

โดยเฉพาะส่วนนี้:

ลาเมแสดงให้เห็นว่าจำนวนขั้นตอนที่จำเป็นเพื่อให้ได้ตัวหารร่วมที่ยิ่งใหญ่ที่สุดสำหรับสองจำนวนที่น้อยกว่า n

ข้อความแสดงแทน

ดังนั้นO(log min(a, b))เป็นสิ่งที่ดีที่ถูกผูกไว้ด้านบน


4
นั่นเป็นความจริงสำหรับจำนวนขั้นตอน แต่ไม่ได้คำนึงถึงความซับซ้อนของแต่ละขั้นตอนซึ่งปรับตามจำนวนหลัก (ln n)
JoshD

9

นี่คือความเข้าใจที่เข้าใจง่ายเกี่ยวกับความซับซ้อนของรันไทม์ของอัลกอริทึมของ Euclid การพิสูจน์อย่างเป็นทางการครอบคลุมอยู่ในข้อความต่างๆเช่น Introduction to Algorithms และ TAOCP Vol 2

ก่อนอื่นให้คิดว่าถ้าเราลองใช้ gcd ของ Fibonacci สองตัวคือ F (k + 1) และ F (k) คุณอาจสังเกตได้อย่างรวดเร็วว่าอัลกอริทึมของ Euclid วนซ้ำไปที่ F (k) และ F (k-1) นั่นคือด้วยการวนซ้ำแต่ละครั้งเราจะเลื่อนตัวเลขลงหนึ่งในอนุกรมฟีโบนักชี เนื่องจากตัวเลข Fibonacci คือ O (Phi ^ k) โดยที่ Phi เป็นอัตราส่วนทองคำเราจะเห็นว่ารันไทม์ของ GCD คือ O (log n) โดยที่ n = max (a, b) และ log มีฐานของ Phi ต่อไปเราสามารถพิสูจน์ได้ว่านี่จะเป็นกรณีที่เลวร้ายที่สุดโดยสังเกตว่าตัวเลข Fibonacci สร้างคู่อย่างสม่ำเสมอโดยที่ส่วนที่เหลือยังคงมีขนาดใหญ่พอในการวนซ้ำแต่ละครั้งและจะไม่กลายเป็นศูนย์จนกว่าคุณจะมาถึงตอนเริ่มต้นของซีรีส์

เราสามารถสร้าง O (log n) โดยที่ n = max (a, b) ผูกให้แน่นยิ่งขึ้น สมมติว่า b> = a เพื่อให้เราสามารถเขียนขอบเขตที่ O (log b) ขั้นแรกให้สังเกตว่า GCD (ka, kb) = GCD (a, b) เนื่องจากค่าที่ใหญ่ที่สุดของ k คือ gcd (a, c) เราสามารถแทนที่ b ด้วย b / gcd (a, b) ในรันไทม์ของเราซึ่งจะทำให้ขอบเขตของ O แน่นขึ้น (log b / gcd (a, b))


คุณสามารถพิสูจน์อย่างเป็นทางการได้หรือไม่ว่า Fibonacci nos ก่อให้เกิดกรณีที่เลวร้ายที่สุดสำหรับ Euclids algo?
Akash

4

กรณีที่เลวร้ายที่สุดของ Euclid Algorithm คือเมื่อส่วนที่เหลือมีขนาดใหญ่ที่สุดในแต่ละขั้นตอนกล่าวคือ เป็นเวลาสองเทอมติดต่อกันของลำดับฟีโบนักชี

เมื่อ n และ m เป็นจำนวนหลักของ a และ b โดยสมมติว่า n> = m อัลกอริทึมจะใช้การหาร O (m)

โปรดทราบว่าความซับซ้อนจะได้รับในรูปของขนาดของอินพุตเสมอในกรณีนี้คือจำนวนหลัก


4

กรณีที่เลวร้ายที่สุดจะเกิดขึ้นเมื่อทั้ง n และ m เป็นตัวเลข Fibonacci ติดต่อกัน

gcd (Fn, Fn − 1) = gcd (Fn − 1, Fn − 2) = ⋯ = gcd (F1, F0) = 1 และหมายเลข Fibonacci ที่ n คือ 1.618 ^ n โดยที่ 1.618 คืออัตราส่วนทองคำ

ดังนั้นในการค้นหา gcd (n, m) จำนวนการเรียกซ้ำจะเป็นΘ (บันทึก)


3

นี่คือการวิเคราะห์ในหนังสือโครงสร้างข้อมูลและการวิเคราะห์อัลกอริทึมใน CโดยMark Allen Weiss (พิมพ์ครั้งที่สอง 2.4.4):

อัลกอริทึมของ Euclid ทำงานโดยการคำนวณส่วนที่เหลืออย่างต่อเนื่องจนกว่าจะถึง 0 ส่วนที่เหลือที่ไม่ใช่ศูนย์สุดท้ายคือคำตอบ

นี่คือรหัส:

unsigned int Gcd(unsigned int M, unsigned int N)
{

    unsigned int Rem;
    while (N > 0) {
        Rem = M % N;
        M = N;
        N = Rem;
    }
    Return M;
}

นี่คือทฤษฎีที่เราจะใช้:

ถ้า M> N ดังนั้น M mod N <M / 2

หลักฐาน:

มีสองกรณี ถ้า N <= M / 2 เนื่องจากส่วนที่เหลือมีขนาดเล็กกว่า N ทฤษฎีบทจึงเป็นจริงสำหรับกรณีนี้ อีกกรณีคือ N> M / 2 แต่แล้ว N ไปหาร M หนึ่งครั้งโดยมีเศษเหลือ M - N <M / 2 พิสูจน์ทฤษฎีบท

ดังนั้นเราสามารถอนุมานได้ดังต่อไปนี้:

Variables    M      N      Rem

initial      M      N      M%N

1 iteration  N     M%N    N%(M%N)

2 iterations M%N  N%(M%N) (M%N)%(N%(M%N)) < (M%N)/2

ดังนั้นหลังจากการทำซ้ำสองครั้งส่วนที่เหลือจะเป็นครึ่งหนึ่งของค่าเดิมมากที่สุด นี่จะแสดงว่าจำนวนการทำซ้ำมากที่สุด2logN = O(logN)นี้จะแสดงให้เห็นว่าจำนวนของการทำซ้ำเป็นอย่างมาก

โปรดทราบว่าอัลกอริทึมจะคำนวณ Gcd (M, N) โดยสมมติว่า M> = N (ถ้า N> M การวนซ้ำครั้งแรกจะสลับกัน)


2

ทฤษฎีบทของ Gabriel Lame กำหนดจำนวนขั้นตอนตามบันทึก (1 / sqrt (5) * (a + 1/2)) - 2 โดยที่ฐานของบันทึกคือ (1 + sqrt (5)) / 2 นี่เป็นสถานการณ์ที่เลวร้ายที่สุดสำหรับอัลกอริทึมและจะเกิดขึ้นเมื่ออินพุตเป็นตัวเลข Fibanocci ที่ต่อเนื่องกัน

ขอบเขตที่เสรีกว่าเล็กน้อยคือ: log a โดยที่ฐานของบันทึกคือ (sqrt (2)) เป็นนัยโดย Koblitz

สำหรับวัตถุประสงค์ในการเข้ารหัสเรามักจะพิจารณาความซับซ้อนระดับบิตของอัลกอริทึมโดยคำนึงถึงขนาดบิตที่กำหนดโดย k = loga

นี่คือการวิเคราะห์โดยละเอียดเกี่ยวกับความซับซ้อนระดับบิตของ Euclid Algorithm:

แม้ว่าในการอ้างอิงส่วนใหญ่ความซับซ้อนระดับบิตของ Euclid Algorithm จะได้รับจาก O (loga) ^ 3 แต่ก็มีขอบเขตที่แน่นกว่าซึ่งก็คือ O (loga) ^ 2

พิจารณา; r0 = a, r1 = b, r0 = q1.r1 + r2 . . , ri-1 = qi.ri + ri + 1,. . . , rm-2 = qm-1.rm-1 + rm rm-1 = qm.rm

สังเกตว่า: a = r0> = b = r1> r2> r3 ... > rm-1> rm> 0 .......... (1)

และ rm เป็นตัวหารร่วมที่ยิ่งใหญ่ที่สุดของ a และ b

โดยการอ้างสิทธิ์ในหนังสือของ Koblitz (A course in number Theory and Cryptography) สามารถพิสูจน์ได้ว่า: ri + 1 <(ri-1) / 2 ................. ( 2)

อีกครั้งใน Koblitz จำนวนการดำเนินการบิตที่จำเป็นในการหารจำนวนเต็มบวก k บิตด้วยจำนวนเต็มบวก l-bit (สมมติว่า k> = l) ได้รับเป็น: (k-l + 1) .l ...... ............. (3)

โดย (1) และ (2) จำนวนตัวหารคือ O (loga) และโดย (3) ความซับซ้อนทั้งหมดคือ O (loga) ^ 3

ตอนนี้อาจลดลงเป็น O (loga) ^ 2 โดยคำพูดใน Koblitz

พิจารณา ki = logri +1

โดย (1) และ (2) เรามี: ki + 1 <= ki สำหรับ i = 0,1, ... , m-2, m-1 และ ki + 2 <= (ki) -1 สำหรับ i = 0 , 1, ... , ม -2

และโดย (3) ต้นทุนรวมของตัวหารม. ล้อมรอบด้วย: SUM [(ki-1) - ((ki) -1))] * ki สำหรับ i = 0,1,2, .. , m

การจัดเรียงสิ่งนี้ใหม่: SUM [(ki-1) - ((ki) -1))] * ki <= 4 * k0 ^ 2

ดังนั้นความซับซ้อนระดับบิตของอัลกอริทึมของ Euclid คือ O (loga) ^ 2


1

อย่างไรก็ตามสำหรับอัลกอริทึมซ้ำเรามี:

int iterativeEGCD(long long n, long long m) {
    long long a;
    int numberOfIterations = 0;
    while ( n != 0 ) {
         a = m;
         m = n;
         n = a % n;
        numberOfIterations ++;
    }
    printf("\nIterative GCD iterated %d times.", numberOfIterations);
    return m;
}

สำหรับคู่ Fibonacci ไม่มีความแตกต่างระหว่างiterativeEGCD()และiterativeEGCDForWorstCase()โดยที่คู่หลังมีลักษณะดังต่อไปนี้:

int iterativeEGCDForWorstCase(long long n, long long m) {
    long long a;
    int numberOfIterations = 0;
    while ( n != 0 ) {
         a = m;
         m = n;
         n = a - n;
        numberOfIterations ++;
    }
    printf("\nIterative GCD iterated %d times.", numberOfIterations);
    return m;
}

ใช่กับ Fibonacci Pairs n = a % nและn = a - nมันก็เหมือนกันทุกประการ

factor = m / (n % m)เรายังไม่ทราบว่าในการตอบสนองที่ก่อนหน้านี้สำหรับคำถามเดียวกันมีปัจจัยที่ลดลงในขณะนั้น:

ดังนั้นในการกำหนดรูปแบบ GCD แบบยุคลิดแบบวนซ้ำในรูปแบบที่กำหนดเราอาจพรรณนาว่าเป็น "เครื่องจำลอง" ดังนี้:

void iterativeGCDSimulator(long long x, long long y) {
    long long i;
    double factor = x / (double)(x % y);
    int numberOfIterations = 0;
    for ( i = x * y ; i >= 1 ; i = i / factor) {
        numberOfIterations ++;
    }
    printf("\nIterative GCD Simulator iterated %d times.", numberOfIterations);
}

จากผลงาน (สไลด์สุดท้าย) ของ Dr. Jauhar Ali ลูปด้านบนเป็นลอการิทึม

ป้อนคำอธิบายภาพที่นี่

ใช่เล็ก ๆ โอ้เพราะจำลองบอกจำนวนซ้ำที่มากที่สุด คู่ที่ไม่ใช่ Fibonacci จะใช้เวลาในการทำซ้ำน้อยกว่า Fibonacci เมื่อตรวจสอบบน Euclidean GCD


เนื่องจากการศึกษานี้ดำเนินการโดยใช้ภาษา C ปัญหาด้านความแม่นยำอาจให้ค่าที่ผิดพลาด / ไม่ชัดเจน นั่นเป็นเหตุผลที่นานถูกนำมาใช้เพื่อให้พอดีกับที่ดีกว่าตัวแปร floating point ชื่อปัจจัย คอมไพเลอร์ที่ใช้คือ MinGW 2.95
Mohamed Ennahdi El Idrissi

1

ในทุกขั้นตอนมีสองกรณี

b> = a / 2 แล้ว a, b = b, a% b จะทำให้ b เป็นครึ่งหนึ่งของค่าก่อนหน้า

b <a / 2 จากนั้น a, b = b, a% b จะสร้างค่าสูงสุดครึ่งหนึ่งของค่าก่อนหน้าเนื่องจาก b น้อยกว่า a / 2

ดังนั้นในทุกขั้นตอนอัลกอริทึมจะลดตัวเลขอย่างน้อยหนึ่งตัวให้เหลืออย่างน้อยครึ่งหนึ่ง

ในขั้นตอนO (log a) + O (log b) ส่วนใหญ่จะลดลงเป็นกรณีธรรมดา ซึ่งให้ผลอัลกอริทึม O (log n) โดยที่ n คือขีด จำกัด บนของ a และ b

ฉันได้พบมันที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.