如何为此深度优先搜索解决方案

时间:2015-10-12 17:00:31

标签: java search graph artificial-intelligence depth-first-search

我有一个具有State的益智游戏,具体取决于拼图中各个部分的排列。我正在尝试使用深度优先搜索解决这个难题,但我对如何处理它感到困惑。根据我的理解,深度优先搜索将搜索图形以找到解决方案,但我的谜题不是图形形式。我所知道的是目前的州和州可以实现的州。

我是否应该建立此图表,因为我发现了目前所处州的所有可能状态?难道这不会破坏目的 - 首先构建一个包含每种可能状态的图形,然后在整个图形中搜索解决方案吗?

我有一个方法可以使用Move从当前状态探索所有可能的状态,我肯定会派上用场,除非我不知道如何使用它。

2 个答案:

答案 0 :(得分:1)

您不必显式构建图表。您可以在概念上将您的问题表示为图形,其中节点是状态,边缘是状态之间的过渡。深度优先搜索是一直沿着边缘直到达到结束状态,然后移动到另一边缘。所以它看起来像这样(伪代码):

def search(state):
    if is_end_state(state):
        # search down this branch finished, do something
        return something

    for move in possible_moves_from(state):
        search(apply_move(state, move))

您最终会通过递归调用和堆栈状态隐式构建图形。

请注意,如果您有周期(例如,您可以向左移动,然后向右移动以返回完全相同的状态),那么您将必须跟踪已经访问过的状态,否则您将永远循环。像这样:

def search(state, seen_states):
    if state in seen_states:
        # already visited, don't visit again
        return 

    seen_states.add(state)

    # same as before:      
    if is_end_state(state):
        return something

    for move in possible_moves_from(state):
        search(apply_move(state, move), seen_states)

就如何实现这一点而言,我建议您seen_statesHashSet<State>,并使State可以播放。

答案 1 :(得分:0)

听起来像深度第一是错误的方式。如果你有一个州,并且你知道你可以从那个州获得的所有州,那么广度优先可能更合适。使用BFS,您会知道您遇到的第一个解决方案是最短的解决方案。

如果您确定有一个解决方案,那么您就不必担心无限递归,因为在循环中捕获的任何路径最终都不会是最短的,它们只会导致不必要的工作

使用队列的迭代解决方案可行。

/** pseudocode **/
Queue q = new LinkedList();
q.put(myState)
while ( !q.isEmpty()) {
  State s = q.remove();
  if ( endState.equals(s)) {
    return something;
  }
  for ( State newState : s.getNextStates()) {
    q.add(newState);
  }
}

如果您确实想要进行深度优先搜索,那么只需将队列更改为堆栈,然后您将不得不处理周期。

如果您的队列项是包含当前状态路径而不是当前状态的包装器,那么您可以轻松地到达最短路径所经过的深度和路径(或至少是第一条最短路径)发现是否有多条相同深度的路线。)