ในระหว่างที่คิดถึงปัญหาหนึ่งฉันรู้ว่าฉันต้องสร้างอัลกอริทึมที่มีประสิทธิภาพในการแก้ไขงานต่อไปนี้:
ปัญหา:เราได้รับกล่องสี่เหลี่ยมสองมิติของด้านซึ่งด้านขนานกับแกน เราสามารถตรวจสอบมันผ่านด้านบน อย่างไรก็ตามยังมีส่วนแนวนอนแต่ละเซกเมนต์มีจำนวนเต็ม -coordinate ( ) และ -coordinates ( ) และเชื่อมต่อจุดและ (ดูที่ ภาพด้านล่าง)
เราอยากทราบว่าแต่ละเซ็กเมนต์ที่ด้านบนของกล่องเราจะมองลึกเข้าไปในแนวตั้งได้อย่างไรถ้ามองผ่านเซ็กเมนต์นี้
อย่างเป็นทางการสำหรับเราต้องการหาy_i
ตัวอย่าง: รับและกลุ่มตั้งอยู่ในภาพด้านล่างผลที่ได้คือ7) ดูว่าแสงที่ลึกสามารถเข้าไปในกล่องได้
โชคดีสำหรับเราทั้งและมีขนาดค่อนข้างเล็กและเราสามารถทำการคำนวณแบบออฟไลน์ได้
อัลกอริธึมที่ง่ายที่สุดในการแก้ปัญหานี้คือแรงเดรัจฉาน: สำหรับแต่ละเซกเมนต์เคลื่อนที่อาร์เรย์ทั้งหมดและอัพเดตในกรณีที่จำเป็น แต่ก็จะช่วยให้เราไม่ได้น่าประทับใจมาก(ล้านบาท)
การปรับปรุงที่ดีมากคือการใช้แผนภูมิส่วนซึ่งสามารถเพิ่มค่าสูงสุดในส่วนในระหว่างการค้นหาและอ่านค่าสุดท้าย ผมจะไม่อธิบายมันต่อไป แต่เราจะเห็นว่าเวลาซับซ้อนคือn)
อย่างไรก็ตามฉันคิดอัลกอริทึมที่เร็วกว่า:
เค้าร่าง:
เรียงลำดับเซ็กเมนต์ตามลำดับที่ลดลงของ -coordinate (เวลาเชิงเส้นโดยใช้รูปแบบการเรียงลำดับการนับ) โปรดทราบว่าหากส่วนใดส่วนหนึ่งของหน่วยถูกครอบคลุมโดยส่วนใด ๆ ก่อนหน้านี้จะไม่มีส่วนต่อไปนี้ที่สามารถผูกลำแสงผ่านกลุ่มส่วนหน่วยนี้ จากนั้นเราจะทำการกวาดบรรทัดจากด้านบนไปด้านล่างของกล่องx x
ทีนี้เราจะมาแนะนำนิยาม: -unit เซ็กเมนต์เป็นส่วนแนวนอนจินตภาพในการกวาดซึ่ง -coordinates เป็นจำนวนเต็มและความยาวเท่ากับ 1 แต่ละเซกเมนต์ในระหว่างกระบวนการกวาดอาจไม่ถูกทำเครื่องหมาย (นั่นคือลำแสงจาก ด้านบนของกล่องสามารถเข้าถึงกลุ่มนี้) หรือทำเครื่องหมาย (กรณีตรงข้าม) พิจารณากลุ่ม -unit ที่มี ,ไม่ได้ทำเครื่องหมายเสมอ Let 's ยังแนะนำชุด\} แต่ละชุดจะมีลำดับทั้งหมดของเซ็กเมนต์ -unit ที่ทำเครื่องหมายติดต่อกัน(หากมี) ที่มีเครื่องหมายต่อไปนี้x x x 1 = n x 2 = n + 1 S 0 = { 0 } , S 1 = { 1 } , … , S n = { n } x ส่วน
เราต้องการโครงสร้างข้อมูลที่สามารถใช้งานในเซกเมนต์เหล่านี้และตั้งค่าได้อย่างมีประสิทธิภาพ เราจะใช้โครงสร้าง find-union ที่ขยายโดยฟิลด์ที่เก็บดัชนีเซ็กเมนต์ -unit สูงสุด(ดัชนีของเซ็กเมนต์ที่ไม่ได้ทำเครื่องหมาย )
ตอนนี้เราสามารถจัดการส่วนต่างๆได้อย่างมีประสิทธิภาพ สมมติว่าตอนนี้เรากำลังพิจารณาส่วน -th ในการสั่งซื้อ (เรียกว่า "แบบสอบถาม") ซึ่งจะเริ่มขึ้นในและสิ้นสุดในx_2เราจำเป็นต้องค้นหาเซกเมนต์ -unit ที่ไม่ได้ทำเครื่องหมายซึ่งอยู่ในเซ็กเมนต์ th (นี่คือเซกเมนต์ที่ลำแสงจะสิ้นสุดลง) เราจะทำสิ่งต่อไปนี้: อันดับแรกเราจะพบกลุ่มที่ไม่มีเครื่องหมายในแบบสอบถาม ( ค้นหาตัวแทนของชุดที่มีอยู่และรับดัชนีสูงสุดของชุดนี้ซึ่งเป็นส่วนที่ไม่ได้ทำเครื่องหมายตามคำจำกัดความ ) จากนั้นดัชนีนี้x 1 x 2 x ฉันx 1 x y x x + 1 x ≥ x 2 อยู่ในแบบสอบถามให้เพิ่มลงในผลลัพธ์ (ผลลัพธ์สำหรับส่วนนี้คือ ) และทำเครื่องหมายดัชนีนี้ ( ชุดยูเนี่ยนที่มีและ ) แล้วทำซ้ำขั้นตอนนี้จนกว่าเราจะพบว่าทุกป้ายส่วนที่เป็นต่อไปค้นหาแบบสอบถามจะช่วยให้เราดัชนีx_2
โปรดทราบว่าการดำเนินการค้นหาสหภาพจะดำเนินการในสองกรณีเท่านั้น: เราเริ่มพิจารณาเซ็กเมนต์ (ซึ่งอาจเกิดขึ้นครั้ง) หรือเราเพิ่งทำเครื่องหมายเซ็กเมนต์ -unit (สิ่งนี้สามารถเกิดขึ้นได้ครั้ง) ดังนั้นความซับซ้อนโดยรวมคือ (เป็นฟังก์ชัน Ackermann แบบผกผัน ) หากสิ่งที่ไม่ชัดเจนฉันสามารถอธิบายเพิ่มเติมเกี่ยวกับเรื่องนี้ บางทีฉันอาจจะสามารถเพิ่มรูปภาพได้ถ้าฉันมีเวลาx n O ( ( n + m ) α ( n ) ) α
ตอนนี้ฉันมาถึง "กำแพง" ฉันไม่สามารถคิดอัลกอริธึมเชิงเส้นได้ แต่ดูเหมือนว่าควรมีอย่างใดอย่างหนึ่ง ดังนั้นฉันมีสองคำถาม:
- มีอัลกอริธึมเชิงเส้นเวลา (นั่นคือ ) ในการแก้ปัญหาการมองเห็นส่วนแนวนอนหรือไม่?
- หากไม่เป็นเช่นนั้นอะไรคือข้อพิสูจน์ว่าปัญหาการมองเห็นคือ ?