Может найти путь с помощью DFS, но не может указать правильные направления для Pacman _ Python

1

Я работаю над заданием, найденным на странице курса AI на веб-сайте berkley для удовольствия. Мне нужно написать поиск в глубину для игры pacman, чтобы он мог найти свой путь. Проблема заключается в том, что pacman застревает. Сначала я вставлю код, чтобы сделать то, что я говорю более ясно:

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 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

Теперь, если вы прочитаете мой код под dfs, вы увидите, что открытый список содержит все точки, которые я посещаю и расширяю.

Файл Path содержит направление, заданное для pacman. Проблема возникает, когда я сталкиваюсь с тем условием, что оба преемника, которых я получаю, не рассматриваются, мой пакман берет путь, который ведет в тупик, поэтому ему нужно возвращаться. Мой Open делает это и находит решение, но я не могу найти способ, как обеспечить направления backtracing в моем списке путей. Если вы перейдете на сайт http://inst.eecs.berkeley.edu/~cs188/sp09/projects/search/search.html и загрузите zip и вставьте мой код в search.py в поисках dfs, вы поймете мою проблему.

  • 0
    по какой-то причине мой код под dfs отображается красным, если кто-то знает, как его редактировать, то сделайте !! :)
Теги:
depth-first-search
pacman

4 ответа

3
Лучший ответ

Некоторые подсказки:

  • Каждый проверенный вами узел должен инкапсулировать данные о том, как вы туда попали.
  • DFS - как стек; вы начинаете с нажатия на начальное состояние. Вы кладете стек и отталкиваете узлы, которые могут следовать за узлом, который вы выскочили.
  • Поскольку вы в конечном счете пытаетесь найти путь, данные узла должны содержать ваше местоположение и путь, который вы сделали, чтобы добраться туда.
  • 0
    да, у меня есть путь в Open. Если он попадает в тупик, он выталкивает элемент из стека до точки, где он получает неисследованный узел. Но список путей, который содержит направление с указанием на юг, север и т. Д., Я не могу указать правильный путь в нем, потому что это будет означать пересечение посещенного узла снова. Если вы запустите мой код и путь печати, вы будете знать, что я говорю !!
  • 0
    У вас слишком много структур данных, и это делает всю установку слишком сложной. Зачем вам массив State и Path, если вы просто собираетесь переместить данные из State в Path? Я бы также рекомендовал просто обращаться к данным-преемникам с помощью индексов, а не создавать итераторы (то есть для преемника в problem.getSuccessors (посещение): position = successor [0], action = successor [1] и т. Д.)
2

Как вы храните свой путь, ОЧЕНЬ важная тема, если учесть, что некоторые из ваших поисков могут привести к длительным шагам 200+. Итерируя по списку, который много раз.... O (2 ^ N) или O (3 ^ N)? списки для любого вида поиска в качестве механизма хранения пути являются неправильным ответом, особенно когда вы попадаете в BFS и в любое время имеете несколько целей (что означает, что могут существовать несколько путей через один и тот же узел). Сложность списков и хранение данных смехотворны.

Я рекомендую ссылки в качестве механизма хранения пути. Когда вы нажимаете свои узлы на бахрому, просто введите их в словарь с уникальным ключом и нажмите клавишу. Затем, когда вы вытаскиваете узел из бахромы, вы можете получить все состояние, как есть, из словаря.

Если частью вашего состояния является узел, в котором это состояние было за один шаг ранее, тогда у вас есть путь к началу; конечный узел ссылается на тот, который находится за ним, который связан с ним позади него и т.д. Использование уникальной ключевой системы, такой как это, позволяет использовать несколько путей через одну и ту же точку, при ЧРЕЗМЕРНО низкой стоимости данных; вы все равно должны быть рациональны в отношении путей, которые вы снимаете с края. Тем не менее, в любое время, когда вы вытаскиваете что-либо из бахромы, вы тянете весь путь, всего 1 номер.

1

Я сделал это, убедившись, что каждый ход - всего лишь 1 дистанция. Одна из проблем с вашим кодом заключалась в том, что он пытался прыгнуть на 5 или 6 мест. Удостоверьтесь, что каждое движение, которое он делает, одно и наоборот, пока расстояние перемещения не станет 1 до вашего следующего пункта назначения. Подсказка manhattanDistance().

  • 0
    У меня похожая проблема. Что может сделать Манхэттен, чтобы помочь моему делу здесь?
0
 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

я изменил код, как сказал. прямо сейчас у меня нет ничего в пути.

это открытое после нахождения решения - (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')]

теперь, если вы заметите, когда он получит три члена списка, он принимает путь, который был тупиком, теперь Open способен выполнить обратный путь и найти правильный путь, но мне нужен способ как-то указать направление возврата в переменной Path, как

например, Path = ['south', west 'west'.................] и т.д.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню