【问题标题】:How to find shortest path in this type of maze如何在这种类型的迷宫中找到最短路径
【发布时间】:2015-11-04 06:15:59
【问题描述】:

Red Dot - Represents the initial location
Black Dot - Already occupied
Green - Free to occupy
Destination - Boundry of the matrix [which means either x = 0 or y = 0 or x = 8 or y = 8]

示例:

red dot 一次只能移动一次,并且可以在与其相连的六个绿色圆圈之一中移动。 在这种迷宫中计算最短路径的最快方法是什么。

【问题讨论】:

  • 什么是“路径”?你能举一些例子吗?为包含漂亮图片的问题投票。
  • 这到底是什么意思?目标 - 矩阵的边界 [表示 x = 0 或 y = 0 或 x = 9 或 y = 9] 9 次成功移动?
  • 见编辑中的例子。红点必须到达迷宫的边界。
  • 开始总是在中间还是可以无处不在?
  • @MarkusHütter 是的。它可以在迷宫中的任何地方

标签: algorithm path shortest-path breadth-first-search shortest


【解决方案1】:

首先,您不需要 Dijkstra,因为边的所有值都是相同的。您可以使用简单的BFSDFS 算法。最坏情况的复杂性是相同的,但我会使用 BFS,因为它具有更好的平均情况复杂性。但是,O(|V|+|E|) 是您可以达到的最快速度,并且已被证明。

如何表示您的图表?最好的方法是为每个Node 保留一个邻居列表。您示例中的黑点不算作邻居。因此,在您的示例中,每个节点将有 0(完全被黑点覆盖)到 6 个邻居。然后,您可以通过这些列表从任何节点点到达任何地方。

BFS 算法有一个属性,它为每个节点分配一个层,这意味着它与起始节点的距离。你从你的起点开始,你的当前层将为0。然后你只需跟随当前层中的所有节点(通常保留在队列中)并尝试找到它的邻居(从他们的邻居列表中),它没有层分配,你分配给他们+1更高的层。一旦你在迷宫的边界找到你的节点(它仍然可以将 x,y 作为边界检查的属性(或属性布尔边界)),你就知道它与你的层值一样远。如果你想打印准确的方式,你只需要找到返回的方式(通过你的邻居列表),它满足每一步都在 -1 层以下的条件。这将打印从头到尾的方式,但我相信您会在 Stack 数据结构的一些帮助下获得结果:)

【讨论】:

    【解决方案2】:

    您所拥有的是一个“简单”的图形问题。图形连接是您拥有的合法移动。起始节点是你的红点。要获得单个终端节点,请在给定迷宫外再创造一个圆圈;以零成本的移动将所有真正的出口节点连接到新圆。

    现在,应用 Dijkstra 算法。完成。


    查看问题的另一种方法是递归。移动红点,将旧位置标记为黑色。从新位置再次出现。退出时返回(返回路径长度 1)或没有合法移动(返回路径长度无限)。保持最短的已知路径。

    这些能让你摆脱困境吗?

    【讨论】:

      【解决方案3】:

      A* 搜索算法

      (来自: https://en.wikipedia.org/wiki/A*_search_algorithm)

      下面的伪代码描述了算法[可疑 – 讨论]:

      function A*(start,goal)
          ClosedSet := {}       // The set of nodes already evaluated.
          OpenSet := {start}    // The set of tentative nodes to be evaluated, initially containing the start node
          Came_From := the empty map    // The map of navigated nodes.
      
      
          g_score := map with default value of Infinity
          g_score[start] := 0    // Cost from start along best known path.
          // Estimated total cost from start to goal through y.
          f_score := map with default value of Infinity
          f_score[start] := g_score[start] + heuristic_cost_estimate(start, goal)
      
          while OpenSet is not empty
             current := the node in OpenSet having the lowest f_score[] value
              if current = goal
                  return reconstruct_path(Came_From, goal)
      
             OpenSet.Remove(current)
             ClosedSet.Add(current)
             for each neighbor of current
                 if neighbor in ClosedSet 
                     continue     // Ignore the neighbor which is already evaluated.
              tentative_g_score := g_score[current] + dist_between(current,neighbor) // length of this path.
              if neighbor not in OpenSet  // Discover a new node
                  OpenSet.Add(neighbor)
              else if tentative_g_score >= g_score[neighbor] 
                  continue        // This is not a better path.
      
              // This path is the best until now. Record it!
              Came_From[neighbor] := current
              g_score[neighbor] := tentative_g_score
              f_score[neighbor] := g_score[neighbor] + heuristic_cost_estimate(neighbor, goal)
      
      return failure
      
      function reconstruct_path(Came_From,current)
          total_path := [current]
          while current in Came_From.Keys:
              current := Came_From[current]
              total_path.append(current)
          return total_path
      

      所以,据我了解 - 您可以将起始节点设置在红点位置 \ 中心位置,并将目标节点设置为 x = 0 或 y = 0 或 x = 8 或 y = 8(您可以4个函数调用,取最少)

      至于节点的启发式值 - 只需将黑色阻塞节点设置为非常高的启发式值,这将使它们无法到达,因此算法将绕过它们。

      【讨论】:

      • 如果能简单介绍一下算法的作用就好了。 SO 帮助中心 stackoverflow.com/help/deleted-answers> 说:为什么以及如何删除某些答案?不能从根本上回答问题的答案可能会被删除。这包括以下答案:…… • 仅是指向外部网站的链接
      猜你喜欢
      • 2012-04-08
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      相关资源
      最近更新 更多