อัลกอริทึมสำหรับการนั่ง Zoombinis บนเรือข้ามฟากของกัปตันคาจันหรือไม่


12

ฉันเพิ่งเล่นเกมThe Logical Journey of the Zoombinisเมื่อไม่นานมานี้และพยายามใช้อัลกอริธึมคอมพิวเตอร์บางอย่างที่สามารถไขปริศนาต่าง ๆ ได้ ฉันติดอยู่กับวิธีเข้าหาปริศนาเรือข้ามฟากของกัปตันคาจุน

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

ในจิ๊กซอว์แพขนานยนต์ภารกิจคือการจัดคอลเลคชั่น 16 Zoombinis บนที่นั่ง 16 ที่นั่งของเรือข้ามฟาก ข้อตกลงดังกล่าวจะต้องปฏิบัติตามกฎว่าจะต้องมี Zoombinis ซึ่งมีที่นั่งอย่างน้อยหนึ่งที่นั่งที่อยู่ติดกัน หาก Zoombinis สองคนมีผมที่แตกต่างกันดวงตาที่แตกต่างกันจมูกที่แตกต่างกันและเท้าที่แตกต่างจากกันพวกเขาอาจไม่ได้อยู่ติดกัน

การจัดเรียงที่นั่งเปลี่ยนแปลงตามระดับ เพื่อความเป็นรูปเป็นร่างเรามามุ่งเน้นที่ระดับ "ยากมาก" ซึ่งมี 16 ที่นั่งที่จัดเรียงในตาราง 4-by-4 นี่คือตัวอย่างที่ 15 Zoombinis ถูกกฎหมายนั่ง แต่ Zoombini สุดท้ายที่ยืนอยู่บนท่าเรือไม่สามารถวางบนที่นั่งว่างสุดท้ายได้เพราะเธอจะไม่แบ่งปันคุณสมบัติกับ Zoombini ทางขวา:

ตัวอย่างของตัวต่อที่ทำจนจบ

มี 16! Zoom 21 ล้านล้านตำแหน่งที่เป็นไปได้ของ Zoombinis สู่ที่นั่ง ดังนั้นเพียงแค่วิ่งผ่านการมอบหมายที่เป็นไปได้ทุกอย่างเพื่อดูว่ามันถูกกฎหมายหรือไม่ ฮิวริสติกบางอย่างที่ฉันอาจใช้เพื่อแก้ไขปัญหานี้อย่างสมเหตุสมผลคืออะไร


2
มันทำให้ฉันนึกถึงซูโดกุและนักซูโดกุมักจะใช้การย้อนรอยบางอย่าง
mattecapu

2
Subgraph Isomorphism Problemหากคุณมีความพร้อมและยินดีที่จะขุดผ่านบางวรรณกรรมที่ซับซ้อนมากขึ้นแล้วคุณจะพบข้อมูลที่เป็นประโยชน์โดยการค้นหา ปัญหาคือการหากราฟหนึ่งในกราฟอื่น ในกรณีของคุณกราฟย่อยจะเป็นที่นั่ง (ขอบเป็นคำคุณศัพท์) ในขณะที่กราฟหลักจะเป็น zoombinis โดยที่การเชื่อมต่อนั้นจะมีลักษณะที่ใช้ร่วมกัน โปรดทราบว่าโดยทั่วไปแล้วปัญหานี้เกิดจากปัญหา NP-complete และมักจะทำโดยการย้อนรอยด้วยเช่นกันอย่างไรก็ตามสำหรับกรณีพิเศษบางอย่าง (ซึ่งกราฟของคุณอาจดีมาก) สามารถแก้ปัญหาพหุนามหรือเชิงเส้นได้
ธรรมดา

นี่เป็นความคิดที่ดีฉันชอบ Zoombinis ตั้งแต่เด็กฉันอาจทำแบบเดียวกัน!
AlexFoxGill

คำตอบ:


8

ขอบคุณ @mattecapu สำหรับคำค้นหาที่มีประโยชน์ของ Google ของ "อัลกอริทึมการย้อนรอย" นั่นทำให้ฉันคิดว่าฉันต้องการอาหาร

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

13   5   6  14

 7   1   2   9

 8   3   4  10

15  11  12  16

นี่คือรหัสเทียมบางส่วนที่อธิบายถึงฟังก์ชั่นที่ฉันเขียน คุณป้อนรายการที่มี Zoombinis 16 ตัวและตัวชี้ไปยังที่นั่งแรกในรายการที่ลิงก์

function recursively_assign_seat(zoombini_list, seat):

    if zoombini_list is empty:
        return True

    else:
        for each z in zoombini_list:

            for each n in seat.neighbors:
                if not allowed_as_neighbors(z, n):
                    next z

            seat.occupant ← z
            if recursively_assign_seat(zoombini_list.remove(z), seat.next):
                return True
            else:
                seat.occupant ← None

        return False

มันทำงานได้อย่างรวดเร็วอย่างน่าประหลาดใจจริงๆ! ฉันยินดีมากกับมัน

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


1
เมื่อคุณกรอก8คุณเท่านั้นที่อยู่ติดกับ2แต่คุณอาจจะเติม9ซึ่งอยู่ติดกับทั้งสองและ7 3งานที่ดีแก้มันแม้ว่า!
AlexFoxGill

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