【问题标题】:Solving a maze with HashMap用 HashMap 解迷宫
【发布时间】:2022-01-13 01:56:56
【问题描述】:

我正在努力寻找解决迷宫的方法。 HashMap 的键是房间,值是您可以从中访问的房间列表。

Map<String, String> map ={Entrance=[R1], Room1=[R2,R4], R2=[R1,R3], R3=[R2,R4,Exit], R4=[R1,R3]}

每个 Rn 都是一个房间。

List<String> key = map.get("Entrance");
List<String> path = new List<>();
Stack<String> visited = new Stack<>();
visited.add("Entrance");
for (String x : key){
   if (!visited.contains(x))
      path.add(x);
   else
      return path;
}

我知道我应该做一些回溯,但不知道从这里去哪里。我不知道如何让它返回房间列表,所以它是通往出口的路径。

【问题讨论】:

  • 这是一个纸和笔将提供更多帮助的时代。您从一个房间(入口)开始,它有 1 个或多个出口。您需要确定您以前是否访问过任何房间,如果没有,只需选择一个并跳入其中,然后基本上重复,直到您走到死胡同。如果您无法继续前进,请回溯,直到找到另一个可以访问的房间,始终避免“访问过”的房间
  • 谢谢,我只是不确定我应该如何实现它。
  • 在你用笔和纸完成这个之后(就像上面建议的那样)我想你会想把它表示为一个图,然后在这个图上运行图算法,比如 Dijkstra 的最短路径算法.可能并不总是有解决方案。但是在 Google 上搜索“Dijkstra 的 Java”和“Dijkstra 的 Graph Java”,找到您理解的解决方案。
  • 你也可以考虑使用类似GeeksForGeeks, backtacking 的例子。我最近实现了“老鼠迷宫”的一个变体,根据你的例子,它似乎是一个很好的匹配。虽然它确实使用了递归,但没有它我能够生成你的问题的基本结果
  • 我们无法为您解决这个问题。斗争(尽管很痛苦)将帮助您更好地了解将来如何解决其他问题。例如,在我的测试中,我使用LinkedList 来跟踪“好”路径,因为它允许我有效地使用它作为 LIFO 队列,以及List 来跟踪所有我去过的房间。这些是您需要能够做出和理解的关键决策点

标签: java loops nested-loops


【解决方案1】:

所以,基本上,你所拥有的是......

            +----+----+
Entrance -> | R1 | R4 |
            +----+----+
            | R2 | R3 | -> Exit
            +----+----+

你需要找到去R3的路(出口在哪里)

所以,我们可以看看这个问题,像这样。

我们从entrance开始

+--------------+-----------------+------+---------+
| Current Room | Available Exits | Path | History |
+--------------+-----------------+------+---------+
| Entrance     | R1              |      |         |
+--------------+-----------------+------+---------+

将当前房间添加到历史记录

+--------------+-----------------+------+----------+
| Current Room | Available Exits | Path | History  |
+--------------+-----------------+------+----------+
| Entrance     | R1              |      | Entrance |
+--------------+-----------------+------+----------+

是否包含Exit?不,那我们找个房间去,在这种情况下,R1是我们唯一的选择,让我们去R1。将Entrance 添加到我们的路径

+--------------+------------------+----------+----------+
| Current Room | Available Exits  |   Path   | History  |
+--------------+------------------+----------+----------+
| R1           | Entrance, R2, R4 | Entrance | Entrance |
+--------------+------------------+----------+----------+

是否包含Exit?不。好的,我们需要删除我们已经访问过的所有房间。这给我们留下了R2R4,不管我们选择哪个。

将当前房间添加到历史和路径中

+--------------+------------------+-------------+-------------+
| Current Room | Available Exits  |    Path     |   History   |
+--------------+------------------+-------------+-------------+
| R1           | Entrance, R2, R4 | Entrance,R1 | Entrance,R1 |
+--------------+------------------+-------------+-------------+

我们去R4

+--------------+-----------------+-------------+-------------+
| Current Room | Available Exits |    Path     |   History   |
+--------------+-----------------+-------------+-------------+
| R4           | R1, R3          | Entrance,R1 | Entrance,R1 |
+--------------+-----------------+-------------+-------------+

是否包含Exit?不,我们已经是R1,所以剩下的就是R3

R4 添加到我们的路径和历史中

+--------------+-----------------+----------------+----------------+
| Current Room | Available Exits |      Path      |    History     |
+--------------+-----------------+----------------+----------------+
| R4           | R1, R3          | Entrance,R1,R4 | Entrance,R1,R4 |
+--------------+-----------------+----------------+----------------+

我们去R3

+--------------+-----------------+----------------+----------------+
| Current Room | Available Exits |      Path      |    History     |
+--------------+-----------------+----------------+----------------+
| R3           | R2, R4, Exit    | Entrance,R2,R4 | Entrance,R2,R4 |
+--------------+-----------------+----------------+----------------+

是否包含Exit?是的!!!

将它添加到我们的路径中,让我们开始吧!!

+--------------+-----------------+---------------------+---------------------+
| Current Room | Available Exits |        Path         |       History       |
+--------------+-----------------+---------------------+---------------------+
| R3           | R2, R4, Exit    | Entrance,R2,R4,Exit | Entrance,R2,R4,Exit |
+--------------+-----------------+---------------------+---------------------+

所以,你通过“迷宫”的路径是Entrance -&gt; R2 -&gt; R4 -&gt; Exit,我们甚至不需要回溯!

现在,上面的工作流程有一个模式,看看你能不能挑出来。尝试每次选择不同的房间,看看它会把你带到哪里。

从技术上讲,您不需要历史记录,因为您不太可能回溯,但如果迷宫变得更复杂,它会派上用场,因为如果您进行回溯,您会弹出最后一个元素这条路,但历史会提醒你不要再走那条路;)

老实说,我认为办公桌检查作为一个概念被低估了,我妻子对我很生气,因为我有几十本笔记簿,里面都有不同想法的不同涂鸦,全都无关,所以我需要一个笔记为每个单独的想法预订??

【讨论】:

  • 我想我明白这一点,但在回溯部分时遇到了麻烦。您可能有代码示例吗?
  • @Ferret-2742 根据您当前的输入,您实际上不需要进行回溯,只有两个可用路径,R1->R4->R3 和 R1->R2-> R3,没有一条可用的路径会把你带入死胡同,所以我暂时专注于此。如果以后需要回溯,基本概念是;如果当前房间没有可用的路线,使“当前房间”等于path 中的最后一个房间,然后重试(已将死胡同添加到历史记录中)
【解决方案2】:

您需要实现一种算法来查找路径。有多种算法可以解决这类问题。

如果您不关心效率,那么广度优先搜索可能是最容易实现的。堆栈溢出方面已经有很好的例子:

Finding the shortest path nodes with breadth first search

Breadth First Search and Depth First Search

如果您关心算法的效率(例如,您希望它处理逐渐变大的图),您将需要使用图算法,例如 Dijkstra's shortest path

有很多关于使用这种算法的教程,这里有一个这样的基于 Java 的教程。

https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-in-java-using-priorityqueue/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-22
    • 2014-05-07
    • 2020-06-14
    • 1970-01-01
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多