คำถามมากเกินไปในครั้งเดียวดังนั้นจึงยากที่จะให้คำตอบที่เป็นรูปธรรม แต่เพื่อหารือเกี่ยวกับหัวข้อเหล่านี้บางส่วน ฉันจะแบ่งคำตอบออกเป็นสองข้อและพยายามพูดให้ดีที่สุดเท่าที่จะทำได้ ฉันไม่ได้อ้างว่ารายการใด ๆ เหล่านี้จะเสร็จสมบูรณ์แต่เป็นวิธีการต่าง ๆ ที่ฉันจำได้
ส่วนที่ 1 - อัลกอริทึมการทำให้เข้าใจผิด
สำหรับผู้เริ่มต้นมีหลายวิธีในการใช้การค้นหาเส้นทาง แต่ไม่ใช่ทั้งหมดที่ส่งคืนเส้นทางที่สั้นที่สุดหรือมีประสิทธิภาพหรือเชื่อถือได้ ตัวอย่างเช่น
วิธีการดั้งเดิมที่ไม่ "มองไปข้างหน้า" และทำทีละขั้นตอน:
การ backstepping แบบสุ่ม - ดำเนินการทีละขั้นในทิศทางของเป้าหมาย หากพบสิ่งกีดขวางให้พยายามหลีกเลี่ยงโดยการถอยกลับเล็กน้อยในทิศทางที่สุ่มแล้วลองอีกครั้ง ไม่น่าเชื่อถือเลยและจะติดอยู่ในสถานการณ์ที่หลากหลาย
Obstacle tracing - วิธีอื่น ๆ คล้ายกับ backstepping แบบสุ่ม แต่แทนที่จะเคลื่อนที่กลับแบบสุ่มให้เริ่มการติดตามรอบ ๆ วัตถุเมื่อพบการชนราวกับว่าคุณมีมือขวาติดอยู่กับกำแพงและต้องขยับสัมผัส เมื่อไม่มีการชนกันอย่างต่อเนื่องเคลื่อนที่ไปในทิศทางของเป้าหมาย อีกครั้งสามารถติดในหลาย ๆ สถานการณ์
วิธีการที่มองไปข้างหน้าเพื่อค้นหาเส้นทางทั้งหมดในครั้งเดียว:
การค้นหาครั้งแรกกว้าง - สำรวจกราฟอย่างง่ายโดยไปที่ชั้นของเด็กแต่ละครั้งหยุดเมื่อพบเส้นทาง หากกราฟไม่มีการถ่วงน้ำหนัก (เช่นระยะห่างระหว่างแต่ละโหนดที่อยู่ติดกันจะเท่ากันเสมอ) จะพบเส้นทางที่สั้นที่สุดแม้ว่าจะไม่ได้ประสิทธิภาพมากเกินไป สำหรับกราฟที่มีน้ำหนักถ่วงน้ำหนักมันอาจไม่ส่งคืนพา ธ ที่สั้นที่สุด แต่จะหาได้หากมีอยู่
การค้นหาความลึกครั้งแรก - อีกวิธีหนึ่งในการสำรวจกราฟ แต่แทนที่จะเอามันเป็นชั้น ๆ เลเยอร์อัลกอริทึมจะพยายามค้นหาลึกลงไปในกราฟก่อน วิธีนี้อาจมีปัญหาหากความลึกของการค้นหาไม่ จำกัด โดยเฉพาะอย่างยิ่งเมื่อใช้การใช้งานแบบเรียกซ้ำซึ่งอาจนำไปสู่การโอเวอร์โฟลว์สแต็กดังนั้นจึงมักจะปลอดภัยกว่าในการติดตั้งซ้ำ ๆ
การค้นหาครั้งแรกที่ดีที่สุด - คล้ายกับการค้นหาแบบกว้างครั้งแรก แต่ใช้การวิเคราะห์พฤติกรรมที่เลือกเพื่อนบ้านที่มีแนวโน้มมากที่สุดก่อน เส้นทางที่ส่งคืนอาจไม่สั้นที่สุด แต่จะเร็วกว่าการค้นหาแบบกว้างครั้งแรก A * เป็นประเภทของการค้นหาครั้งแรกที่ดีที่สุด
วิธีการของ Dijkstra - ติดตามค่าใช้จ่ายทั้งหมดตั้งแต่เริ่มต้นจนถึงทุกโหนดที่เข้าชมและใช้เพื่อกำหนดลำดับที่ดีที่สุดในการสำรวจกราฟ ทำงานกับกราฟถ่วงน้ำหนักและส่งคืนเส้นทางที่สั้นที่สุด แต่อาจเกี่ยวข้องกับการค้นหาจำนวนมาก
A * - คล้ายกับ Dijkstra แต่ใช้ฮิวริสติกเพื่อประเมินความเป็นไปได้ที่แต่ละโหนดจะใกล้เคียงกับเป้าหมายเพื่อที่จะทำการตัดสินใจที่ดีที่สุด ด้วยเหตุนี้ฮิวริสติก A จึงค้นหาเส้นทางที่สั้นที่สุดในกราฟถ่วงน้ำหนักในเวลาที่เหมาะสมกว่า
จากนั้นจะมีการเปลี่ยนแปลงของ A * (หรือการปรับแต่งการหาเส้นทางโดยทั่วไป) ที่ทำให้มันเร็วขึ้นหรือปรับให้เข้ากับสภาพแวดล้อมบางอย่างเช่น (ดูคำตอบที่เกี่ยวข้องและรายการที่ครอบคลุมใน cstheory.SE ):
- LPA * - คล้ายกับ A * แต่สามารถคำนวณเส้นทางที่ดีที่สุดได้อย่างรวดเร็วยิ่งขึ้นเมื่อมีการเปลี่ยนแปลงกราฟเล็กน้อย
- D * Lite - ขึ้นอยู่กับ LPA * มันทำสิ่งเดียวกัน แต่สมมติว่า "จุดเริ่มต้น" เป็นหน่วยเคลื่อนที่ไปสู่เส้นชัยในขณะที่มีการเปลี่ยนแปลงกราฟ
- HPA * (ลำดับชั้น) - ใช้หลายเลเยอร์ที่ระดับ abstraction ที่แตกต่างกันเพื่อเพิ่มความเร็วในการค้นหา ยกตัวอย่างเช่นเลเยอร์เลเวลที่สูงกว่านั้นอาจเชื่อมต่อห้องต่างๆในขณะที่เลเยอร์เลเยอร์ที่ต่ำกว่าจะคอยดูแลหลีกเลี่ยงอุปสรรค
- IDA * (Iterative Deepening) - ลดการใช้หน่วยความจำโดยเปรียบเทียบกับ A * ปกติโดยใช้การทำซ้ำลึก
- SMA * (ขอบเขตของหน่วยความจำแบบง่าย) - ใช้เฉพาะหน่วยความจำที่มีอยู่เพื่อดำเนินการค้นหา
- ค้นหาจุดกระโดด - มอบเครดิตให้แก่ Eric ในการแสดงความคิดเห็นเพื่อพูดถึงมัน! เพิ่มความเร็วการค้นหาเส้นทางบนแผนที่กริดต้นทุนสม่ำเสมอ ( ลิงค์ )
ส่วนที่ 2 - การแทน Space Search
และสุดท้ายเพื่อตอบคำถามนี้:
ฉันรู้ว่า A * เป็นเหมือนอัลกอริทึมที่ใช้ในเกม 2D นั่นยอดเยี่ยมและทั้งหมด แต่เกมแบบ 2D ที่ไม่อิงกับกริดเป็นอย่างไร
ความเข้าใจผิดครั้งใหญ่สองประการที่นี่! ในความเป็นจริง:
- A * ไม่สนใจว่าเกมนั้นเป็น 2D หรือ 3D และมีความเหมาะสมเท่าเทียมกันสำหรับทั้งสองกรณี
- A * ทำงานภายใต้การแสดงกราฟใด ๆดังนั้นจึงไม่สนใจว่าโลกจะเป็นกริดหรือไม่
ดังนั้นหากโลกไม่จำเป็นต้องเป็นกริดคุณสามารถเป็นตัวแทนในรูปแบบอื่นได้อีกบ้าง? ต่อไปนี้เป็นภาพรวมโดยย่อเกี่ยวกับวิธีแบ่งพาร์ติชันของพื้นที่โลกสำหรับการหาเส้นทางและส่วนใหญ่ของงานเหล่านี้ทั้งสำหรับ 2D และ 3D:
Rectangular grid - แบ่งพาร์ติชันออกเป็นกริดสแควร์ปกติโดยแต่ละเซลล์ในกริดนั้นเป็นหนึ่งโหนดในกราฟและการเชื่อมต่อระหว่างสองโหนดที่ไม่มีสิ่งกีดขวางนั้นเป็นขอบ
Quadtree - อีกวิธีในการแบ่งพื้นที่ แต่แทนที่จะแบ่งพาร์ติชันเป็นกริดของเซลล์ที่มีขนาดปกติให้แบ่งพาร์ติชันเป็นสี่พาร์ติชันแล้วแบ่งพาร์ติชันเหล่านี้ออกเป็นสี่ส่วนอีกครั้ง เพิ่มมิติที่สามทำให้octree
รูปหลายเหลี่ยมนูน - การแบ่งพื้นที่ที่สามารถเดินได้เข้าไปในตาข่ายของรูปหลายเหลี่ยมนูนที่เชื่อมต่อถึงกัน รูปหลายเหลี่ยมแต่ละอันจะกลายเป็นโหนดและขอบที่แบ่งปันคือขอบของกราฟ ตัวอย่างเหล่านี้สามารถเป็นรูปสามเหลี่ยมได้และบางครั้งอาจเป็นตาข่ายที่สร้างโดยศิลปินเมื่อสร้างสินทรัพย์ระดับ มักจะเรียกว่าเป็นตาข่ายนำทาง ดูลิงค์นี้ ต่อไปนี้เป็นที่นิยมมากตาข่ายนำทางชุดเครื่องมือก่อสร้าง: แต่งใหม่
จุดที่มองเห็น - วิธีที่พบมากที่สุดคือการวางโหนดที่อยู่ด้านนอกของจุดยอดนูนของสิ่งกีดขวางจากนั้นเชื่อมต่อแต่ละคู่ของโหนดที่สามารถมองเห็นซึ่งกันและกัน ตรวจสอบลิงค์นี้ โหนดไม่จำเป็นต้องเป็นจุดยอดและสามารถวางด้วยตนเองโดยนักออกแบบในแผนที่ ในกรณีที่ระบบมักถูกเรียกว่ากราฟ waypoint