解决迷宫收集硬币的高效算法

时间:2018-11-29 06:19:38

标签: algorithm graph-algorithm shortest-path maze

在以固定数量的步骤收集最多数量的硬币的同时,用于解决迷宫(最好是图形)的最佳算法是什么?

每个边缘都有一个距离,每个节点都有一定数量的硬币(0-n个硬币)

给出固定的步骤总数作为输入,并确保在这些步骤之后有解决迷宫的解决方案。

谢谢

1 个答案:

答案 0 :(得分:3)

对不起,您找不到针对该问题的有效解决方案,它是 NP-hard ,这意味着如果您想要精确的解决方案,它将具有指数级的复杂性。这可以通过减少Knapsack问题来证明。

假设您有一个带 n 项的背包实例,设置了重量的 w_0 ... w_n 并设置了 v_0 ..._ v_n 值和容量 W ,我们可以构建一个图形,其中每个顶点对应一个值,再加上2个额外的顶点 s e 并结束。从权重 w_i / 2 创建从 s 到每个顶点 v_i 的边,以及从 v_i 到每个顶点的边顶点 e 和相应的权重 w_i / 2 。现在,找到从 s e 的路径,该路径的长度被限制为 W 。此路径将不会再访问顶点 v_i 一次,因为收集硬币后没有理由返回该节点。另外,要访问任何 v_i 并转到 e ,无论是从s还是从e返回,它都会花费完全的 w_i 步骤。该解决方案保证不超过步长限制,并且值的组合最大。因此,只需选择访问过的所有顶点 v_i ,我们便可以解决NP困难的Knapsack优化版本。

现在这还不是那么糟糕。问题有解决方案,只是效率低下。对于小迷宫,它仍然可以使用蛮力进行工作,即从顶点开始,然后尝试递归地朝任何方向移动。如果超过最大步数-中止。如果到达目的地-返回路径。然后,在所有返回的路径中,选择产生最多硬币的路径。

此外,如果不需要精确的解决方案,则可以尝试提供近似的解决方案。例如,您可以使用Dijkstra算法来生成最短路径树。因此,现在您有了从源到每个顶点的最短路径。选择从源到目标的路径,并尝试迭代地进行改进。在每次迭代中,在路径上选择一个顶点,查看其所有邻居,并查看通过该邻居的顶点会为您提供更好的价值,同时仍受步骤约束。这不一定会为您提供最佳解决方案,但可能会产生一些好的解决方案。

然后,您可以尝试其他优化,例如“捡硬币然后跑”。查看您的路径,并尝试通过从某个顶点到其相邻点来改善它,然后立即返回。如果迷宫有死胡同,这可能会很有用,这样自然就不会去那里到达目的地,但是您有足够的步骤去那里收集硬币并返回。

我希望这会有所帮助。