ขนาดหน้าต่างที่เล็กลงn log n
การเรียงลำดับอาจใช้งานได้ มีอัลกอริธึมที่ดีกว่าเพื่อให้บรรลุสิ่งนี้หรือไม่?
ขนาดหน้าต่างที่เล็กลงn log n
การเรียงลำดับอาจใช้งานได้ มีอัลกอริธึมที่ดีกว่าเพื่อให้บรรลุสิ่งนี้หรือไม่?
คำตอบ:
มันเป็นรูปแบบที่ไม่ดีในการเรียงลำดับอาร์เรย์เพื่อคำนวณค่ามัธยฐาน Medians (และ quantiles อื่น ๆ ) โดยทั่วไปจะคำนวณโดยใช้อัลกอริทึมquickselectโดยมีความซับซ้อน
นอกจากนี้คุณยังอาจต้องการที่จะมองไปที่คำตอบของฉันคำถามที่เกี่ยวข้องเมื่อเร็ว ๆ นี้ที่นี่
นี่คือบทความที่อธิบายถึงอัลกอริทึมที่เป็นไปได้ มีซอร์สโค้ดและแอปพลิเคชั่นที่ค่อนข้างจริงจัง (การตรวจจับคลื่นความโน้มถ่วงที่อิงกับเลเซอร์อินเฟอโรเมท) ดังนั้นคุณสามารถคาดหวังว่ามันจะผ่านการทดสอบอย่างดี
หากคุณยินดีที่จะยอมรับการประมาณมีวิธีอื่น ๆ ตัวอย่างเช่นการประมาณหนึ่งค่าที่มีอันดับอยู่ภายในระยะห่าง (ผู้ใช้ระบุ) บางส่วนจากค่ามัธยฐานที่แท้จริง ตัวอย่างเช่นค่ามัธยฐานมี (ปกติ) อันดับที่ 0.5 และหากคุณระบุข้อกำหนดข้อผิดพลาดที่ 10% คุณจะต้องการคำตอบที่มีอันดับระหว่าง 0.45 ถึง 0.55
หากคำตอบดังกล่าวเหมาะสมแล้วมีวิธีแก้ปัญหามากมายที่สามารถทำงานกับหน้าต่างเลื่อนของข้อมูลได้ แนวคิดพื้นฐานคือการรักษาตัวอย่างข้อมูลขนาดที่แน่นอน (ประมาณ 1 / คำผิดพลาด) และคำนวณค่ามัธยฐานในตัวอย่างนี้ มันสามารถแสดงให้เห็นได้ว่ามีความน่าจะเป็นสูงโดยไม่คำนึงถึงลักษณะของสัญญาณเข้า
ดังนั้นคำถามหลักคือวิธีการรักษาตัวอย่างการรันข้อมูลขนาดที่แน่นอนและมีวิธีการมากมายที่รวมถึงเทคนิคที่เรียกว่าการสุ่มตัวอย่างอ่างเก็บน้ำ ตัวอย่างเช่นกระดาษนี้: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.24.7136
หากคุณรักษาหน้าต่างความยาวของข้อมูลเป็นรายการเชื่อมโยงที่เรียงลำดับแล้วโดยใช้การค้นหาแบบไบนารี (เพื่อแทรกองค์ประกอบใหม่แต่ละรายการตามที่ได้รับการเลื่อนเข้าไปในหน้าต่าง) และอาร์เรย์แบบวงกลมของตัวชี้ (เพื่อค้นหาองค์ประกอบที่ จำเป็นต้องลบ) การเลื่อนแต่ละครั้งของหน้าต่างต้องใช้ความพยายาม O (log (k)) สำหรับการแทรกองค์ประกอบเดียวเท่านั้นมีความพยายาม O (1) สำหรับการลบองค์ประกอบที่เลื่อนออกจากหน้าต่างและมีเพียงความพยายาม O (1) ในการค้นหา ค่ามัธยฐาน (เพราะทุกครั้งที่มีการแทรกหรือลบองค์ประกอบหนึ่งในรายการคุณสามารถอัปเดตตัวชี้ไปยังค่ามัธยฐานในเวลา O (1)) ความพยายามทั้งหมดสำหรับการประมวลผลอาร์เรย์ของความยาว N จึงเป็น O ((nk) log (k)) <= O (n log (k)) นี่ดีกว่าวิธีอื่น ๆ ที่เสนอมาจนถึงตอนนี้และมันไม่ได้เป็นการประมาณมันแน่นอน
ในขณะที่คุณกล่าวถึงการเรียงลำดับจะเป็นหน้าต่างของความยาวO(n·log n)
n
การทำเช่นนี้จะเป็นการเพิ่มl=vectorlength
ต้นทุนการผลิตO(l·n·log n)
อีกอัน
วิธีที่ง่ายที่สุดในการผลักดันสิ่งนี้คือการเก็บรายการเรียงลำดับขององค์ประกอบสุดท้าย n ในหน่วยความจำเมื่อย้ายจากหน้าต่างหนึ่งไปยังอีกหน้าต่างหนึ่ง ในฐานะที่เป็นลบ / ใส่องค์ประกอบหนึ่งจาก / ลงในรายการสั่งซื้อทั้งสองนี้จะส่งผลให้ค่าใช้จ่ายของO(n)
O(l·n)
pseudocode:
l = length(input)
aidvector = sort(input(1:n))
output(i) = aid(n/2)
for i = n+1:l
remove input(i-n) from aidvector
sort aid(n) into aidvector
output(i) = aid(n/2)
นี่คือโซลูชัน O (1) สำหรับการค้นหาค่ามัธยฐานปัจจุบันและ O (บันทึก n) สำหรับการเพิ่มหมายเลขใหม่ http://www.dsalgo.com/RunningMedian.php
หากคุณสามารถใช้ชีวิตอยู่กับการประมาณการแทนที่จะเป็นค่ามัธยฐานที่แท้จริงอัลกอริทึม Remedian (PDF)คือหนึ่งรอบที่มีข้อกำหนดด้านพื้นที่จัดเก็บต่ำและความแม่นยำที่กำหนดไว้ดี
การเยียวยาด้วยฐานขดำเนินการโดยการคำนวณค่ามัธยฐานของกลุ่มการสังเกต b จากนั้นค่ามัธยฐานของค่ามัธยฐานเหล่านี้จนกระทั่งเหลือเพียงค่าประมาณเดียว วิธีนี้ต้องการเพียง k อาร์เรย์ที่มีขนาด b (โดยที่ n = b ^ k) ...
ฉันใช้ไลบรารี RunStats C ++ นี้ในแอปพลิเคชันแบบฝัง มันเป็นห้องสมุดสถิติการทำงานที่ง่ายที่สุดที่ฉันได้พบ
จากลิงค์:
รหัสนี้เป็นส่วนเสริมของวิธีการของ Knuth และ Welford สำหรับการคำนวณความเบี่ยงเบนมาตรฐานในการส่งข้อมูลครั้งเดียว มันคำนวณความเบ้และความโด่งด้วยอินเทอร์เฟซที่คล้ายกัน นอกจากต้องการเพียงหนึ่งข้อมูลผ่านเท่านั้นอัลกอริทึมนั้นมีเสถียรภาพเชิงตัวเลขและแม่นยำ