อัลกอริทึมของ Fortune

อัลกอริทึมของ Fortuneเป็นอัลกอริทึมแบบกวาดเส้นสำหรับการสร้างแผนภาพ Voronoiจากชุดจุดในระนาบโดยใช้ เวลา O ( n log n ) และ พื้นที่O( n ) [ 1 ] [ 2 ]เดิมทีได้รับการตีพิมพ์โดยSteven Fortuneในปี 1986 ในบทความของเขาเรื่อง "A sweepline algorithm for Voronoi diagrams" [ 3 ]
คำอธิบายอัลกอริธึม
อัลกอริทึมนี้รักษาทั้งเส้นกวาด (sweep line)และเส้นชายหาด (beach line)ซึ่งทั้งสองเส้นจะเคลื่อนที่ผ่านระนาบขณะที่อัลกอริทึมดำเนินไป เส้นกวาดเป็นเส้นตรง ซึ่งเราอาจสมมติโดยทั่วไปว่าเป็นเส้นแนวตั้งและเคลื่อนที่จากซ้ายไปขวาบนระนาบ ในช่วงเวลาใด ๆ ระหว่างการทำงานของอัลกอริทึม จุดข้อมูลที่อยู่ทางซ้ายของเส้นกวาดจะถูกรวมเข้าในแผนภาพโวโรนอยแล้ว ในขณะที่จุดที่อยู่ทางขวาของเส้นกวาดจะยังไม่ถูกพิจารณา เส้นชายหาดไม่ใช่เส้นตรง แต่เป็นเส้นโค้งที่ซับซ้อนและเป็นชิ้นส่วนอยู่ทางซ้ายของเส้นกวาด ประกอบด้วยชิ้นส่วนของพาราโบลามันแบ่งส่วนของระนาบที่สามารถทราบแผนภาพโวโรนอยได้ โดยไม่คำนึงถึงจุดอื่น ๆ ที่อาจอยู่ทางขวาของเส้นกวาด ออกจากส่วนที่เหลือของระนาบ สำหรับแต่ละจุดทางซ้ายของเส้นกวาด เราสามารถกำหนดพาราโบลาของจุดที่อยู่ห่างจากจุดนั้นและจากเส้นกวาดเท่ากันได้ เส้นชายหาดเป็นขอบเขตของการรวมกันของพาราโบลาเหล่านี้ เมื่อเส้นกวาดเคลื่อนที่ไปเรื่อยๆ จุดยอดของเส้นขอบที่พาราโบลาสองเส้นตัดกัน จะลากเส้นขอบของแผนภาพโวโรนอย เส้นขอบจะเคลื่อนที่ไปโดยรักษาระยะฐานของพาราโบลาแต่ละอันให้อยู่กึ่งกลางระหว่างจุดที่เส้นกวาดผ่านในตอนแรกกับตำแหน่งใหม่ของเส้นกวาด ในทางคณิตศาสตร์ หมายความว่าพาราโบลาแต่ละอันถูกสร้างขึ้นโดยใช้เส้นกวาดเป็นเส้นไดเรกทริกซ์และจุดเริ่มต้นเป็นจุดโฟกัส
อัลกอริทึมนี้เก็บรักษาโครงสร้างข้อมูลเป็นต้นไม้ค้นหาแบบไบนารีที่อธิบายโครงสร้างเชิงผสมของเส้นชายหาด และคิวลำดับความสำคัญที่แสดงรายการเหตุการณ์ในอนาคตที่อาจเปลี่ยนแปลงโครงสร้างของเส้นชายหาด เหตุการณ์เหล่านี้รวมถึงการเพิ่มพาราโบลาอีกอันให้กับเส้นชายหาด (เมื่อเส้นกวาดตัดกับจุดอินพุตอื่น) และการลบเส้นโค้งออกจากเส้นชายหาด (เมื่อเส้นกวาดสัมผัสกับวงกลมที่ผ่านจุดอินพุตสามจุดซึ่งพาราโบลาของจุดเหล่านั้นเป็นส่วนต่อเนื่องของเส้นชายหาด) แต่ละเหตุการณ์ดังกล่าวอาจได้รับการจัดลำดับความสำคัญโดย พิกัด xของเส้นกวาด ณ จุดที่เหตุการณ์เกิดขึ้น จากนั้นอัลกอริทึมจะประกอบด้วยการลบเหตุการณ์ถัดไปออกจากคิวลำดับความสำคัญซ้ำๆ การค้นหาการเปลี่ยนแปลงที่เหตุการณ์นั้นก่อให้เกิดในเส้นชายหาด และการอัปเดตโครงสร้างข้อมูล
เนื่องจากมีเหตุการณ์ O( n ) ที่ต้องประมวลผล (แต่ละเหตุการณ์เกี่ยวข้องกับคุณลักษณะบางอย่างของแผนภาพโวโรนอย) และใช้เวลา O(log n ) ในการประมวลผลแต่ละเหตุการณ์ (แต่ละเหตุการณ์ประกอบด้วยการดำเนินการต้นไม้ค้นหาแบบไบนารีและคิวลำดับความสำคัญจำนวนคงที่) ดังนั้นเวลาทั้งหมดจึงเป็น O( n log n )
รหัสเทียม
คำอธิบาย รหัสเทียมของอัลกอริทึม[ 4 ]
อนุญาตเป็นการเปลี่ยนแปลง, ที่ไหนคือระยะทางแบบยุคลิดระหว่างzกับไซต์ที่ใกล้ที่สุด ให้T เป็น "แนวชายหาด" ให้ เป็นบริเวณที่ครอบคลุมโดยไซต์pให้เป็นรังสีขอบเขตระหว่างไซต์pและqให้ ให้ เป็นชุดของไซต์ที่จะนำอัลกอริธึมนี้ไปใช้ ให้ให้ X เป็นไซต์ที่สกัดจากS ที่มีพิกัด yน้อยที่สุดเรียงลำดับตามพิกัด x ให้ DeleteMin( X ) เป็นการกระทำในการลบไซต์ที่ต่ำที่สุดและซ้ายสุดของX (เรียงลำดับตาม y เว้นแต่ว่าไซต์ทั้งสองจะเหมือนกัน ในกรณีนั้นให้เรียงลำดับตาม x) ให้Vเป็นแผนที่โวโรนอยของSที่จะสร้างขึ้นโดยอัลกอริทึมนี้ สร้างรังสีขอบเขตแนวตั้งเริ่มต้นในขณะที่ Q ไม่ว่างเปล่าให้ ลบ ค่าต่ำสุดของQ ออกหากp ของpเป็นไซต์ใน: ค้นหาการปรากฏของภูมิภาคในTที่มีp อยู่ ถูกล้อมกรอบโดยทางด้านซ้ายและทางด้านขวา สร้างรังสีขอบเขตใหม่และโดยใช้ฐานp แทนที่กับในT ให้ลบ ส่วนที่ทับซ้อนกันทั้งหมดออกจากQและแทรก จุดตัดใดๆ ระหว่าง ลงใน Qและแทรก จุดตัดใดๆ ระหว่าง ลงใน Qและpเป็นจุดยอดโวโรนอยในให้ p เป็นจุดตัดของทางด้านซ้ายและทางด้านขวา ให้เป็นเพื่อนบ้านทางซ้ายของและ ปล่อยให้เป็นเพื่อนบ้านที่ดีของในT ถ้าสร้าง รังสีขอบเขตใหม่มิฉะนั้น ถ้าpอยู่ทางขวาของค่าที่สูงกว่าระหว่างqและsให้ สร้างมิฉะนั้นสร้าง แทนที่endifด้วยการสร้างใหม่ในT ให้ลบ ส่วนที่ทับซ้อนกันทั้งหมดออกจากQและ ลบ จุดตัดใดๆ ระหว่าง Q ออกจากQและแทรก จุดตัดใดๆ ระหว่าง ลงใน Qและแทรก จุดตัดใดๆ ระหว่าง ลงใน Qและ บันทึกpเป็นจุดสูงสุดของและและฐานของ ส่งออกส่วนขอบเขตและendcase endwhile ส่งออกรังสีขอบเขตที่เหลือในT
ไซต์และดิสก์ที่มีน้ำหนัก
ไซต์ที่มีน้ำหนักแบบบวก
ตามที่ Fortune อธิบายไว้ในเอกสารอ้างอิง[ 1 ]เวอร์ชันที่แก้ไขของอัลกอริทึมเส้นกวาดสามารถใช้สร้างแผนภาพ Voronoi ที่ถ่วงน้ำหนัก แบบบวกได้ โดยที่ระยะทางไปยังแต่ละไซต์จะถูกชดเชยด้วยน้ำหนักของไซต์ ซึ่งอาจมองได้ว่าเป็นแผนภาพ Voronoi ของชุดดิสก์ที่มีจุดศูนย์กลางอยู่ที่ไซต์และมีรัศมีเท่ากับน้ำหนักของไซต์ พบว่าอัลกอริทึมมีความซับซ้อนของเวลาโดยที่ n คือจำนวนไซต์ตามอ้างอิง[ 1 ]
อาจใช้ไซต์ที่มีน้ำหนักเพื่อควบคุมพื้นที่ของเซลล์โวโรนอยเมื่อใช้แผนภาพโวโรนอยในการสร้างแผนที่ต้นไม้ในแผนภาพโวโรนอยที่มีน้ำหนักแบบบวก เส้นแบ่งครึ่งระหว่างไซต์โดยทั่วไปจะเป็นไฮเปอร์โบลา ซึ่งแตกต่างจากแผนภาพโวโรนอยที่ไม่มีน้ำหนักและแผนภาพกำลังของดิสก์ซึ่งเส้นแบ่งครึ่งจะเป็นเส้นตรง
ลิงก์ภายนอก
- การใช้งาน C ของ Steven Fortune
- อัลกอริทึม Voronoi ของ Fortune ที่เขียนด้วยภาษา C++
- อัลกอริทึมของ Fortune ที่เขียนด้วย JavaScriptถูกเก็บไว้ใน GitHub ตั้งแต่เดือนสิงหาคม 2558
- การเข้าถึง การแสดงภาพอัลกอริทึมของ Fortuneณ ปี 2025 ถูกบล็อกแล้ว