อัลกอริทึมในการคำนวณค่ามัธยฐานที่ทำงานอยู่หรือไม่


18

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


1
ฉันคิดว่านี่เป็นผู้สมัครคนแรกที่ถูกย้ายไปที่ Stack Overflow

อาจเป็นไปได้ แต่มันต้องการคำอธิบายเพิ่มเติมเกี่ยวกับ SO
walkytalky

2
โปรแกรมเมอร์ส่วนใหญ่รู้จัก "มัธยฐาน" (sort (array)) [length / 2] เป็นคำใบ้ที่ใหญ่พอสำหรับผู้ที่ลืม ที่พื้นฐานที่สุดสำหรับแต่ละจุดใหม่คุณจะต้องทำ bisection / insert ในครึ่งหนึ่งของอาเรย์ ...
Paul

1
เปิดการสนทนาอีกครั้งที่meta.stats.stackexchange.com/questions/276/…
Rob Hyndman

2
เล็กน้อยเกินกว่าจะแสดงความคิดเห็นได้ แต่รหัสสำหรับค่ามัธยฐานของ 3s เป็นเพียงแค่ + b + c - max (a, b, c) - min (a, b. c) ใช้งานได้ดีแม้ว่าจะมีสายสัมพันธ์ นั่นเป็นสิ่งที่ชัดเจนสำหรับฉันเมื่อฉันคิดถึงจากรหัสของคนอื่น (ทำไมเขา (ในกรณีนี้)) การบวกและลบเพื่อให้ได้ค่ามัธยฐาน ???) และอีกสองสามคนอาจมีปฏิกิริยาแบบเดียวกัน max () และ min () มักจะถูกนำมาใช้เป็นฟังก์ชั่นที่เร็วสุด น่าเศร้าที่ไม่มีเคล็ดลับดังกล่าวโดยทั่วไป
Nick Cox

คำตอบ:


11

มันเป็นรูปแบบที่ไม่ดีในการเรียงลำดับอาร์เรย์เพื่อคำนวณค่ามัธยฐาน Medians (และ quantiles อื่น ๆ ) โดยทั่วไปจะคำนวณโดยใช้อัลกอริทึมquickselectโดยมีความซับซ้อนO(n)

นอกจากนี้คุณยังอาจต้องการที่จะมองไปที่คำตอบของฉันคำถามที่เกี่ยวข้องเมื่อเร็ว ๆ นี้ที่นี่


7

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


1
ลิงก์ใช้งานไม่ได้และไม่มีข้อมูลชื่อหรือผู้แต่งยากที่จะหาสิ่งที่อ้างถึง
Kristopher Johnson


6

หากคุณยินดีที่จะยอมรับการประมาณมีวิธีอื่น ๆ ตัวอย่างเช่นการประมาณหนึ่งค่าที่มีอันดับอยู่ภายในระยะห่าง (ผู้ใช้ระบุ) บางส่วนจากค่ามัธยฐานที่แท้จริง ตัวอย่างเช่นค่ามัธยฐานมี (ปกติ) อันดับที่ 0.5 และหากคุณระบุข้อกำหนดข้อผิดพลาดที่ 10% คุณจะต้องการคำตอบที่มีอันดับระหว่าง 0.45 ถึง 0.55

หากคำตอบดังกล่าวเหมาะสมแล้วมีวิธีแก้ปัญหามากมายที่สามารถทำงานกับหน้าต่างเลื่อนของข้อมูลได้ แนวคิดพื้นฐานคือการรักษาตัวอย่างข้อมูลขนาดที่แน่นอน (ประมาณ 1 / คำผิดพลาด) และคำนวณค่ามัธยฐานในตัวอย่างนี้ มันสามารถแสดงให้เห็นได้ว่ามีความน่าจะเป็นสูงโดยไม่คำนึงถึงลักษณะของสัญญาณเข้า

ดังนั้นคำถามหลักคือวิธีการรักษาตัวอย่างการรันข้อมูลขนาดที่แน่นอนและมีวิธีการมากมายที่รวมถึงเทคนิคที่เรียกว่าการสุ่มตัวอย่างอ่างเก็บน้ำ ตัวอย่างเช่นกระดาษนี้: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.24.7136


4

หากคุณรักษาหน้าต่างความยาวของข้อมูลเป็นรายการเชื่อมโยงที่เรียงลำดับแล้วโดยใช้การค้นหาแบบไบนารี (เพื่อแทรกองค์ประกอบใหม่แต่ละรายการตามที่ได้รับการเลื่อนเข้าไปในหน้าต่าง) และอาร์เรย์แบบวงกลมของตัวชี้ (เพื่อค้นหาองค์ประกอบที่ จำเป็นต้องลบ) การเลื่อนแต่ละครั้งของหน้าต่างต้องใช้ความพยายาม O (log (k)) สำหรับการแทรกองค์ประกอบเดียวเท่านั้นมีความพยายาม O (1) สำหรับการลบองค์ประกอบที่เลื่อนออกจากหน้าต่างและมีเพียงความพยายาม O (1) ในการค้นหา ค่ามัธยฐาน (เพราะทุกครั้งที่มีการแทรกหรือลบองค์ประกอบหนึ่งในรายการคุณสามารถอัปเดตตัวชี้ไปยังค่ามัธยฐานในเวลา O (1)) ความพยายามทั้งหมดสำหรับการประมวลผลอาร์เรย์ของความยาว N จึงเป็น O ((nk) log (k)) <= O (n log (k)) นี่ดีกว่าวิธีอื่น ๆ ที่เสนอมาจนถึงตอนนี้และมันไม่ได้เป็นการประมาณมันแน่นอน


1
คุณสามารถอธิบายรายละเอียดเกี่ยวกับวิธีที่คุณเสนอให้ทำการค้นหาแบบไบนารีในรายการที่เชื่อมโยงเป็นสองเท่าที่เรียงลำดับได้หรือไม่?
NPE

ลิงก์ 'หนึ่ง' ช่วยให้คุณสำรวจรายการตามลำดับที่เรียงไว้ อีกอันหนึ่งอนุญาตให้คุณสำรวจตามลำดับที่องค์ประกอบปรากฏ ยังไม่ชัดเจนว่าคุณจะทำอย่างไรกับพอยน์เตอร์เช่นเดียวกับ @aix คำถาม
shabbychef

2
@aix ฉันคิดว่าความรักของคุณถูกต้องแล้ว ฉันต้องการรายการข้ามที่สามารถทำดัชนีได้ไม่ใช่เฉพาะรายการที่เชื่อมโยงเป็นสองเท่าเรียงลำดับ แนวคิดคือมีโครงสร้างข้อมูลที่อนุญาตการแทรกองค์ประกอบหนึ่งการลบองค์ประกอบหนึ่งและค้นหาค่ามัธยฐานในเวลา O (log (n)) ที่คาดหวัง (หรือดีกว่า)
whuber

3

ในขณะที่คุณกล่าวถึงการเรียงลำดับจะเป็นหน้าต่างของความยาว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)


2

หากคุณสามารถใช้ชีวิตอยู่กับการประมาณการแทนที่จะเป็นค่ามัธยฐานที่แท้จริงอัลกอริทึม Remedian (PDF)คือหนึ่งรอบที่มีข้อกำหนดด้านพื้นที่จัดเก็บต่ำและความแม่นยำที่กำหนดไว้ดี

การเยียวยาด้วยฐานขดำเนินการโดยการคำนวณค่ามัธยฐานของกลุ่มการสังเกต b จากนั้นค่ามัธยฐานของค่ามัธยฐานเหล่านี้จนกระทั่งเหลือเพียงค่าประมาณเดียว วิธีนี้ต้องการเพียง k อาร์เรย์ที่มีขนาด b (โดยที่ n = b ^ k) ...


0

ฉันใช้ไลบรารี RunStats C ++ นี้ในแอปพลิเคชันแบบฝัง มันเป็นห้องสมุดสถิติการทำงานที่ง่ายที่สุดที่ฉันได้พบ

จากลิงค์:

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


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