关于DFS的两个递归函数的差异

时间:2012-10-22 05:42:20

标签: python recursion depth-first-search

我正在从人工智能项目开发一个python程序。这是关于深度优先搜索。 我有一个python代码可以正常工作:

def depthFirst(problem,start,path,result,vis):
    next=problem.getSuccessors(start)
    if problem.isGoalState(start):
        result.append(path)
        print path
    for I in next:
        if I[0] not in vis:
            vis.append(I[0])
            depthFirst(problem,I[0],path+[I[1]],result,vis)
            vis.pop()

    def depthFirstSearch(problem):
        start=problem.getStartState()
        result=[]
        depthFirst(problem,start,[],result,[])
        return result[-1]

我知道对于数字,python不能返回它的引用,但是对于列表,它传递它的引用而不是它的值。

我写了类似的程序;这里我使用变量path而不是result

def depthFirst(problem,start,path,vis):
    if problem.isGoalState(start[0]):
        print 'Start1',start[1]

        print 'Path',path
        l=start[1]
        path.append(l)
        path=path[0]
        print 'FindPath',path

        return

    #vis.add(start[0])
    fringe=problem.getSuccessors(start[0])
    for child in fringe:
        '''if problem.isGoalState(child):
            path.apend(child[1])

            break
            return'''
        print child
        if child[0] not in vis:
            tmppath=start[1][:]
            tmppath.append(child[1])

            vis.add(child[0])
            print 'vis=',vis
            print path
            depthFirst(problem,(child[0],tmppath),path,vis)
        print 'path=',path

def depthFirstSearch(problem):
    start=problem.getStartState()
    path=[]
    vis=set([])

    depthFirst(problem,[start,[]],path,vis)
    print path[0]
    return path[0]

但它确定了一条与第一条路径截然不同的路径。我认为这两个程序是相同的,但我只是想将result更改为path。怎么会有所不同。

2 个答案:

答案 0 :(得分:0)

我已尽最大努力为您的代码中的某些问题添加注释,并希望它能解决您的问题:

def depthFirst(problem,start,path,vis):
    if problem.isGoalState(start[0]):
        l=start[1]      # just use path.append(start[1]) here
        path.append(l)  # AND why do you even need path here at all???
        path=path[0]    # if you assign path=path[0], then don't call path[0]
                        # in depthFirstSearch
        return

    # vis.add(start[0]) # Why comment this out? Move this to the top!
    fringe=problem.getSuccessors(start[0])
    for child in fringe:
        if child[0] not in vis:
            tmppath=start[1][:]
            tmppath.append(child[1])
            vis.add(child[0])  # you AREN'T discovering it yet, don't add it here!
            depthFirst(problem,(child[0],tmppath),path,vis)

def depthFirstSearch(problem):
    start=problem.getStartState()
    path=[]
    vis=set([])
    depthFirst(problem,[start,[]],path,vis)
    return path[0]  # should be path instead here since you assigned path=path[0]

这是我认为应该有效的固定版本:

def depthFirst(problem,start,path,vis):
    vis.add(start[0])

    if problem.isGoalState(start[0]):
        path.append(start[1])  # still convoluted..
        path = path[0]
        return True

    fringe=problem.getSuccessors(start[0])
    for child in fringe:
        if child[0] not in vis:
            tmppath = start[1][:]
            tmppath.append(child[1])
            depthFirst(problem, (child[0], tmppath), path, vis)

def depthFirstSearch(problem):
    start=problem.getStartState()
    path=[]
    vis=set([])
    if depthFirst(problem, [start, []], path, vis):
        return path

答案 1 :(得分:-2)

我对python不是很熟悉,但如果你需要通过引用传递var,也许这会对你有所帮助:How do I pass a variable by reference?