[英]Algorithm for solving Flow Free Game
我最近開始玩Flow Free Game 。
用管道連接匹配的顏色以創建流動。 配對所有顏色,並覆蓋整個板以解決 Flow Free 中的每個難題。 但要小心,如果它們交叉或重疊,管道會破裂!
我意識到這只是給定點對之間的尋路游戲,條件是沒有兩條路徑重疊。 我有興趣為游戲編寫解決方案,但不知道從哪里開始。 我想過使用回溯,但對於非常大的電路板尺寸,它的時間復雜度很高。
是否有任何合適的算法可以有效地解決游戲。 使用啟發式方法來解決問題有幫助嗎? 給我一個從哪里開始的提示,我會從那里開始。
我在大多數董事會中觀察到,通常
這是正確的觀察,可以用來有效地解決它嗎?
問題顯然出在 NP 中:如果你猜出一個棋盤星座,很容易(poly-time)檢查它是否解決了問題。
它是否是 NP-hard(意味着與 NP 中的所有其他問題一樣難,例如 SAT)尚不清楚。 當然,現代 SAT 求解器無論如何都不會關心和解決大型實例(我猜高達 100x100)。
在這里,我只是將核子的評論復制到 OP:
搜索“數字鏈接的 SAT 公式”和“數字鏈接的 NP 完整性”會找到一些參考資料。 不出所料,最有趣的兩個是日語。 第一個是 NP 完備性的實際紙質證明。 第二部分描述了如何使用 SAT 求解器 Sugar 求解 NumberLink。 ——
有幾種可能性可以對問題進行編碼。 我會給一個我可以很快彌補的。
j_random_hacker 指出不允許獨立循環。 以下編碼確實允許它們。 這個問題使 SAT 編碼的吸引力降低了一些。 我能想到的禁止獨立循環的最簡單方法是引入 O(n^2) 新變量,其中n
是板上的瓷磚數量(計算每個瓷磚與下一個水槽的距離),除非使用日志編碼這會將其降低到O(n*log n)
,這可能會使求解器更難解決問題。
每塊瓷磚、一塊類型和顏色一個變量。 例如,如果某個變量XYTC
為真,則它編碼 X/Y 位置的圖塊類型為T
且顏色為C
。 您不需要空磁貼類型,因為這不會在解決方案中發生。
設置接收器/源的變量並說沒有其他圖塊可以是接收器/源。
我可能錯過了一些東西。 但它應該很容易修復。
我懷疑沒有多項式時間算法可以保證解決這個問題的每個實例。 但由於其中一個要求是每個方格都必須被管道覆蓋,因此人們和計算機用於解決數獨的類似方法在這里應該很有效:
在分支方面挑選方塊時,一般是一個好主意,可以選擇一個盡可能少的允許顏色。
[編輯:避免形成無效的管道“循環”的可能性很重要。 一種方法是通過為每個方塊 x 的每種允許顏色 i 維護 2 位信息:方塊 x 是否通過確定的 i 色瓷磚路徑連接到第一個 i 色端點,以及相同的第二個 i 色端點的事情。 然后在遞歸時,對於任何允許的顏色,永遠不要選擇具有相同位設置(或都沒有設置)的兩個鄰居的正方形。]
您實際上根本不需要使用任何邏輯推導,但是您使用的推導越多越好,程序運行得越快,因為它們(可能會顯着)減少遞歸量。 一些有用的扣除包括:
基於路徑連通性的更高級推論可能會進一步提供幫助——例如,如果您可以確定連接某對連接器的每條路徑都必須通過特定方格,則可以立即將該顏色分配給該方格。
這種簡單的方法在您的 5x5 示例中推斷出一個沒有任何遞歸的完整解決方案: (5, 2)、(5, 3)、(4, 3) 和 (4, 4) 處的正方形被強制為橙色; (4, 5) 被強制為綠色; (5, 5) 也被強制為綠色,因為沒有其他顏色可以到達這個方塊然后又回來; 現在結束於 (4, 4) 的橙色路徑無處可去,只能完成 (3, 4) 處的橙色路徑。 並且 (3, 1) 也被強制為紅色; (3, 2) 被強制為黃色,依次強制 (2, 1) 和 (2, 2) 為紅色,最終強制黃色路徑在 (3, 3) 處結束。 (2, 2) 處的紅色管道迫使 (1, 2) 變為藍色,並且紅色和藍色路徑最終完全確定,“相互強制”。
我在Needless Complex上找到了一篇博客文章,它完整地解釋了如何使用 SAT 來解決這個問題。
該代碼也是開源的,因此您可以在實際操作中查看(並理解)它。
我將在這里引用它描述您需要在 SAT 中實施的規則:
每個單元格都分配了一種顏色。
每個端點單元格的顏色都是已知和指定的。
謝謝@Matt Zucker創造這個!
我喜歡類似於人類思維的解決方案。 您可以(很容易)通過蠻力獲得數獨的答案,但獲得一條您可以遵循的路徑來解決難題更有用。
我在大多數板子中觀察到,通常 1.對於最遠的點,您需要沿着邊沿路徑走。 2.對於彼此最近的點,如果有,則遵循直接路徑。 這是正確的觀察,可以用來有效地解決它嗎?
這些都是“大多數時候”,但並非總是如此。
我會用這個替換你的第一條規則:如果兩個水槽都沿着邊緣,你需要沿着邊緣沿着路徑走。 (您可以構建一個反例,但大多數情況下都是如此)。 沿邊創建路徑后,沿邊的塊應被視為邊的一部分,因此您的算法將嘗試遵循前一個管道形成的新邊。 我希望這句話是有道理的...
當然,在使用那些“大多數時候”規則之前,您需要遵循絕對規則(請參閱 j_random_hacker 帖子中的兩個推論)。
另一件事是嘗試消除無法找到解決方案的電路板。 讓我們稱未完成的管道(從一個水槽開始但尚未到達另一個水槽的管道)為蛇,未完成管道的最后一個方格將稱為蛇頭。 如果您在兩個相同顏色的頭之間找不到空白方塊的路徑,則意味着您的電路板無法找到解決方案,應該丟棄(或者您需要回溯,具體取決於您的實現)。
自由流動游戲(和其他類似游戲)接受將兩條相同顏色的線並排的棋盤作為有效解決方案,但我相信總是存在沒有並排線的解決方案。 這意味着任何不是水槽的正方形都會有兩個相同顏色的鄰居,而水槽只有一個。 如果規則碰巧總是正確的(我相信它是,但不能證明它),那將是減少可能性數量的額外約束。 我使用並排線解決了 Free Flow 的一些難題,但大多數時候我找到了另一種沒有它們的解決方案。 我還沒有在 Free Flow 的解決方案網站上看到並排的線條。
基於 Big Duck Games 的 IOS 版本,一些規則導致了一種算法來解決流程中的關卡,這家公司似乎生產了規范版本。 這個答案的其余部分假設沒有牆壁、橋梁或扭曲。
即使你出奇地好,巨大的 15x18 方板也是一個很好的例子,說明如何以似乎可能讓你在結束前一遍又一遍地卡住,實際上不得不從頭開始的方式進行。 這可能與一般情況下已經提到的指數時間復雜度有關。 但這並不意味着簡單的策略對大多數董事會來說不是絕對有效的。
塊永遠不會留空,因此孤立塊意味着您做錯了什么。
必須連接相同顏色的基本相鄰單元格。 這排除了相同顏色的 2x2 塊和 3 個相鄰單元格的六邊形網格三角形。
您通常可以通過確定某種顏色進入或排除在某個方塊中來取得持久的進展。
由於第 1 點和第 2 點,在六邊形板上的六邊形網格上,沿邊緣延伸的管道通常被卡住,一直繞到出口,有效地將外邊緣移入並使板變小,因此該過程可以重復。 可以預測什么樣的相鄰條件可以保證以及什么樣的條件可以打破這兩種網格的這種循環。
我發現的大多數(如果不是全部)第 3 方變體都缺少 1 到 4 個,但鑒於這些限制,生成有效板可能是一項艱巨的任務。
回答:
第 3 點建議為每個單元格存儲一個值,該值可以是一種顏色,也可以是一組錯誤/不確定值,每種顏色都有一個值。
求解器可以重復使用點 1 和點 2 以及在管道末端周圍路徑的小鄰域上為點 3 存儲的數據,以逐漸設置顏色或將不確定值設置為 false。
我們中的一些人花了很多時間思考這個問題。 我在這里的一篇 Medium 文章中總結了我們的工作: https : //towardsdatascience.com/deep-learning-vs-puzzle-games-e996feb76162
劇透:到目前為止,好老的 SAT 似乎擊敗了花哨的 AI 算法!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.