统一成本图搜索打开太多节点

时间:2016-07-15 00:46:57

标签: search optimization graph

我正在从2014年开始的归档AI课程作业。

参数“问题”是指在运行时选择具有不同成本函数的对象(有时每次移动成本为1;有时移动的成本更高,具体取决于进行移动的pacman板的哪一侧)。 / p>

如下所示,我得到了正确的行为,但是我打开了比预期更多的搜索节点(大约是作业所期望的2倍)。

如果我将成本变量转为负数,我会在1单位成本情况下获得正确的行为并获得非常少的节点数。但对于董事会特定方面的成本较高的情况,这种行为是相反的。

所以基本上问题是:在统一成本搜索的背景下,我是否正在不必要地打开任何节点?

def uniformCostSearch(problem):
    """Search the node of least total cost first."""
    def UCS(problem, start):


            q = util.PriorityQueue()
            for node in problem.getSuccessors(start): ## Comes a tuple ((x,y), 'North', 1)
                q.push([node], node[2])  ##Push nodes onto queue one a time (so they are paths)

            while not q.isEmpty():
                pathToCheck = q.pop() ##Pops off the lowest priorty path on the queue?
                #if pathToCheck in q.heap:
                #    continue
                lastNode = pathToCheck[-1][0] ## Gets the coordinates of that last node in that path
                if problem.isGoalState(lastNode): ##Checks if those coordinates are goal
                    return pathToCheck  ## If goal, returns that path that was checked
                else: ## Else, need to get successors of that node and put them on queue
                    for successor in problem.getSuccessors(lastNode): ##Gets those successors the popped path's last node and iterates over them
                        nodesVisited = [edge[0] for edge in pathToCheck] ##Looks at all the edges (the node plus its next legal move and cost) and grabs just the coords visited (nodes)
                        if successor[0] not in nodesVisited: ## ##Checks to see if those visited were in THIS particular path (to avoid cyclces)
                            newPath = pathToCheck + [successor] ## If ONE successor was not in path, adds it to the growing path (will do the next one in next part of loop)
                            cost = problem.getCostOfActions([x[1] for x in newPath])
                            q.update(newPath, cost) #Pushes that validated new path onto the back of the queue for retrieval later
            return None

    start = problem.getStartState()#Starting point of stack
    successorList = UCS(problem, start)
    directions = []
    for i in range(len(successorList)):
        directions += successorList[i]
    return directions[1::3]

1 个答案:

答案 0 :(得分:0)

我明白了。

基本上,当我检查我没有重新访问给定路径中的节点时,我不会检查我是否正在访问队列中其他路径中的节点。我可以通过添加一个nodesVisited列表来检查,该列表只是附加了所有访问过的节点并检查了重复访问。