บล็อกโพสต์ปริศนาล่าสุดเกี่ยวกับการค้นหาสามช่องว่างเท่า ๆ กันนำฉันไปสู่คำถามสแต็คโอเวอร์โฟลว์พร้อมคำตอบยอดนิยมที่อ้างว่าทำในเวลา O (n lg n) ส่วนที่น่าสนใจคือว่าการแก้ปัญหาที่เกี่ยวข้องกับการ squaring พหุนาม, อ้างอิงกระดาษที่อธิบายถึงวิธีที่จะทำมันใน O (n LG n) เวลา
ตอนนี้การคูณแบบพหุนามมีค่าเท่ากันกับการคูณตัวเลข ความแตกต่างที่แท้จริงเพียงอย่างเดียวคือการขาดการแบก แต่ ... การบรรทุกสามารถทำได้ในเวลา O (n lg n) ตัวอย่างเช่น:
var value = 100; // = 0b1100100
var inputBitCount = value.BitCount(); // 7 (because 2^7 > 100 >= 2^6)
var n = inputBitCount * 2; // 14
var lgn = n.BitCount(); // 4 (because 2^4 > 14 => 2^3)
var c = lgn + 1; //5; enough space for 2n carries without overflowing
// do apparently O(n log n) polynomial multiplication
var p = ToPolynomialWhereBitsAreCoefficients(value); // x^6 + x^5 + x^2
var p2 = SquarePolynomialInNLogNUsingFFT(p); // x^12 + 2x^11 + 2x^10 + x^8 + 2x^7 + x^4
var s = CoefficientsOfPolynomial(p2); // [0,0,0,0,1,0,0,2,1,0,2,2,1]
// note: s takes O(n lg n) space to store (each value requires at most c-1 bits)
// propagate carries in O(n c) = O(n lg n) time
for (var i = 0; i < n; i++)
for (var j = 1; j < c; j++)
if (s[i].Bit(j))
s[i + j].IncrementInPlace();
// extract bits of result (in little endian order)
var r = new bool[n];
for (var i = 0; i < n; i++)
r[i] = s[i].Bit(0);
// r encodes 0b10011100010000 = 10000
ดังนั้นคำถามของฉันคือสิ่งนี้ความผิดพลาดอยู่ตรงไหน? การคูณตัวเลขใน O (n lg n) เป็นปัญหาแบบเปิดขนาดใหญ่ในสาขาวิทยาศาสตร์คอมพิวเตอร์และฉันสงสัยจริงๆว่าคำตอบจะง่ายขนาดนี้
- ถือผิดหรือไม่ O (n lg n)? ฉันคิดว่า lg n + 1 บิตต่อค่านั้นเพียงพอสำหรับการติดตามการบรรทุกและอัลกอริทึมนั้นง่ายมากฉันจะประหลาดใจถ้ามันผิด โปรดทราบว่าแม้ว่าการเพิ่มขึ้นแต่ละครั้งอาจใช้เวลา O (lg n) แต่ค่าใช้จ่ายรวมสำหรับการเพิ่มขึ้นทีละครั้งคือ O (x)
- อัลกอริทึมการคูณพหุนามเป็นกระดาษผิดหรือมีเงื่อนไขที่ฉันละเมิดหรือไม่? กระดาษใช้การแปลงฟูริเยร์ที่รวดเร็วแทนการแปลงเชิงทฤษฎีจำนวนซึ่งอาจเป็นปัญหา
- มีคนฉลาดมากมายที่พลาดอัลกอริทึมของSchönhage – Strassen เป็นเวลา 40 ปีหรือไม่ นี่ดูเหมือนจะเป็นไปได้น้อยมาก
ฉันเขียนโค้ดเพื่อใช้งานจริงยกเว้นการคูณพหุนามที่มีประสิทธิภาพ (ฉันยังไม่เข้าใจว่าทฤษฏีการแปลงตัวเลขยังดีพอ) การทดสอบแบบสุ่มปรากฏขึ้นเพื่อยืนยันว่าอัลกอริทึมนั้นถูกต้องดังนั้นปัญหาน่าจะเกิดขึ้นในการวิเคราะห์ความซับซ้อนของเวลา
x^10 + 2x^8
? x ^ 10 เพียงครั้งเดียว (x ^ 5 * x ^ 5) และ x ^ 8 สองครั้ง (x ^ 6 * x ^ 2 + x ^ 2 * x ^ 6)