简体   繁体   English

能够使用DFS查找路径,但无法指定前往Pacman的正确方向_ Python

[英]Able to find path using DFS but not able specify the right directions to Pacman _ Python

I am working on an assignment found on an AI course page at berkley website for fun. 我正在做一个任务,该任务位于伯克利网站的AI课程页面上,很有趣。 I need to write a depth-first search for the pacman game so that it can find its path.The problem is the pacman gets stuck. 我需要对pacman游戏进行深度优先搜索,以便找到路径。问题是pacman卡住了。 I'll paste the code first to make what I am saying more clear : 我将首先粘贴代码以使我所说的更加清楚:

import util

class SearchProblem:
  """
  This class outlines the structure of a search problem, but doesn't implement
  any of the methods (in object-oriented terminology: an abstract class).

  You do not need to change anything in this class, ever.
  """

  def getStartState(self):
     """
     Returns the start state for the search problem 
     """
     util.raiseNotDefined()

  def isGoalState(self, state):
     """
       state: Search state

     Returns True if and only if the state is a valid goal state
     """
     util.raiseNotDefined()

  def getSuccessors(self, state):
     """
       state: Search state

     For a given state, this should return a list of triples, 
     (successor, action, stepCost), where 'successor' is a 
     successor to the current state, 'action' is the action
     required to get there, and 'stepCost' is the incremental 
     cost of expanding to that successor
     """
     util.raiseNotDefined()

  def getCostOfActions(self, actions):
     """
          actions: A list of actions to take

     This method returns the total cost of a particular sequence of actions.  The sequence must
     be composed of legal moves
     """
     util.raiseNotDefined()


def tinyMazeSearch(problem):
  """
      Returns a sequence of moves that solves tinyMaze.  For any other
  maze, the sequence of moves will be incorrect, so only use this for tinyMaze
  """
  from game import Directions
  s = Directions.SOUTH
  w = Directions.WEST
  return  [s,s,w,s,w,w,s,w]

def depthFirstSearch(problem):

  """
  Search the deepest nodes in the search tree first [p 74].

  Your search algorithm needs to return a list of actions that reaches
  the goal.  Make sure to implement a graph search algorithm [Fig. 3.18].

  To get started, you might want to try some of these simple commands to
  understand the search problem that is being passed in:

  print 'Start:', problem.getStartState()
  print 'Is the start a goal?', problem.isGoalState(problem.getStartState())
  print 'Start's successors:', problem.getSuccessors(problem.getStartState())

  """

  # *** YOUR CODE HERE ***


  start = [problem.getStartState()]
  for item in start:
      Open=[item]
  State=[]
  Closed=[]
  Path=[]

  if problem.isGoalState(Open[0]) is True:
      return State
  else:
       while Open:
                visit= Open.pop()
                Closed.append(visit)
                if State: 
                  Path.append(State.pop())

                if problem.isGoalState(visit) is True:
                    print Closed
                    return Path
                else:
                    Successors= problem.getSuccessors(visit)
                    for index in Successors:
                            it=iter(index)
                            data=it.next()

                            if data not in Closed :
                              Open.append(data)
                              State.append(it.next())
                            else:
                              print Path

Now if you will read my code under dfs you will see that open list contains all the points I visit and expanded. 现在,如果您在dfs下阅读我的代码,您将看到打开的列表包含我访问并扩展的所有点。

The Path file contains the direction set for the pacman. 路径文件包含为pacman设置的方向。 The problem arises when I face the condition that both successors I get are unvisited, my pacman takes a path which leads to a dead end so it needs to backtrace. 当我遇到两个继承人都未被访问的情况时,问题就出现了,我的吃豆人走了一条通往死胡同的道路,因此需要回溯。 My Open does it and finds the solution but I am not able to find a way on how to provide the directions of backtracing in my path list. 我的公开赛做到了并找到了解决方案,但我无法找到有关如何在路径列表中提供回溯方向的方法。 If you will go to http://inst.eecs.berkeley.edu/~cs188/sp09/projects/search/search.html and download the zip and paste my code in search.py under dfs search you will understand my problem. 如果您要转到http://inst.eecs.berkeley.edu/~cs188/sp09/projects/search/search.html并下载zip并将我的代码粘贴到dfs search下的search.py ,您将理解我的问题。

Some hints: 一些提示:

  • Each node you check should encapsulate the data of how you got there. 您检查的每个节点都应封装到达目的地的数据。
  • DFS is like a stack; DFS就像一个堆栈。 you start by pushing the start state. 您可以通过按开始状态开始。 You pop the stack, and push back the nodes that can follow from the node you popped. 您弹出堆栈,然后从弹出节点中推回可以跟随的节点。
  • Since you are ultimately trying to find a path, the node data must hold your location and the path you took to get there. 由于您最终要尝试查找路径,因此节点数据必须包含您的位置以及到达该位置的路径。

How you store your path is a VERY important topic, when you consider that some of your searches might result in paths 200+ steps long. 当您认为某些搜索可能导致路径长度超过200步时,如何存储路径是非常重要的主题。 Iterating over a list that many times.... O(2^N) or O(3^N) ? 遍历一个列表很多次。... O(2 ^ N)O(3 ^ N)吗? lists for any kind of search as a path storing mechanism are the wrong answer, especially when you get into BFS and any time you have multiple objectives (meaning, multiple paths through the same node can exist). 将任何类型的搜索作为路径存储机制的列表都是错误的答案,尤其是当您进入BFS且任何时候您有多个目标(意味着,可以存在通过同一节点的多个路径)时。 List complexity and the data storage is ridiculous. 列表的复杂性和数据存储是荒谬的。

I recommend linklisting as a path storage mechanism. 我建议将链接列表用作路径存储机制。 When you push your nodes into the fringe, simply key them into a dictionary with a unique key and push the key. 当您将节点推入边缘时,只需使用唯一键将其键入字典即可,然后按下该键。 Then when you pull a node from the fringe, you can get the entire state, as is, from the dictionary. 然后,当您从边缘拉出节点时,您可以直接从字典中获取整个状态。

If part of your state is the node that that state was in one step previously, then you have a path to the start; 如果状态的一部分是该状态先前在某个步骤中的节点,则您有一条起点。 the end node links to the one behind it, which links to the one behind it, etc. Using a unique key system like this allows multiple paths through the same point, at EXTREMELY low data cost; 终端节点链接到其后面的节点,后者链接到其后面的节点,依此类推。使用这样的独特密钥系统,可以通过同一点进行多条路径,而数据成本极低; you still must be rational about which paths you pull off the fringe. 您仍然必须对从边缘拉出的路径保持理性。 However, any time you pull anything off the fringe, you pull it's entire path, with only 1 number. 但是,每当您从边缘拉出任何东西时,就只用一个数字就拉开了它的整个路径。

I did get it work by making sure each move is only 1 distance. 我确实通过确保每一步只有1个距离来使它起作用。 One of the issue with your code was at the end it try to jump 5 or 6 places. 您的代码的问题之一是,最后它试图跳到5或6位。 Make sure every move it make is one and reverse till move distance become 1 to your next destination. 确保它所做的每一步都是一次并反向,直到到下一个目的地的移动距离变为1。 Hint manhattanDistance(). 提示manhattanDistance()。

 start = [problem.getStartState()]
  for item in start:
      Open=[item]
  Closed=[]
  Path=[]

  if problem.isGoalState(Open[0]) is True:
      return 
  else:
       count=0
       while Open:
                if count==0:
                  visit=Open.pop()
                else:
                  temp=Open.pop()
                  visit=temp[0]

                Closed.append(visit)                            
                if problem.isGoalState(visit) is True:
                    return Path
                else:
                    Successors= problem.getSuccessors(visit)
                    for index in Successors:
                            if index[0] not in Closed :
                              Open.append((index[0],index[1]))
                print Open
                count=count+1

i changed the code as u said. 我按照您说的更改了代码。 right now i am not having anything in path. 现在我什么都没走。

this open after finding the solution -( 1,1 is the solution) 找到解决方案后打开-(1,1是解决方案)

[((5, 4), 'South'), ((4, 5), 'West')]
[((5, 4), 'South'), ((3, 5), 'West')]
[((5, 4), 'South'), ((2, 5), 'West')]
[((5, 4), 'South'), ((1, 5), 'West')]
[((5, 4), 'South'), ((1, 4), 'South')]
[((5, 4), 'South'), ((1, 3), 'South')]
[((5, 4), 'South'), ((2, 3), 'East')]
[((5, 4), 'South'), ((2, 2), 'South')]
[((5, 4), 'South'), ((2, 1), 'South'), ((3, 2), 'East')]
[((5, 4), 'South'), ((2, 1), 'South'), ((4, 2), 'East')]
[((5, 4), 'South'), ((2, 1), 'South'), ((4, 3), 'North')]
[((5, 4), 'South'), ((2, 1), 'South'), ((5, 3), 'East')]
[((5, 4), 'South'), ((2, 1), 'South'), ((5, 4), 'North')]
[((5, 4), 'South'), ((2, 1), 'South')]
[((5, 4), 'South'), ((1, 1), 'West')]

now if you will notice when it gets three list members it takes a path which was a dead end now the Open is able to backtrace and find the correct path but i need a way to somewhow specify the return direction in the Path variable like 现在,如果您会注意到当它得到三个列表成员时,它采用的路径是死胡同,现在Open可以回溯并找到正确的路径,但是我需要一种方法以某种方式在Path变量中指定返回方向,例如

for eg Path = ['south',west' west'.................] etc 例如路径= ['south',west'west'.................]等

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

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