简体   繁体   English

求解Flow Free Game的算法

[英]Algorithm for solving Flow Free Game

I recently started playing Flow Free Game .我最近开始玩Flow Free Game

Connect matching colors with pipe to create a flow.用管道连接匹配的颜色以创建流动。 Pair all colors, and cover the entire board to solve each puzzle in Flow Free.配对所有颜色,并覆盖整个板以解决 Flow Free 中的每个难题。 But watch out, pipes will break if they cross or overlap!但要小心,如果它们交叉或重叠,管道会破裂!

I realized it is just path finding game between given pair of points with conditions that no two paths overlap.我意识到这只是给定点对之间的寻路游戏,条件是没有两条路径重叠。 I was interested in writing a solution for the game but don't know where to start.我有兴趣为游戏编写解决方案,但不知道从哪里开始。 I thought of using backtracking but for very large board sizes it will have high time complexity.我想过使用回溯,但对于非常大的电路板尺寸,它的时间复杂度很高。

Is there any suitable algorithm to solve the game efficiently.是否有任何合适的算法可以有效地解决游戏。 Can using heuristics to solve the problem help?使用启发式方法来解决问题有帮助吗? Just give me a hint on where to start, I will take it from there.给我一个从哪里开始的提示,我会从那里开始。

I observed in most of the boards that usually我在大多数董事会中观察到,通常

  1. For furthest points, you need to follow path along edge.对于最远的点,您需要沿着边缘的路径。
  2. For point nearest to each other, follow direct path if there is one.对于彼此最近的点,如果有,则遵循直接路径。

Is this correct observation and can it be used to solve it efficiently?这是正确的观察,可以用来有效地解决它吗?

Reduction to SAT降低到 SAT

Basic idea基本理念

  1. Reduce the problem to SAT将问题简化SAT
  2. Use a modern SAT solver to solve the problem使用现代 SAT 求解器解决问题
  3. Profit利润

Complexity复杂

The problem is obviously in NP: If you guess a board constellation, it is easy (poly-time) to check whether it solves the problem.问题显然出在 NP 中:如果你猜出一个棋盘星座,很容易(poly-time)检查它是否解决了问题。

Whether it is NP-hard (meaning as hard as every other problem in NP, eg SAT), is not clear.它是否是 NP-hard(意味着与 NP 中的所有其他问题一样难,例如 SAT)尚不清楚。 Surely modern SAT solvers will not care and solve large instances in a breeze anyway (I guess up to 100x100).当然,现代 SAT 求解器无论如何都不会关心和解决大型实例(我猜高达 100x100)。

Literature on Number Link数字链接文献

Here I just copy Nuclearman's comment to the OP:在这里,我只是将核子的评论复制到 OP:

Searching for "SAT formulation of numberlink" and "NP-completeness of numberlink" leads to a couple references.搜索“数字链接的 SAT 公式”和“数字链接的 NP 完整性”会找到一些参考资料。 Unsurprisingly, the two most interesting ones are in Japanese.不出所料,最有趣的两个是日语。 The first is the actual paper proof of NP-completeness.一个是 NP 完备性的实际纸质证明。 The second describes how to solve NumberLink using the SAT solver, Sugar.第二部分描述了如何使用 SAT 求解器 Sugar 求解 NumberLink。 ——

Hint for reduction to SAT降低到 SAT 的提示

There are several possibilities to encode the problem.有几种可能性可以对问题进行编码。 I'll give one that I could make up quickly.我会给一个我可以很快弥补的。

Remark评论

j_random_hacker noted that free-standing cycles are not allowed. j_random_hacker 指出不允许独立循环。 The following encoding does allow them.以下编码确实允许它们。 This problem makes the SAT encoding a bit less attractive.这个问题使 SAT 编码的吸引力降低了一些。 The simplest method I could think of to forbid free-standing loops would introduce O(n^2) new variables, where n is the number of tiles on the board (count distance from next sink for each tile) unless one uses log encoding for this, which would bring it down to O(n*log n) , possible making the problem harder for the solver.我能想到的禁止独立循环的最简单方法是引入 O(n^2) 新变量,其中n是板上的瓷砖数量(计算每个瓷砖与下一个水槽的距离),除非使用日志编码这会将其降低到O(n*log n) ,这可能会使求解器更难解决问题。

Variables变量

One variable per tile, piece type and color.每块瓷砖、一块类型和颜色一个变量。 Example if some variable XYTC is true it encodes that the tile at position X/Y is of type T and has color C .例如,如果某个变量XYTC为真,则它编码 X/Y 位置的图块类型为T且颜色为C You don't need the empty tile type since this cannot happen in a solution.您不需要空磁贴类型,因为这不会在解决方案中发生。

Set initial variables设置初始变量

Set the variables for the sink/sources and say no other tile can be sink/source.设置接收器/源的变量并说没有其他图块可以是接收器/源。

Constraints约束

  1. For every position, exactly one color/piece combination is true (cardinality constraint).对于每个位置,只有一种颜色/件组合为真(基数约束)。
  2. For every variable (position, type, color), the four adjacent tiles have to be compatible (if the color matches).对于每个变量(位置、类型、颜色),四个相邻的图块必须兼容(如果颜色匹配)。

I might have missed something.我可能错过了一些东西。 But it should be easily fixed.但它应该很容易修复。

I suspect that no polynomial-time algorithm is guaranteed to solve every instance of this problem.我怀疑没有多项式时间算法可以保证解决这个问题的每个实例。 But since one of the requirements is that every square must be covered by pipe, a similar approach to what both people and computers use for solving Sudoku should work well here:但由于其中一个要求是每个方格都必须被管道覆盖,因此人们和计算机用于解决数独的类似方法在这里应该很有效:

  1. For every empty square, form a set of possible colours for that square, and then repeatedly perform logical deductions at each square to shrink the allowed set of colours for that square.对于每个空方块,为该方块形成一组可能的颜色,然后在每个方块上重复执行逻辑推演以缩小该方块允许的颜色集。
  2. Whenever a square's set of possible colours shrinks to size 1, the colour for that square is determined.每当一个正方形的可能颜色集缩小到大小 1 时,就确定了该正方形的颜色。
  3. If we reach a state where no more logical deductions can be performed and the puzzle is not completely solved yet (ie there is at least one square with more than one possible colour), pick one of these undecided squares and recurse on it, trying each of the possible colours in turn.如果我们达到无法进行更多逻辑推论并且谜题尚未完全解决的状态(即,至少有一个正方形有不止一种可能的颜色),请选择这些未定正方形中的一个并对其进行递归,尝试每个依次选择可能的颜色。 Each try will either lead to a solution, or a contradiction;每次尝试要么会导致解决方案,要么会导致矛盾; the latter eliminates that colour as a possibility for that square.后者消除了该颜色作为该正方形的可能性。

When picking a square to branch on, it's generally a good idea to pick a square with as few allowed colours as possible.在分支方面挑选方块时,一般是一个好主意,可以选择一个尽可能少的允许颜色。

[EDIT: It's important to avoid the possibility of forming invalid "loops" of pipe. [编辑:避免形成无效的管道“循环”的可能性很重要。 One way to do this is by maintaining, for each allowed colour i of each square x, 2 bits of information: whether the square x is connected by a path of definite i-coloured tiles to the first i-coloured endpoint, and the same thing for the second i-coloured endpoint.一种方法是通过为每个方块 x 的每种允许颜色 i 维护 2 位信息:方块 x 是否通过确定的 i 色瓷砖路径连接到第一个 i 色端点,以及相同的第二个 i 色端点的事情。 Then when recursing, don't ever pick a square that has two neighbours with the same bit set (or with neither bit set) for any allowed colour.]然后在递归时,对于任何允许的颜色,永远不要选择具有相同位设置(或都没有设置)的两个邻居的正方形。]

You actually don't need to use any logical deductions at all, but the more and better deductions you use, the faster the program will run as they will (possibly dramatically) reduce the amount of recursion.您实际上根本不需要使用任何逻辑推导,但是您使用的推导越多越好,程序运行得越快,因为它们(可能会显着)减少递归量。 Some useful deductions include:一些有用的扣除包括:

  1. If a square is the only possible way to extend the path for some particular colour, then it must be assigned that colour.如果正方形是为某种特定颜色扩展路径的唯一可能方式,则必须为其分配该颜色。
  2. If a square has colour i in its set of allowed colours, but it does not have at least 2 neighbouring squares that also have colour i in their sets of allowed colours, then it can't be "reached" by any path of colour i, and colour i can be eliminated as a possibility.如果一个方块在其允许的颜色集中有颜色 i,但它没有至少 2 个相邻的方块在其允许的颜色集中也有颜色 i,那么它不能被任何颜色 i 的路径“到达” ,并且颜色 i 可以作为一种可能性被消除。

More advanced deductions based on path connectivity might help further -- eg if you can determine that every path connecting some pair of connectors must pass through a particular square, you can immediately assign that colour to the square.基于路径连通性的更高级推论可能会进一步提供帮助——例如,如果您可以确定连接某对连接器的每条路径都必须通过特定方格,则可以立即将该颜色分配给该方格。

This simple approach infers a complete solution without any recursion in your 5x5 example: the squares at (5, 2), (5, 3), (4, 3) and (4, 4) are forced to be orange;这种简单的方法在您的 5x5 示例中推断出一个没有任何递归的完整解决方案: (5, 2)、(5, 3)、(4, 3) 和 (4, 4) 处的正方形被强制为橙色; (4, 5) is forced to be green; (4, 5) 被强制为绿色; (5, 5) is also forced to be green by virtue of the fact that no other colour could get to this square and then back again; (5, 5) 也被强制为绿色,因为没有其他颜色可以到达这个方块然后又回来; now the orange path ending at (4, 4) has nowhere to go except to complete the orange path at (3, 4).现在结束于 (4, 4) 的橙色路径无处可去,只能完成 (3, 4) 处的橙色路径。 Also (3, 1) is forced to be red;并且 (3, 1) 也被强制为红色; (3, 2) is forced to be yellow, which in turn forces (2, 1) and then (2, 2) to be red, which finally forces the yellow path to finish at (3, 3). (3, 2) 被强制为黄色,依次强制 (2, 1) 和 (2, 2) 为红色,最终强制黄色路径在 (3, 3) 处结束。 The red pipe at (2, 2) forces (1, 2) to be blue, and the red and blue paths wind up being completely determined, "forcing each other" as they go. (2, 2) 处的红色管道迫使 (1, 2) 变为蓝色,并且红色和蓝色路径最终完全确定,“相互强制”。

I found a blog post on Needlessly Complex that completely explains how to use SAT to solve this problem.我在Needless Complex上找到了一篇博客文章,它完整地解释了如何使用 SAT 来解决这个问题。

The code is open-source as well, so you can look at it (and understand it) in action.该代码也是开源的,因此您可以在实际操作中查看(并理解)它。

I'll provide a quote from it here that describes the rules you need to implement in SAT:我将在这里引用它描述您需要在 SAT 中实施的规则:

  • Every cell is assigned a single color.每个单元格都分配了一种颜色。

  • The color of every endpoint cell is known and specified.每个端点单元格的颜色都是已知和指定的。

  • Every endpoint cell has exactly one neighbor which matches its color.每个端点单元格都有一个与其颜色相匹配的邻居。
  • The flow through every non-endpoint cell matches exactly one of the six direction types.通过每个非端点单元格的流与六种方向类型中的一种完全匹配。
  • The neighbors of a cell specified by its direction type must match its color.由其方向类型指定的单元格的邻居必须与其颜色匹配。
  • The neighbors of a cell not specified by its direction type must not match its color.未由其方向类型指定的单元格的邻居不得与其颜色匹配。

Thank you @Matt Zucker for creating this!谢谢@Matt Zucker创造这个!

I like solutions that are similar to human thinking.我喜欢类似于人类思维的解决方案。 You can (pretty easily) get the answer of a Sudoku by brute force, but it's more useful to get a path you could have followed to solve the puzzle.您可以(很容易)通过蛮力获得数独的答案,但获得一条您可以遵循的路径来解决难题更有用。

I observed in most of the boards that usually 1.For furthest points, you need to follow path along edge.我在大多数板子中观察到,通常 1.对于最远的点,您需要沿着边沿路径走。 2.For point nearest to each other, follow direct path if there is one. 2.对于彼此最近的点,如果有,则遵循直接路径。 Is this correct observation and can it be used to solve it efficiently?这是正确的观察,可以用来有效地解决它吗?

These are true "most of the times", but not always.这些都是“大多数时候”,但并非总是如此。

I would replace your first rule by this one : if both sinks are along edge, you need to follow path along edge.我会用这个替换你的第一条规则:如果两个水槽都沿着边缘,你需要沿着边缘沿着路径走。 (You could build a counter-example, but it's true most of the times). (您可以构建一个反例,但大多数情况下都是如此)。 After you make a path along the edge, the blocks along the edge should be considered part of the edge, so your algorithm will try to follow the new edge made by the previous pipe.沿边创建路径后,沿边的块应被视为边的一部分,因此您的算法将尝试遵循前一个管道形成的新边。 I hope this sentence makes sense...我希望这句话是有道理的...

Of course, before using those "most of the times" rules, you need to follow absolutes rules (see the two deductions from j_random_hacker's post).当然,在使用那些“大多数时候”规则之前,您需要遵循绝对规则(请参阅 j_random_hacker 帖子中的两个推论)。

Another thing is to try to eliminate boards that can't lead to a solution.另一件事是尝试消除无法找到解决方案的电路板。 Let's call an unfinished pipe (one that starts from a sink but does not yet reach the other sink) a snake, and the last square of the unfinished pipe will be called the snake's head.让我们称未完成的管道(从一个水槽开始但尚未到达另一个水槽的管道)为蛇,未完成管道的最后一个方格将称为蛇头。 If you can't find a path of blank squares between the two heads of the same color, it means your board can't lead to a solution and should be discarded (or you need to backtrack, depending of your implementation).如果您在两个相同颜色的头之间找不到空白方块的路径,则意味着您的电路板无法找到解决方案,应该丢弃(或者您需要回溯,具体取决于您的实现)。

The free flow game (and other similar games) accept as a valid solution a board where there are two lines of the same color side-by-side, but I believe that there always exists a solution without side-by-side lines.自由流动游戏(和其他类似游戏)接受将两条相同颜色的线并排的棋盘作为有效解决方案,但我相信总是存在没有并排线的解决方案。 That would mean that any square that is not a sink would have exactly two neighbors of the same color, and sinks would have exactly one.这意味着任何不是水槽的正方形都会有两个相同颜色的邻居,而水槽只有一个。 If the rule happens to be always true (I believe it is, but can't prove it), that would be an additional constraint to decrease your number of possibilities.如果规则碰巧总是正确的(我相信它是,但不能证明它),那将是减少可能性数量的额外约束。 I solved some of Free Flow's puzzles using side-by-side lines, but most of the times I found another solution without them.我使用并排线解决了 Free Flow 的一些难题,但大多数时候我找到了另一种没有它们的解决方案。 I haven't seen side-by-side lines on Free Flow's solutions web site.我还没有在 Free Flow 的解决方案网站上看到并排的线条。

A few rules that lead to a sort of algorithm to solve levels in flow, based on the IOS vertions by Big Duck Games, this company seems to produce the canonical versions.基于 Big Duck Games 的 IOS 版本,一些规则导致了一种算法来解决流程中的关卡,这家公司似乎生产了规范版本。 The rest of this answer assumes no walls, bridges or warps.这个答案的其余部分假设没有墙壁、桥梁或扭曲。

Even if your uncannily good, the huge 15x18 square boards are a good example of how just going at it in ways that seem likely get you stuck just before the end over and over again and practically having to start again from scratch.即使你出奇地好,巨大的 15x18 方板也是一个很好的例子,说明如何以似乎可能让你在结束前一遍又一遍地卡住,实际上不得不从头开始的方式进行。 This is probably to do with the already mentioned exponential time complexity in the general case.这可能与一般情况下已经提到的指数时间复杂度有关。 But this doesn't mean that a simple stratergy isn't overwhelmingly effective for most boards.但这并不意味着简单的策略对大多数董事会来说不是绝对有效的。

  1. Blocks are never left empty, therefore orphaned blocks mean you've done something wrong.块永远不会留空,因此孤立块意味着您做错了什么。

  2. Cardinally neighbouring cells of the same colour must be connected.必须连接相同颜色的基本相邻单元格。 This rules out 2x2 blocks of the same colour and on the hexagonal grid triangles of 3 neighbouring cells.这排除了相同颜色的 2x2 块和 3 个相邻单元格的六边形网格三角形。

  3. You can often make perminent progress by establishing that a color goes or is excluded from a certain square.您通常可以通过确定某种颜色进入或排除在某个方块中来取得持久的进展。

  4. Due to points 1 and 2, on the hexagonal grid on boards that are hexagonal in shape a pipe going along an edge is usually stuck going along it all the way round to the exit, effectively moving the outer edge in and making the board smaller so the process can be repeated.由于第 1 点和第 2 点,在六边形板上的六边形网格上,沿边缘延伸的管道通常被卡住,一直绕到出口,有效地将外边缘移入并使板变小,因此该过程可以重复。 It is predictable what sorts of neighbouring conditions guarantee and what sorts can break this cycle for both sorts of grid.可以预测什么样的相邻条件可以保证以及什么样的条件可以打破这两种网格的这种循环。

Most if not all 3rd party variants I've found lack 1 to 4, but given these restraints generating valid boards may be a difficult task.我发现的大多数(如果不是全部)第 3 方变体都缺少 1 到 4 个,但鉴于这些限制,生成有效板可能是一项艰巨的任务。


Answer:回答:

Point 3 suggests a value be stored for each cell that is able to be either a colour, or a set of false/indeterminate values there being one for each colour.第 3 点建议为每个单元格存储一个值,该值可以是一种颜色,也可以是一组错误/不确定值,每种颜色都有一个值。

A solver could repeatedly use points 1 and 2 along with the data stored for point 3 on small neighbourhoods of paths around the ends of pipes to increasingly set colours or set the indeterminate values to false.求解器可以重复使用点 1 和点 2 以及在管道末端周围路径的小邻域上为点 3 存储的数据,以逐渐设置颜色或将不确定值设置为 false。

A few of us have spent quite a bit of time thinking about this.我们中的一些人花了很多时间思考这个问题。 I summarised our work in a Medium article here: https://towardsdatascience.com/deep-learning-vs-puzzle-games-e996feb76162我在这里的一篇 Medium 文章中总结了我们的工作: https : //towardsdatascience.com/deep-learning-vs-puzzle-games-e996feb76162

Spoiler: so far, good old SAT seems to beat fancy AI algorithms!剧透:到目前为止,好老的 SAT 似乎击败了花哨的 AI 算法!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM