การรับรู้สถานการณ์ในการค้นหาเส้นทาง


11

สมมติว่าคุณต้องหาเส้นทางที่สั้นที่สุดผ่านดันเจี้ยนซึ่งมีบางข้อความที่เปิดให้คุณหลังจากที่รวบรวมสิ่งของบางอย่างเช่นประตูและกุญแจที่ถูกล็อคเป็นต้น

ปฏิกิริยาทางเดินอาหารปกติต่อคำว่า "เส้นทางที่สั้นที่สุด" จะเป็น A * อย่างชัดเจน แต่ A * จะล้มเหลวในสภาพแวดล้อมเช่นนี้เนื่องจากฉันเห็นปัญหามากมายที่กำหนดฮิวริสติกที่เชื่อถือได้และยิ่งมีความเป็นไปได้มากที่โหนดจะต้องเข้าชมหลายครั้งซึ่งเป็นไปไม่ได้ใน A * แบบเดิมและก็จะ ทำให้ฮิวริสติกหนักขึ้น

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

ปัญหาใหญ่ที่ฉันเห็นด้วยวิธีแก้ปัญหาของฉันคือหลังจากพบเส้นทางทั้งหมดรวมถึงเส้นทางสำหรับการรับไอเท็มระยะทางทั้งหมดที่ตัวแทนเดินทางอาจไม่ได้น้อยที่สุดเนื่องจากอาจมีประตูปิดกั้นอื่น ๆ ที่อยู่ไกลกว่าเป้าหมาย แต่มีรหัสที่เหมาะสมของพวกเขาใช้ได้ง่ายขึ้นมาก A * จะละเลยประตูเหล่านี้ในการผ่านครั้งแรกที่มีการเพิกเฉยต่อประตูที่ถูกบล็อก

ฉันแน่ใจว่าฉันไม่ใช่คนแรกที่พยายามแก้ไขปัญหานี้และขอขอบคุณที่ป้อนข้อมูลเกี่ยวกับปัญหา


ฉันไม่รู้ว่าจะใช้งาน A * ปกติได้อย่างไร แต่ฉันเห็นการใช้งานที่มีเส้นทางหลากหลายมีระดับ "น้ำหนัก" ซึ่งจะเปลี่ยนเส้นทางที่น่าสนใจต่าง ๆ คุณไม่สามารถคำนวณเส้นทางที่เป็นไปได้ทั้งหมดจากนั้นตั้งค่า "น้ำหนัก" ของเส้นทางที่ข้ามประตูที่ถูกล็อกไปเป็นค่าอินฟินิตี้ที่เป็นบวกหรือไม่ นี่จะทำให้เส้นทางนั้นดูยาวมากและไม่เคยใช้ นี่เป็นหลักสูตรที่มีผลบังคับใช้หากคุณคำนวณเส้นทางล่วงหน้าแทนการทำเพื่อแต่ละเอนทิตีแต่ละครั้งที่อัพเดต
William Mariager

ขอบคุณสำหรับการตอบกลับ แต่สิ่งที่คุณลืมคือการปลดล็อกประตูอาจเป็นวิธีเดียวที่จะไปยังโหนดเป้าหมายซึ่งในกรณีนี้อัลกอริทึมที่คุณกล่าวถึงจะไม่พบเส้นทาง หรือถ้าน้ำหนักของเส้นทางที่ถูกบล็อกนั้นไม่มีที่สิ้นสุดเพียงแค่นั้นมันจะเลือกหนึ่งในเส้นทางที่ถูกบล็อกและยืนต่อหน้าปัญหาเดิมของฉัน
Marc Müller

คำตอบ:


8

วิธีจัดการสถานการณ์ดังกล่าวอย่างเหมาะสมโดยใช้ A * ที่ตรงไปตรงมาคือการขยายพื้นที่การค้นหา นั่นคือจินตนาการว่ามีสำเนาของดันเจี้ยนแยกต่างหากสำหรับแต่ละรายการที่ตัวละครของคุณอาจถืออยู่

ในแต่ละกรุของดันเจี้ยนประตูที่ผ่านได้นั้นจะสามารถผ่านได้โดยใช้ชุดรายการที่เกี่ยวข้อง วิธีเดียวที่จะส่งผ่านจากดันเจี้ยนหนึ่งสำเนาไปยังอีกอันหนึ่งคือยืนบนตำแหน่งของรายการและหยิบมันขึ้นมา

คุณสามารถขยายเคล็ดลับนี้เพื่อรวมการเปลี่ยนแปลงสถานะอื่น ๆ เช่นสวิตช์ที่สามารถเปิดและ / หรือปิดประตู คุณสามารถอนุญาตให้ผู้เล่นวางไอเท็มได้แม้ว่าสิ่งนี้จะซับซ้อนเนื่องจากรัฐจะต้องรวมตำแหน่งของไอเท็มที่ดรอปแต่ละอันเพิ่มพื้นที่การค้นหาที่อาจเกิดขึ้นอย่างมากมาย

เพิ่มประสิทธิภาพมีประโยชน์มากคือการ precalculate เส้นทางที่สั้นที่สุดจากแต่ละประตู (ที่จริงแต่ละด้านของแต่ละประตู) และรายการที่จะสามารถเข้าถึงได้อื่น ๆ ทุกประตู / รายการสมมติว่าประตูทุกบานถูกล็อค เมื่อคุณมีเส้นทางเหล่านั้นคุณก็สามารถปฏิบัติต่อพวกมันเป็นขอบถ่วงน้ำหนักในกราฟที่เชื่อมต่อสถานที่สำคัญเหล่านี้กับแต่ละอื่น ๆ และละเว้นสถานที่อื่น ๆ ทั้งหมด

ตัวอย่างเช่นสมมติว่าคุกใต้ดินของคุณมีสิบประตูและห้าปุ่ม จากนั้นจะมี 2 * 10 + 5 = 25 ตำแหน่งสำคัญและ 2 ^ 5 = 32 รายการที่เป็นไปได้รวมกันทั้งหมด 25 * 32 = 800 โหนดในพื้นที่การค้นหาแบบเต็ม นี่เป็นตัวเลขที่ค่อนข้างมากโดยเฉพาะอย่างยิ่งเนื่องจากพื้นที่การค้นหาส่วนใหญ่ไม่สามารถเข้าถึงได้


5

จากมุมมองของโลกแห่งความเป็นจริง: ถ้าคุณมุ่งหน้าจาก A ถึง B และพบประตู D ในแบบของคุณที่ถูกล็อคคุณจะรู้ว่าคุณต้องพบกุญแจ D. ดังนั้นถ้า AI ของคุณไม่รู้เหมือนมนุษย์ทั่วไป ที่จะเกี่ยวข้องกับการหัวเราะเยาะสำหรับคีย์ซึ่งเป็นชุดของขั้นตอนการค้นหาเส้นทางเล็ก ๆ ในตัวของมันเอง ในอีกทางหนึ่งคุณอาจต้องการให้ AI ของคุณรู้ก่อนที่จะลองเส้นทางว่ามีประตูล็อคอยู่ในเส้นทางนั้นและในกรณีนั้นมันอาจจะรู้ด้วยว่าจะหากุญแจได้จากที่ไหน

ไม่ว่าจะด้วยวิธีใดปัญหาคือหนึ่งในการเชื่อมต่อที่สองระดับ ที่ระดับ "บนพื้นดิน" คุณรู้ว่าคุณสามารถเคลื่อนที่ได้อย่างปลอดภัยภายในหนึ่งโซนที่ไม่มีการแบ่งแยก ... แบ่งโดยประตูล็อคนั่นคือ นี่คือที่ที่คุณสามารถใช้การนำ A * pathfinding ไปใช้ได้อย่างอิสระ (ในตัวอย่างง่ายๆคุณจะเห็นโซนเป็นห้องเดี่ยวคุณไม่สามารถไปที่ห้องอื่นโดยไม่ต้องปลดล็อกประตูในความเป็นจริงมันอาจเป็นพื้นที่ทั้งหมดของคุกใต้ดินของคุณ) นี่คือรากฐานของคุณ เอนทิตี้ของการเคลื่อนไหว แต่มันเหมือนกับการเดินไปรอบ ๆ ด้วยสายตาที่ละห้อยแทนที่จะสำรวจพื้นที่รอบ ๆ ตัวคุณก่อน - คุณน่าจะเดินเข้าไปในเสาตะเกียง หรือในกรณีนี้ประตูล็อค ดังนั้นแผนที่ระดับพื้นดินที่ A * ของคุณทำงานอยู่จะต้อง จำกัด ผู้เล่นให้เคลื่อนไหวภายในโซนปัจจุบันเท่านั้น

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

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

มีความเป็นไปได้ว่ากุญแจที่ถูกค้นหานั้นอยู่ด้านหลังประตูล็อค ... และกุญแจไปที่ประตูนั้นก็เหมือนกัน ... และอื่น ๆ ที่อยู่ในอาการคลื่นไส้ นี่เป็นปัญหาการแก้ไขปัญหาการพึ่งพาและมีวิธีการแก้ไขปัญหานี้สองสามวิธีซึ่งหนึ่งในนั้นคือ Petri Nets ดูนี้กระดาษที่ยอดเยี่ยม

PS หากคุณกำลังสร้างดันเจี้ยนของคุณเป็นขั้นตอนจากนั้นคุณสามารถเก็บข้อมูลเกี่ยวกับการเรียงลำดับการพึ่งพาได้หากคุณทราบตำแหน่งเริ่มต้นของผู้เล่นแล้ว


2

ปฏิกิริยาทางเดินอาหารปกติต่อคำว่า "เส้นทางที่สั้นที่สุด" จะเป็น A * อย่างชัดเจน แต่ A * จะล้มเหลวในสภาพแวดล้อมเช่นนี้เนื่องจากฉันเห็นปัญหามากมายที่กำหนดฮิวริสติกที่เชื่อถือได้และยิ่งมีความเป็นไปได้มากที่โหนดจะต้องเข้าชมหลายครั้งซึ่งเป็นไปไม่ได้ใน A * แบบเดิมและก็จะ ทำให้ฮิวริสติกหนักขึ้น

ประการแรกฮิวริสติกที่ยอมรับได้ไม่จำเป็นต้องสมบูรณ์แบบ มันจะต้องดูถูกดูแคลนและจะต้องดีกว่าไม่มีอะไร เนื่องจากคุณทำงานด้วยระยะทางจริงดูเหมือนว่าอย่างน้อย A * จะช่วยได้บ้างและแม้ว่าฮิวริสติกจะไม่ปรับปรุงการค้นหามากนักก็อาจจะดีกว่าการค้นหาแบบกว้างครั้งแรก หรือคล้ายกัน

ประการที่สอง A * สามารถไปที่โหนดได้หลายครั้งเท่าที่คุณต้องการ โปรดจำไว้ว่า A * ไม่ใช่อัลกอริธึมการค้นหาพา ธ แต่เป็นอัลกอริทึมการค้นหา มันค้นหาผ่านรัฐ ในเกมเรามักจะเปรียบเทียบสถานะกับตำแหน่งเพราะเราไม่สนใจว่าคุณจะไปถึงรัฐนั้นได้อย่างไร - แค่เส้นทางสั้นแค่ไหนที่จะไปถึงที่นั่น อย่างไรก็ตามในปัญหาเช่นนี้สถานะคือการรวมกันของตำแหน่งบวกสถานะอื่น ๆ ที่เกี่ยวข้องเช่นกุญแจที่จัดขึ้น

อย่างไรก็ตามเป็นเรื่องจริงที่ภาวะแทรกซ้อนเหล่านี้จะย้าย A * จากขอบเขตของ 'ประสิทธิภาพสูง' ถึง 'จะสำเร็จ แต่อาจไม่อยู่ในช่วงเวลาที่ฉันต้องการ' เวลาที่คุณต้องการคืออะไร ในความเป็นจริงทำไมคุณต้องทำเช่นนี้ - คุณต้องการเส้นทางที่สั้นที่สุดหรือเส้นทางที่เหมาะสมพอสมควรหรือไม่?

สิ่งที่ฉันคิดคือเพียงแค่มองหาเส้นทางจากจุดเริ่มต้นของดันเจี้ยนไปยังจุดสิ้นสุดโดยไม่สนใจประตูที่ถูกบล็อก หลังจากพบเส้นทางนี้สำหรับประตูแต่ละบานที่ขวางทางของเราเส้นทางเพิ่มเติมที่ค้นหาคีย์ที่เหมาะสมและกลับไปที่ประตูจะถูกค้นหาและสำรวจก่อนที่จะถึงประตู

มันง่ายที่จะพิสูจน์ว่าระบบดังกล่าวจะไม่ดีพอ คุณจะเริ่มเส้นทางเพิ่มเติมจากที่ไหน หากจากจุดเริ่มต้นคุณจะเสียเวลาวางแผนเส้นทางเดิมไปที่ประตู หากจากจุดสิ้นสุดการวางกุญแจใกล้กับจุดเริ่มต้นหมายความว่าเส้นทางผ่านแผนที่สองครั้งเมื่อครั้งหนึ่งพอเพียง หากคุณลองและคำนวณคะแนนการผสานที่ดีที่สุดสำหรับเส้นทางไปและกลับจากประตูและเส้นทางเดิมนั่นจะให้ผลลัพธ์ที่ดีที่สุด แต่จะต้องใช้ทรัพยากรอย่างมากเนื่องจากจำนวนการเรียงสับเปลี่ยนและความยากลำบากในการค้นหาฮิวริสติก หากคุณเพิ่มคีย์หลาย ๆ ตัวลงในปัญหาคุณมีปัญหาพนักงานขายเดินทางซึ่งไม่ง่ายที่จะแก้ปัญหาอย่างมีประสิทธิภาพ

สิ่งที่ฉันจะลองถ้าเป็นไปได้ที่จะผ่อนคลายเกณฑ์ 'เส้นทางที่สั้นที่สุด' คือ:

  • สร้างกราฟระดับสูงซึ่งมีสถานที่สำคัญเท่านั้น - ตำแหน่งสำคัญตำแหน่งประตูตำแหน่งภายในพื้นที่ที่ถูกล็อคและจดบันทึกระยะห่างระหว่างเส้นตรง หากแผนที่ของคุณแบ่งออกเป็นห้องหรือสถานที่อื่น ๆ โดยสิ้นเชิงนั่นยอดเยี่ยมมาก
  • ใช้ A * เพื่อค้นหาเส้นทางผ่านกราฟนี้ตั้งแต่ต้นจนจบ ฮิวริสติกระยะทางคาร์ทีเซียนปกติควรเพียงพอที่จะจัดการได้
  • ตอนนี้ด้วยเส้นทางแบบง่าย ๆ ระหว่างจุดทางเหล่านี้ใช้ A * อีกครั้งเพื่อลงจุดเส้นทางระดับต่ำจากจุดทางเดียวไปยังจุดถัดไป
  • เข้าร่วมเส้นทางระดับต่ำเหล่านี้เพื่อสร้างเส้นทางทั้งหมดของคุณ

เมื่อฉันได้งานนั้นมาฉันจะพิจารณาการปรับให้เหมาะสมเล็กน้อยเช่น ถ่วงน้ำหนักพื้นที่ด้วยกุญแจอย่างผ่อนปรนมากขึ้นเพื่อให้เส้นทางในระดับต่ำมีแนวโน้มที่จะทำให้มีการออกนอกเส้นทางขนาดเล็กเพื่อรวบรวมกุญแจ


0

ด้วยข้อมูลที่คุณให้ฉันคิดว่าคุณสามารถใช้ A * ด้วยการปรับเปลี่ยนเพียงเล็กน้อย ในอัลกอริทึม A * ปกติคุณจะทำเครื่องหมายทุก ๆ โหนดในขณะที่คุณผ่านมันเพื่อให้แน่ใจว่าคุณจะไม่ผ่านมันอีกครั้ง นั่นคือส่วนที่แน่นอนที่ทำให้เกิดปัญหากับรายการ การเปลี่ยนแปลงที่สำคัญคือการจำรายการของคุณเมื่อคุณผ่านจากโหนดก่อนหน้านี้ นี่คือรหัส sudo อธิบายสิ่งที่ฉันหมายถึง:

if (nodestoCheck.notempty())
    newNode = nodeToCheck.first;
    if (notpassed(newNode.pos, newNode.items))
        if (room(newNode).containItem)
            add NewNode + room(NewNode).items 
        else
            do normal A* algorithm for new Node

ด้วยอัลกอริทึมนี้คุณจะเริ่มตรวจสอบโหนดทั้งหมดโดยไม่มีรายการก่อน มีความเป็นไปได้สูงที่กลุ่มการค้นหาแรกของคุณถูกปิดกั้นโดยประตูบางบาน แต่มันจะหากุญแจไปที่ประตูนั้นก่อนที่มันจะค้นหาทุกห้อง จากคีย์นั้นคุณจะเริ่มการค้นหาใหม่โดยมีคีย์เฉพาะนั้น คราวนี้เมื่อคุณไปถึงประตูคุณอาจจะผ่านมันไป รูทีนเดียวกันจะดำเนินต่อไปจนกว่าคุณจะพบทางออกจากคุกใต้ดิน ปัญหาเดียวคือการใช้หน่วยความจำทุกครั้งที่มีประตูและกุญแจจำนวนมาก แม้ว่ามันจะไม่เป็นปัญหาสำหรับอย่างน้อย 10 หรือ 15 ปุ่ม


0

ทำไมคุณไม่ใช้แค่ A * ปกติและประตูล็อครุ่นเป็นภูมิภาคที่ไม่สามารถใช้ได้ เมื่อคุณหยิบกุญแจ (เดินบนไทล์คีย์?) มันจะเปลี่ยนประตูที่ถูกล็อคนั้นไปสู่ภูมิภาคที่พอจะผ่านได้

สิ่งนี้หมายความว่าตัวค้นหาพา ธ ของคุณจะไปหาเส้นทางที่ไม่มีกุญแจสั้นที่สุดและหากพบคีย์ตามทางมันจะรวมสิ่งนั้นไว้ในเส้นทางหากมันช่วย

ดูเหมือนว่าสมเหตุสมผลสำหรับฉัน มันไม่สมบูรณ์แบบ แต่เป็นวิธีแก้ปัญหาอย่างง่าย

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