3

我一直在尝试不同的方式来实现深度优先搜索。我找到了一些工作方法,但它们涉及一些相当繁琐的字典工作。我使用列表开发了一个新想法,但是此实现返回的操作与所需的结果不匹配。我会尽量清楚地注释代码:

start = problem.getStartState()            ## returns an (x, y) tuple
children = problem.getSuccessors(start)    ##returns the children of a parent node in ((start                  
                                           state), action, cost) format. 
stack = Stack()                            ##creates a Stack (LIFO) data structure
visited = []                               ##list of visited nodes
visited.append(start)
for child in children:
    stack.push((child, [], [], 0))         ##push children to fringe in the format of (child,
    while stack:                           ##path taken, actions taken, cost) 
        parent = stack.pop()
        node = parent[0]
        if parent[0] in visited: continue
        visited.append(parent[0])
        path = parent[1] + [node[0]]           ##assigns previous path/actions/cost to new 
        actions = parent[2] + [node[1]]        ##node, creating a cumulative, ordered list of
        print actions                          ##the path/actions and a cumulative cost
        cost = parent[3] + node[2]
        if problem.isGoalState(node[0]):
            print parent[2]
            return parent[2]                    ## returns list of actions 
        children = problem.getSuccessors(node[0])
        if children != []:
            for child in children:
                stack.push((child, path, actions, cost))   ##assigns cumulative lists to child

任何人都看到我的问题在这个实现中可能出在哪里?顺便说一句,我知道 DFS 在大多数情况下是一种低效的算法。但是一旦我正确地实现了这个实现,它应该能够通过简单地更改存储父节点子节点的数据结构来跨越其他搜索算法。

4

2 回答 2

6

CS188 朋友:D 在这里阅读您的代码真的很难......所有这些索引%)使用更多变量,它会更清晰。我的解决方案:

def depthFirstSearch(problem):
    fringe = util.Stack()
    expanded = set()
    fringe.push((problem.getStartState(),[],0))
    
    while not fringe.isEmpty():
        curState, curMoves, curCost = fringe.pop()
        
        if(curState in expanded):
            continue
        
        expanded.add(curState)
        
        if problem.isGoalState(curState):
            return curMoves
        
        for state, direction, cost in problem.getSuccessors(curState):
            fringe.push((state, curMoves+[direction], curCost))
    return []

我希望我不需要评论它。很容易阅读:)祝您有美好的一天;)

于 2012-10-16T15:03:52.490 回答
4

你似乎有名字冲突。注意:

children = problem.getSuccessors(start)    ##returns the children of a parent node in ((start                  
... 
for child in children:
    ...
    while stack:
        ...
        children = problem.getSuccessors(node[0])
        ...

在第一次迭代之后,您的原始子代会丢失,因为它被内部循环中的子代覆盖。

一般来说,DFS最好使用递归函数实现,大致如下(未经测试):

def dfs(problem, state, visited):
    visited.append(state)

    # have we reached the goal?
    if problem.isGoalState(state):
        return [state]

    for child in problem.getSuccessors(state):
        # if child is already visited, don't bother with it
        if child in visited: continue

        # otherwise, visit the child
        ret = dfs(problem, child, visited)

        if ret is not None:
            # goal state has been reached, accumulate the states
            ret.append(state)
            return ret

    return None # failed to find solution here
    # note that Python return None by default when reaching the end of a function
于 2012-10-16T14:55:27.743 回答