使用深度优先搜索的迷宫中最短距离

时间:2018-12-12 22:58:07

标签: algorithm depth-first-search breadth-first-search

给出一个MxN矩阵,其中每个元素可以是'o','s'或'g'('s'和'g'是唯一的。只有一个起点和一个终点 )。

假定起始单元格“ s”始终为(0,0)。

我们希望找到起始像元s与目标像元g之间的最短距离,同时避开障碍物o。

示例:

['s', ' ', ' ', ' ', ' ']
[' ', ' ', 'o', 'o', 'o']
['o', ' ', 'o', ' ', ' ']
[' ', ' ', ' ', 'o', ' ']
[' ', ' ', ' ', 'g', ' ']

从“ s”到“ g”的最短距离是7。

我了解我们可以使用先行搜索密码锁算法轻松解决此问题。但是,我很难理解为什么我的深度优先搜索无效

我正在用Python编写,我的代码如下。

class Solution:
   :type maze: list of list
   :type start: tuple
   :type end: tuple
   :rtype: int
   def findShortestDistance(self, maze, start, end):
      self.shortest=math.inf

      #set the default value of visited to be False
      self.visited=defaultdict(lambda: False)

      self.maze=maze
      self.rows=len(maze)
      self.cols=len(maze[0])
      self.depthFirstSearch(0,0,0)
      return self.shortest

   def depthFirstSearch(self, i, j, numStep):
      if i<0 or j<0 or i>=self.rows or j>=self.cols:
         return
      elif self.maze[i][j]=='o':
         return
      elif self.maze[i][j]=='g':
         self.shortest=min(self.shortest,numStep)
         return
      elif self.visited[(i,j)]:
         return

      self.visited[(i,j)]=True

      self.depthFirstSearch(i-1,j,numStep+1)
      self.depthFirstSearch(i,j-1,numStep+1)
      self.depthFirstSearch(i,j+1,numStep+1)
      self.depthFirstSearch(i+1,j,numStep+1)

      self.visited[(i,j)]=False

我真的看不到为什么这行不通,但是我无法通过几个隐藏的测试用例来解决这个问题。

还可以有人告诉这个算法运行时间吗?在我看来,就像指数。

2 个答案:

答案 0 :(得分:0)

这里的DFS并不是一个好主意,因为您将不断地重新访问相同的子路径,并且还因为您将不得不探索所有可能的路径以找到最短的路径。一般而言,当您在进行重复工作时遇到递归问题时,应该考虑动态编程。但是,在这种特定情况下,您可以使用DFS,实际上,它与解决此问题的标准DP解决方案非常相似。

现在有关您的实现的一些注意事项:

    通常避免突变,尤其是在功能算法中。具有副作用而不是返回值的递归函数有点奇怪,尽管可以说它有助于减小堆栈的大小。
  • 我发现很难计算复杂度。它基本上等于任意长度的有效路径的数量,因此尤其是在没有障碍的情况下,这非常庞大,因为有许多长度大致等于n*m的路径。
  • 我找不到您的逻辑问题。您确定不是只是在失败的测试中超时吗?

答案 1 :(得分:0)

您的逻辑问题是,将节点标记为未访问会增加不必要的搜索, 请确保,如果A点和Dest点之间的最短浴池不能长于B点和Dest点之间的最短路径,通过A

使用以下内容

class Solution:
   def findShortestDistance(self, maze, start, end):
        self.shortest=math.inf

        #set the default value of visited to be False
        self.visited=defaultdict(lambda: False)

        self.maze=maze
        self.rows=len(maze)
        self.cols=len(maze[0])
        self.depthFirstSearch(0,0,0)
        return self.shortest

   def depthFirstSearch(self, i, j, numStep):
        if i<0 or j<0 or i>=self.rows or j>=self.cols:
            return
        elif self.maze[i][j]=='o':
            return
        elif self.maze[i][j]=='g':
            self.shortest=min(self.shortest,numStep)
            return
        elif self.visited[(i,j)]:
            return

        self.visited[(i,j)] = True
        print("{} {}".format(i,j))
        self.depthFirstSearch(i-1,j,numStep+1)
        self.depthFirstSearch(i,j-1,numStep+1)
        self.depthFirstSearch(i,j+1,numStep+1)
        self.depthFirstSearch(i+1,j,numStep+1)

        return