小言_互联网的博客

CS 188 (4) Uniform Cost Search( 统一代价搜索算法)

323人阅读  评论(0)

    本文要实现 Uniform Cost Search( 统一代价搜索算法) ,首先搜索总成本最小的节点,  统一代价搜索算法搜索到达目标。

    PriorityQueue实现一个优先级队列的数据结构,每个插入元素具有与之关联的优先级,client快速检索队列中优先级最低的元素,以 O(1) 时间复杂度访问最低优先级的元素。   

class PriorityQueue:	
    """	
      Implements a priority queue data structure. Each inserted item	
      has a priority associated with it and the client is usually interested	
      in quick retrieval of the lowest-priority item in the queue. This	
      data structure allows O(1) access to the lowest-priority item.	
    """	
    def  __init__(self):	
        self.heap = []	
        self.count = 0	

	
    def push(self, item, priority):	
        entry = (priority, self.count, item)	
        heapq.heappush(self.heap, entry)	
        self.count += 1	

	
    def pop(self):	
        (_, _, item) = heapq.heappop(self.heap)	
        return item	

	
    def isEmpty(self):	
        return len(self.heap) == 0	

	
    def update(self, item, priority):	
        # If item already in priority queue with higher priority, update its priority and rebuild the heap.	
        # If item already in priority queue with equal or lower priority, do nothing.	
        # If item not in priority queue, do the same thing as self.push.	
        for index, (p, c, i) in enumerate(self.heap):	
            if i == item:	
                if p <= priority:	
                    break	
                del self.heap[index]	
                self.heap.append((priority, c, item))	
                heapq.heapify(self.heap)	
                break	
        else:	
            self.push(item, priority)	

   Heap queue(heapq 堆队列)中堆是数组,对于所有k,a[k]<=a[2*k+1]和a[k]<=a[2*k+2],从0开始计算元素。为了比较,不存在的元素被认为是无限的,堆a[0]始终是其最小元素。

     Heap queue 堆队列的用法:

heap = []            # 新建一个空堆	
heappush(heap, item) # 将一个新的元素压入堆	
item = heappop(heap) # 从堆中取出最小的元素	
item = heap[0]       #最小是元素是heap【0】,直接获取	
heapify(x)           #将列表按线性时间转换为堆	
item = heapreplace(heap, item) # 弹出并返回最小的元素,并添加新的元素;堆大小不变

统一代价搜索算法代码:

# search.py	
# ---------	
# Licensing Information:  You are free to use or extend these projects for	
# educational purposes provided that (1) you do not distribute or publish	
# solutions, (2) you retain this notice, and (3) you provide clear	
# attribution to UC Berkeley, including a link to http://ai.berkeley.edu.	
# 	
# Attribution Information: The Pacman AI projects were developed at UC Berkeley.	
# The core projects and autograders were primarily created by John DeNero	
# (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu).	
# Student side autograding was added by Brad Miller, Nick Hay, and	
# Pieter Abbeel (pabbeel@cs.berkeley.edu).	
def uniformCostSearch(problem):	
    """Search the node of least total cost first."""	
    "*** YOUR CODE HERE ***"	
    #util.raiseNotDefined()	
    path =Path([problem.getStartState()],[],0)	
    if problem.isGoalState(problem.getStartState()):	
        return path.directions	
    	
    #创建优先队列	
    queue = util.PriorityQueue()	
    # push的第一个参数path是状态项Path,属性(位置、方向、成本)	
    #push的第二个参数0是优先级	
    #在heapq.heappush中将(优先级priority, 计数索引self.count, 状态项item)三元组	
    #根据优先级priority, 计数索引self.count的组合优先级	
    #即(优先级priority如一样,按计数索引判断优先级),将状态项item压入队列。	
    queue.push(path,0) 	
    visited =[problem.getStartState()]	
    	
    #和广度优先搜索的区别,仅在于queue.push的不同。	
    while not queue.isEmpty():	
        #如队列不为空,取最先进入队列的元素(List的最后一个元素),获取当前路径	
        currentPath = queue.pop()	
        currentLocation = currentPath.locations[-1]	
         #如果当前位置已经是终点的位置,则返回当前路径的方向列表,用于移动pac man。	
        if problem.isGoalState(currentLocation):	
            return currentPath.directions	
        else:	
            #在搜索问题中取得当前位置后继的下一个状态.getSuccessors中for循环遍历北、南、东、西四个方向,	
            #directionToVector取得方向到坐标偏移向量的转换值,在当前坐标上加上位移的坐标偏移量值,	
            #如果下一步坐标移动的点不是围墙,则在后续状态列表中加入三元组( nextState, action, cost)	
            nextSteps = problem.getSuccessors(currentLocation)	
            for nextStep in nextSteps:	
                #遍历下一步的状态,依次获得位置、方向、成本信息	
                nextLocation =nextStep[0]	
                nextDirection = nextStep[1]	
                nextCost = nextStep[2]	
                # 不在当前路径里面而且下一个位置还没被访问(多条路径交叉点)	
                if (nextLocation not in currentPath.locations) and (nextLocation not in visited):	
                    if not problem.isGoalState(nextLocation):	
                        visited.append(nextLocation)	
                        print("访问的位置:", visited)	
                    #获取当前路径列表集	
                    nextLocations =currentPath.locations[:]	
                    #将新的位置加入到当前路径的列表里面	
                    nextLocations.append(nextLocation)	
                    print("当前位置:",currentLocation)	
                    print("当前位置下一步可能的移动位置:",nextLocation)	
                    print("加到当前位置列表集:",nextLocations)	
                    #print()	
                    #print()	
                    #print(currentLocation,nextLocation,nextLocations)	
                    #获取当前的方向集	
                    nextDirections = currentPath.directions[:]	
                    #将新的方向加入到当前方向集的列表里面	
                    nextDirections.append(nextDirection)	
                    nextCosts = currentPath.cost +nextCost	
                    nextPath =Path(nextLocations,nextDirections,nextCosts)	
                    #下一步的状态,入优先级别的队列	
                    # push的第一个参数nextPath是状态项Path,属性(位置、方向、成本)	
                    #push的第二个参数nextCosts是优先级	
                    #在heapq.heappush中将(优先级priority, 计数索引self.count, 状态项item)三元组	
                    #根据优先级priority, 计数索引self.count的组合优先级	
                    #即(优先级priority如一样,按计数索引判断优先级),将状态项item压入队列。	
                    print("优先级:",nextCosts)	
                    print()	
                    print()	
                    queue.push(nextPath, nextCosts)	

	
    #队列为空,仍未到达终点,返回空集	
    return []	
  

虽然BFS会找到一条通向目标的最少行动路径,但我们可能希望找到其他意义上“最好”的路径。考虑一下mediumDottedMaze 迷宫和mediumScaryMaze迷宫。通过改变成本函数,我们可以鼓励Pacman找到不同的路径。例如,我们可以对在幽灵出入地区的危险步骤收取更高的费用,或者对食物丰富地区的步骤收取更少的费用,而一个理性的Pacman代理应该调整它的行为来做出反应。在search.py中的uniformCostSearch函数中实现了统一成本图搜索算法。可查看util.py,了解一些在实现中可能有用的数据结构。

        观察以下三种布局中的成功行为,其中下面的代理使用不同的成本函数(代理和成本函数已编写),StayEastSearchAgent的成本函数是costFn = lambda pos: .5 ** pos[0];StayWestSearchAgent的成本函数是costFn = lambda pos: 2 ** pos[0],StayEastSearchAgent and StayWestSearchAgen的路径成本应该分别非常低和非常高。

python pacman.py -l mediumMaze -p SearchAgent -a fn=ucs	
python pacman.py -l mediumDottedMaze -p StayEastSearchAgent	
python pacman.py -l mediumScaryMaze -p StayWestSearchAgent

运行结果分别如下:

E:\2019reforce_learning\cs188\proj1-search-python3>python pacman.py -l mediumMaze -p SearchAgent -a fn=ucs	
[SearchAgent] using function ucs	
[SearchAgent] using problem type PositionSearchProblem	
Path found with total cost of 68 in 0.3 seconds	
Search nodes expanded: 269	
Pacman emerges victorious! Score: 442	
Average Score: 442.0	
Scores:        442.0	
Win Rate:      1/1 (1.00)	
Record:        Win	

	
E:\2019reforce_learning\cs188\proj1-search-python3>python pacman.py -l mediumDottedMaze -p StayEastSearchAgent	
Path found with total cost of 1 in 0.2 seconds	
Search nodes expanded: 186	
Pacman emerges victorious! Score: 646	
Average Score: 646.0	
Scores:        646.0	
Win Rate:      1/1 (1.00)	
Record:        Win	

	
E:\2019reforce_learning\cs188\proj1-search-python3>python pacman.py -l mediumScaryMaze -p StayWestSearchAgent	
Path found with total cost of 68719479864 in 0.2 seconds	
Search nodes expanded: 108	
Pacman emerges victorious! Score: 418	
Average Score: 418.0	
Scores:        418.0	
Win Rate:      1/1 (1.00)	
Record:        Win

如使用mediumMaze 布局:

E:\2019reforce_learning\cs188\proj1-search-python3>python pacman.py -l mediumMaze -p SearchAgent -a fn=ucs	
[SearchAgent] using function ucs	
[SearchAgent] using problem type PositionSearchProblem	
Path found with total cost of 68 in 0.3 seconds	
Search nodes expanded: 269	
Pacman emerges victorious! Score: 442	
Average Score: 442.0	
Scores:        442.0	
Win Rate:      1/1 (1.00)	
Record:        Win	

	
E:\2019reforce_learning\cs188\proj1-search-python3>python pacman.py -l mediumMaze -p StayEastSearchAgent	
Path found with total cost of 1 in 0.2 seconds	
Search nodes expanded: 260	
Pacman emerges victorious! Score: 436	
Average Score: 436.0	
Scores:        436.0	
Win Rate:      1/1 (1.00)	
Record:        Win	

	
E:\2019reforce_learning\cs188\proj1-search-python3>python pacman.py -l mediumMaze -p StayWestSearchAgent	
Path found with total cost of 17183280440 in 0.2 seconds	
Search nodes expanded: 173	
Pacman emerges victorious! Score: 358	
Average Score: 358.0	
Scores:        358.0	
Win Rate:      1/1 (1.00)	
Record:        Win	

欢迎关注微信公众号:“从零起步学习人工智能”。


转载:https://blog.csdn.net/duan_zhihua/article/details/101442413
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场