Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何对深度优先搜索解决方案建模_Java_Search_Graph_Artificial Intelligence_Depth First Search - Fatal编程技术网

Java 如何对深度优先搜索解决方案建模

Java 如何对深度优先搜索解决方案建模,java,search,graph,artificial-intelligence,depth-first-search,Java,Search,Graph,Artificial Intelligence,Depth First Search,我有一个益智游戏,它有一个状态,这取决于拼图中各部分的排列。我试图用深度优先搜索来解决这个难题,但是我对如何解决这个问题感到困惑。据我所知,深度优先搜索将搜索一个图形以找到解决方案,但我的难题不是图形形式。我所知道的只是当前的状态以及从该状态可以达到的状态 当我从当前的状态中发现所有可能的状态时,我是否应该构建这个图?但是,这不是违背了目的吗?首先用每个可能的状态构建一个图,然后在整个图中搜索解决方案 我有一种方法,可以使用移动从当前状态探索所有可能的状态,我相信这会很有用,除非我不知道如何使用

我有一个益智游戏,它有一个
状态
,这取决于拼图中各部分的排列。我试图用深度优先搜索来解决这个难题,但是我对如何解决这个问题感到困惑。据我所知,深度优先搜索将搜索一个图形以找到解决方案,但我的难题不是图形形式。我所知道的只是当前的状态以及从该状态可以达到的状态

当我从当前的状态中发现所有可能的状态时,我是否应该构建这个图?但是,这不是违背了目的吗?首先用每个可能的状态构建一个图,然后在整个图中搜索解决方案


我有一种方法,可以使用
移动
从当前状态探索所有可能的状态,我相信这会很有用,除非我不知道如何使用它。

您不必显式地构建图形。从概念上讲,您可以将问题表示为一个图,其中节点是状态,边是状态之间的转换。深度优先搜索是在移动到另一条边之前,一直跟踪一条边,直到到达结束状态。所以它看起来像这样(伪代码):

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

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

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)

就如何实现这一点而言,我建议您将
状态
设置为
哈希集
,并将
状态
设置为可哈希。

在我看来,深度优先是错误的。如果你有一个州,并且你知道你能从这个州到达的所有州,那么广度优先可能更合适。有了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);
  }
}
如果您确实想进行深度优先搜索,那么只需将队列更改为堆栈,但您必须处理循环


如果您的队列项目是一个包装器,其中包含到当前状态的路径,而不仅仅是当前状态的路径,那么您可以很容易地获得最短路径所经过的深度和路径(或者,如果有多条相同深度的路径,则至少是发现的第一条最短路径)

那么本质上,这只需要沿着一条“路径”一直搜索,然后倒带,直到找到解决方案?如何判断当前状态中的一个可能状态是否已经存在?我的意思是,如果我移动的片段足够多,我将得到重复的状态,它将永远循环。@Brejuro:请参阅更新。你只需要跟踪所看到的状态,如果你已经看到了,就不要去那里,例如,把它们放在一个集合中。谢谢你的帮助,把它建模成一个图形有意义吗?如中所示,在运行时添加节点和边?我还计划实现其他搜索算法,所以我不确定使用图实现是否有用。
/** 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);
  }
}