该项目聚焦于在吃豆人游戏场景中实现搜索算法,以帮助吃豆人智能体寻找路径和收集食物。需要完成的作业主要是在search.py
文件中实现深度优先搜索(DFS)、一致代价搜索(UCS)、A*算法这三种搜索算法,以及在searchAgents.py
文件中为CornersProblem
实现一个非平凡一致性启发函数。
- 深度优先搜索(DFS)
- 在
search.py
文件中,深度优先搜索需要使用util.Stack
数据结构来实现。从起始状态开始,将其压入栈中,并标记为已访问。然后不断从栈中弹出状态,检查是否为目标状态。若是,则返回到达该状态的动作序列;若不是,则获取该状态的后继状态,将未访问过的后继状态及其动作序列压入栈中,并标记为已访问,持续这个过程直到找到目标状态或栈为空。
def depthFirstSearch(problem):stack = util.Stack()visited = set()stack.push((problem.getStartState(), []))visited.add(problem.getStartState())while not stack.isEmpty():state, actions = stack.pop()if problem.isGoalState(state):return actionssuccessors = problem.getSuccessors(state)for successor, action, _ in successors:if successor not in visited:stack.push((successor, actions + [action]))visited.add(successor)
- 在
- 一致代价搜索(UCS):在
search.py
的uniformCostSearch
函数中,利用util.PriorityQueue
来实现一致代价搜索。将起始状态及其代价(初始为0)放入优先队列,同时记录已访问状态。每次从队列中取出代价最小的状态,若为目标状态则返回路径;否则,获取其后继状态,计算新的代价并将未访问的后继状态及其新代价和路径加入队列,直到找到目标状态。def uniformCostSearch(problem):priority_queue = util.PriorityQueue()priority_queue.push((problem.getStartState(), []), 0)visited = set()while not priority_queue.isEmpty():state, actions = priority_queue.pop()if problem.isGoalState(state):return actionsif state in visited:continuevisited.add(state)successors = problem.getSuccessors(state)for successor, action, cost in successors:new_actions = actions + [action]new_cost = problem.getCostOfActions(new_actions)priority_queue.push((successor, new_actions), new_cost)
- A*算法:在
search.py
的aStarSearch
函数里,A*算法同样使用util.PriorityQueue
,结合启发式函数来进行搜索。将起始状态及其总代价(初始为启发式函数值)放入队列,记录已访问状态。每次取出总代价最小的状态,若为目标状态则返回路径;否则,获取后继状态,计算新的总代价(路径代价与启发式函数值之和)并将未访问的后继状态及其新总代价和路径加入队列,直至找到目标状态。def aStarSearch(problem, heuristic=nullHeuristic):priority_queue = util.PriorityQueue()priority_queue.push((problem.getStartState(), []), heuristic(problem.getStartState(), problem))visited = set()while not priority_queue.isEmpty():state, actions = priority_queue.pop()if problem.isGoalState(state):return actionsif state in visited:continuevisited.add(state)successors = problem.getSuccessors(state)for successor, action, cost in successors:new_actions = actions + [action]new_cost = problem.getCostOfActions(new_actions) + heuristic(successor, problem)priority_queue.push((successor, new_actions), new_cost)
- 启发函数设计:在
searchAgents.py
中为CornersProblem
实现启发函数时,要考虑当前状态与目标角落的距离以及已访问角落的情况。利用曼哈顿距离计算当前位置到未访问角落的距离之和,作为启发函数值。同时,确保函数满足非平凡、非负且一致的条件。def cornersHeuristic(state, problem):corners = problem.cornerswalls = problem.wallsnode = state[0]visited_corners = state[1]h_sum = 0for corner in corners:if corner not in visited_corners:h_sum += util.manhattanDistance(node, corner)return h_sum
完成上述代码实现后,可以按照题目中的测试指令,使用pacman.py
和autograder.py
对代码进行测试和验证,确保算法的正确性和有效性。