การติดตามสถานะของผู้เยี่ยมชมในการค้นหาความกว้าง - แรก


10

ดังนั้นฉันจึงพยายามนำ BFS ไปใช้กับตัวต่อSlide Blocks (ประเภทตัวเลข) ตอนนี้สิ่งสำคัญที่ฉันสังเกตเห็นคือถ้าคุณมี4*4คณะกรรมการจำนวนของรัฐสามารถมีขนาดใหญ่เป็น16!ดังนั้นฉันไม่สามารถระบุทุกรัฐล่วงหน้า

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

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


1
ด้านหมายเหตุ: ฉันไม่สามารถนึกถึงกองซ้อนที่เหมาะสมกว่าในการโพสต์คำถามนี้ ฉันรู้ว่ารายละเอียดการใช้งานนั้นไม่ได้รับการต้อนรับในสแต็กนี้
DuttaA

2
imo นี่เป็นคำถามที่ยอดเยี่ยมสำหรับ SE: AI เพราะมันไม่ใช่แค่การนำไปใช้ แต่เป็นแนวคิด ไม่ต้องพูดถึงคำถามดึงดูด 4 คำตอบที่ถูกต้องในเวลาไม่กี่ชั่วโมง (ใช้เสรีภาพในการแก้ไขชื่อสำหรับการค้นหาและสร้างแท็ก BFS)
DukeZhou

คำตอบ:


8

คุณสามารถใช้set(ในความหมายทางคณิตศาสตร์ของคำเช่นคอลเลกชันที่ไม่สามารถมีรายการที่ซ้ำกัน) เพื่อจัดเก็บสถานะที่คุณได้เห็นแล้ว การดำเนินการที่คุณจะต้องสามารถดำเนินการได้คือ:

  • องค์ประกอบการแทรก
  • ทดสอบว่ามีองค์ประกอบอยู่ในนั้นหรือไม่

ภาษาการเขียนโปรแกรมทุกภาษาน่าจะได้รับการสนับสนุนสำหรับโครงสร้างข้อมูลที่สามารถดำเนินการทั้งสองนี้ได้ในเวลาที่คงที่ ( ) ตัวอย่างเช่น:O(1)

  • set ใน Python
  • HashSet ใน Java

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

ใน pseudocode ชุดดังกล่าว (ลองตั้งชื่อclosed_setเพื่อให้สอดคล้องกับpseudocode บน wikipediaสามารถใช้ในการค้นหาแบบกว้างแรกได้ดังนี้:

frontier = First-In-First-Out Queue
frontier.add(initial_state)

closed_set = set()

while frontier not empty:
    current = frontier.remove_next()

    if current == goal_state:
        return something

    for each child in current.generate_children()
        if child not in closed_set:    // This operation should be supported in O(1) time regardless of closed_set's current size
            frontier.add(child)

    closed_set.add(current)    // this should also run in O(1) time

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


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

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


1
ฉันจะสามารถทำเช่นนั้นได้ แต่เวลาการเปรียบเทียบจะเริ่มเพิ่มขึ้นแบบทวีคูณ
DuttaA

3
@DuttaA ไม่มีเวลาเปรียบเทียบไม่ควรเพิ่มทวีคูณ ชุดนี้ชุดกัญชาหรือสิ่งที่พวกเขาเกิดขึ้นจะถูกเรียกในภาษาของคุณเลือกควรจะสามารถที่จะทดสอบหรือไม่พวกเขามีการใด ๆ ของรัฐได้รับมีค่าคงที่คำนวณซับซ้อน , โดยไม่คำนึงถึงวิธีการหลายองค์ประกอบที่พวกเขามีอยู่แล้ว . พวกเขาไม่ได้อยู่ในรายการพวกเขาจะไม่ทดสอบว่าพวกเขามีแล้วโดยเปรียบเทียบกับทุกองค์ประกอบที่มีอยู่ SO(1)S
Dennis Soemers

1
@DuttaA ฉันได้เพิ่มบาง pseudocode เพื่ออธิบายว่าจะใช้ชุดนี้ได้อย่างไรหวังว่าจะมีบางอย่างที่ชัดเจน โปรดทราบว่าเราไม่เคยวนรอบทั้งหมดclosed_setขนาดของมันไม่ควรส่งผลกระทบต่อเวลาการคำนวณของเรา
Dennis Soemers

1
จริง ๆ แล้วฉันกำลังใช้ c ++ ฉันไม่มีความคิดที่จะ hashing ... เดาว่าฉันจะใช้ python ตอนนี้ ... ขอบคุณสำหรับคำตอบ
DuttaA

3
@DuttaA ใน C ++ คุณอาจต้องการใช้std :: unordered_set
Dennis Soemers

16

คำตอบของ Dennis Soemers นั้นถูกต้อง: คุณควรใช้ HashSet หรือโครงสร้างที่คล้ายกันเพื่อติดตามสถานะการเยี่ยมชมในการค้นหากราฟ BFS

อย่างไรก็ตามมันไม่ได้ตอบคำถามของคุณ คุณพูดถูกในกรณีที่เลวร้ายที่สุด BFS จะขอให้คุณเก็บ 16! โหนด แม้ว่าเวลาที่แทรกและตรวจสอบในชุดจะเป็น O (1) คุณจะยังคงต้องการหน่วยความจำที่ไร้สาระ

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

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

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


2
ใช่นี่เป็นคำตอบที่มีประโยชน์มากกว่าสำหรับผู้ที่ต้องการไขปริศนาอย่างมีประสิทธิภาพ คำตอบของฉันคือคำตอบสำหรับผู้ที่ยืนยันในการใช้ BFS (เพราะพวกเขาต้องการเห็นมันในทางปฏิบัติหรือเรียนรู้วิธีการนำไปใช้หรือเหตุผลใด ๆ ก็ตาม) โปรดทราบว่า BFS หวังว่าจะไม่จำเป็นต้องจัดเก็บ16!โหนดโดยวิธี; นั่นเป็นเพียงกรณีที่เลวร้ายที่สุดมันอาจสามารถหาทางแก้ไขก่อนเวลานั้นได้
Dennis Soemers

@DennisSoemers ถูกต้อง .. คุณถูกต้อง .. ฉันแค่พยายามฝึกฝนทักษะของฉัน ... ฉันจะย้ายไปยังวิธีการค้นหาขั้นสูงเพิ่มเติมในภายหลัง
DuttaA

มีกรณีใดบ้างที่ BFS สามารถส่งคืนโซลูชันภายในที่ยอมรับได้? (ฉันกำลังทำอะไรกับ 81! * tbd-value และ breadth-first ดูดีที่สุดว่ามีปัจจัยการบล็อกที่สามารถพลาดได้ง่ายโดยไม่อ่อนเพลียตอนนี้เราไม่กังวลเกี่ยวกับการเล่นที่แข็งแกร่งอย่างแท้จริง อ่อนแอ "ประสิทธิภาพการทำงานทั่วไปในช่วงของทอพอโลยี gameboard คาดเดาไม่ได้)
DukeZhou

2
@DukeZhou BFS มักจะใช้เฉพาะเมื่อต้องการโซลูชันที่สมบูรณ์ หากต้องการหยุดก่อนคุณต้องใช้ฟังก์ชันที่ประเมินคุณภาพสัมพัทธ์ของโซลูชันบางส่วนที่แตกต่างกัน แต่ถ้าคุณมีฟังก์ชันดังกล่าวคุณอาจใช้ A * แทนได้!
John Doucette

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

7

ในขณะที่คำตอบที่ได้รับนั้นโดยทั่วไปแล้วความจริงแล้ว BFS ในปริศนา 15 ตัวนั้นไม่เพียง แต่เป็นไปได้ แต่มันถูกสร้างขึ้นในปี 2005! กระดาษที่อธิบายวิธีการสามารถพบได้ที่นี่:

http://www.aaai.org/Papers/AAAI/2005/AAAI05-219.pdf

ประเด็นสำคัญบางประการ:

  • ในการดำเนินการนี้จำเป็นต้องใช้หน่วยความจำภายนอก - นั่นคือ BFS ใช้ฮาร์ดไดรฟ์สำหรับการจัดเก็บแทน RAM
  • จริงๆแล้วมีเพียง 15 รัฐ / 2 รัฐเท่านั้นเนื่องจากพื้นที่ของรัฐมีส่วนประกอบที่ไม่สามารถเข้าถึงได้ซึ่งกันและกัน
  • สิ่งนี้ใช้ได้กับปริศนาตัวต่อแบบเลื่อนเนื่องจากพื้นที่ของรัฐเติบโตอย่างช้าๆจากระดับหนึ่งไปอีกระดับ ซึ่งหมายความว่าหน่วยความจำทั้งหมดที่จำเป็นสำหรับระดับใดจะเล็กกว่าขนาดเต็มของพื้นที่รัฐ (สิ่งนี้ตรงกันข้ามกับพื้นที่ของรัฐอย่างลูกบาศก์ของรูบิคซึ่งพื้นที่ของรัฐนั้นเติบโตเร็วกว่ามาก)
  • เนื่องจากปริศนาตัวเลื่อนแบบเรียงต่อกันไม่ได้ถูกบอกทิศทางคุณจึงต้องกังวลกับการซ้ำซ้อนในเลเยอร์ปัจจุบันหรือเลเยอร์ก่อนหน้า ในพื้นที่กำกับคุณอาจสร้างข้อมูลซ้ำในเลเยอร์ก่อนหน้าของการค้นหาซึ่งทำให้สิ่งต่าง ๆ มีความซับซ้อนมากขึ้น
  • ในงานต้นฉบับโดย Korf (เชื่อมโยงด้านบน) พวกเขาไม่ได้เก็บผลการค้นหาจริง ๆ - การค้นหาคำนวณแค่ว่ามีกี่รัฐในแต่ละระดับ หากคุณต้องการเก็บผลลัพธ์แรกที่คุณต้องการเช่น WMBFS ( http://www.cs.du.edu/~sturtevant/papers/bfs_min_write.pdf )
  • มีสามวิธีหลักในการเปรียบเทียบสถานะจากเลเยอร์ก่อนหน้าเมื่อเก็บสถานะไว้ในดิสก์
    • ที่แรกก็คือการเรียงตาม หากคุณเรียงลำดับสองไฟล์ของผู้สืบทอดคุณสามารถสแกนไฟล์เหล่านั้นตามลำดับการค้นหาซ้ำกัน
    • ประการที่สองคือแฮตาม หากคุณใช้ฟังก์ชันแฮชเพื่อจัดกลุ่มผู้สืบทอดเป็นไฟล์คุณสามารถโหลดไฟล์ที่มีขนาดเล็กกว่าพื้นที่เต็มสถานะเพื่อตรวจสอบรายการซ้ำ (โปรดทราบว่ามีสองฟังก์ชันแฮชที่นี่ - หนึ่งเพื่อส่งรัฐไปยังไฟล์และอีกหนึ่งเพื่อแยกรัฐในไฟล์นั้น)
    • ที่สามคือการตรวจสอบซ้ำโครงสร้าง นี่เป็นรูปแบบหนึ่งของการตรวจจับแบบแฮช แต่จะทำในลักษณะที่สามารถตรวจสอบรายการซ้ำได้ทันทีเมื่อมีการสร้างแทนที่จะเป็นหลังจากที่ถูกสร้างขึ้นทั้งหมด

ยังมีอีกมากที่จะกล่าวที่นี่ แต่กระดาษข้างต้นให้รายละเอียดมากขึ้น


มันเป็นคำตอบที่ดี .. แต่ไม่ใช่สำหรับ noobs อย่างฉัน
:)

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

@NotThatGuy ในกราฟที่ไม่ได้บอกทิศทางผู้ปกครองและเด็กอยู่ไกลที่สุด 1 แยกจากกันในระดับความลึกที่พบใน BFS นี่เป็นเพราะเมื่อพบหนึ่งแล้วขอบที่ไม่ได้บอกทิศทางจะรับประกันว่าจะพบอีกอันในทันทีหลังจากนั้น แต่ในกราฟกำกับกำกับสถานะที่ระดับความลึก 10 สามารถสร้างเด็กที่ระดับความลึก 2 ได้เนื่องจากเด็กที่ระดับความลึก 2 ไม่จำเป็นต้องมีขอบกลับไปสู่สถานะอื่น (สิ่งนี้จะทำให้ความลึก 3 แทนความลึก 10) .
นาธานเอส.

@NotThatGuy ถ้าคุณย้ายไพ่ 3 ใบในวงกลมคุณสร้างรอบ แต่ BFS จะสำรวจทั้งสองทิศทางพร้อมกันดังนั้นมันจะไม่นำคุณกลับไปสู่ความลึกที่ตื้นกว่า ไทล์เลื่อน 3x2 เต็มแสดงในการสาธิตนี้และคุณสามารถติดตามวัฏจักรเพื่อดูว่ามันเกิดขึ้นได้อย่างไร: movingai.com/SAS/IDA
Nathan S.

1
สุดยอด ยินดีต้อนรับสู่ SE: AI!
DukeZhou

3

แดกดันคำตอบคือ "ใช้ระบบใดก็ได้ที่คุณต้องการ" hashSet เป็นความคิดที่ดี อย่างไรก็ตามปรากฎว่าความกังวลของคุณเกี่ยวกับการใช้หน่วยความจำไม่มีมูลความจริง BFS นั้นแย่มากที่ปัญหาเหล่านี้ช่วยแก้ไขปัญหานี้ให้คุณได้

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

ซึ่งหมายความว่าเมื่อคุณกำลังประมวลผล BFS สุดท้ายคุณต้องมีสถานะอย่างน้อย 16! / 3 ในหน่วยความจำ ไม่ว่าคุณจะใช้วิธีการแบบใดเพื่อให้แน่ใจว่าความพอดีในหน่วยความจำจะเพียงพอเพื่อให้แน่ใจว่ารายการที่คุณเคยเข้าชมก่อนหน้านี้จะพอดีกับหน่วยความจำเช่นกัน

ดังที่คนอื่น ๆ ชี้ว่านี่ไม่ใช่วิธีที่ดีที่สุดที่จะใช้ ใช้อัลกอริทึมที่เหมาะสมกับปัญหามากขึ้น


2

ปัญหา 15 ปริศนาถูกเล่นบนกระดาน 4x4 การใช้สิ่งนี้ในซอร์สโค้ดจะทำตามขั้นตอน ในตอนแรกเอ็นจิ้นเกมจะต้องถูกตั้งโปรแกรม สิ่งนี้ทำให้สามารถเล่นเกมโดยผู้ให้บริการมนุษย์ เกม 15 ปริศนามีองค์ประกอบฟรีเพียงหนึ่งองค์ประกอบและในส่วนนี้การกระทำจะดำเนินการ เอ็นจิ้นของเกมยอมรับคำสั่งที่เป็นไปได้สี่คำ: ซ้าย, ขวา, ขึ้นและลง ไม่อนุญาตการกระทำอื่น ๆ และเป็นไปได้ที่จะควบคุมเกมด้วยคำแนะนำเหล่านี้เท่านั้น

เลเยอร์ถัดไปสำหรับเล่นเกมคือ GUI สิ่งนี้สำคัญมากเพราะช่วยให้สามารถทดสอบเอนจิ้นเกมและลองแก้ปัญหาด้วยมือ นอกจากนี้ GUI ยังมีความสำคัญเนื่องจากเราต้องใช้การวิเคราะห์พฤติกรรมที่เป็นไปได้ และตอนนี้เราสามารถพูดคุยเกี่ยวกับ AI เอง AI ต้องส่งคำสั่งไปยังเอ็นจิ้นเกม (ซ้าย, ขวา, ขึ้นและลง) แนวทางที่ไร้เดียงสาสำหรับนักแก้ปัญหาคืออัลกอริธึมการค้นหาที่ดุร้ายซึ่งหมายความว่า AI กำลังส่งคำสั่งแบบสุ่มจนกว่าจะถึงสถานะเป้าหมาย แนวคิดขั้นสูงเพิ่มเติมคือการใช้ฐานข้อมูลรูปแบบบางชนิดซึ่งช่วยลดพื้นที่ของรัฐ การค้นหาแบบกว้างครั้งแรกไม่ได้เป็นการวิเคราะห์แบบฮิวริสติกโดยตรง แต่เป็นการเริ่มต้น มันเท่ากับสร้างกราฟสำหรับทดสอบการเคลื่อนไหวที่เป็นไปได้ในลักษณะตามลำดับเวลา

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


1

แนวทางการเล่นเกม

มันเป็นความจริงที่คณะกรรมการมี 16!รัฐที่เป็นไปได้ การใช้ชุดแฮชเป็นสิ่งที่นักเรียนเรียนรู้ในหลักสูตรอัลกอริธึมปีแรกเพื่อหลีกเลี่ยงความซ้ำซ้อนและการวนซ้ำไม่สิ้นสุดเมื่อค้นหากราฟที่อาจมีรอบกราฟ

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

โคตรลำดับย่อย

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

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

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

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

สรุป

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

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