基于A的planner*
import random
import heapq
import logging
from search import searchspace
from planning_task import Task
from heuristics import BlindHeuristic
def a_star(task, heuristic=BlindHeuristic):
"""
Searches for a plan in the given task using A* search.
@param task The task to be solved
@param heuristic A heuristic callable which computes the estimated steps
from a search node to reach the goal.
"""
# get the initial info and then store the current states
current_state = task.initial_state
# a data structure storing the heuristic values on the same level
heap = []
# a list store the node chosen
Node_list = []
# build up a root node
node = searchspace.make_root_node(current_state)
Node_list.append(node)
heuristic_value_node = {} # a dic, map from heuristic_value to (nodes)
# if the goal state have not been achieved
while not task.goal_reached(current_state):
successors = task.get_successor_states(current_state) # get the successors of current_state
if not successors: # if there is no successors, then this search is failed.
return False
# go through all the successors and choose the best as the next state
for successor in successors:
# build up a child node
node = searchspace.make_child_node(Node_list[len(Node_list) - 1], successor[0], successor[1])
# calculate the f(n)
f_value = heuristic(node) + node.g
if f_value not in heap:
heapq.heappush(heap, f_value) # push one heuristic_value into heap
if f_value in heuristic_value_node:
# push the node into the nodes set in the dic
heuristic_value_node[f_value].add(node)
else:
heuristic_value_node[f_value] = set() # create a set in dic
heuristic_value_node[f_value].add(node) # push the node into the nodes set in the dic
# choose this node as the next node
best_node = heuristic_value_node[heap[0]].pop()
# then choose it as the next state
best_state = best_node.state
# if the heuristic_value has no corresponding node then delete it
if heuristic_value_node[heap[0]] == set():
del heuristic_value_node[heapq.heappop(heap)]
# choose the final current_best_state as the next state
current_state = best_state
# push the final current_best_node chosen into node_list
Node_list.append(best_node)
return Node_list.pop().extract_solution() # return the solution
首先,把state转化为node,以树为数据结构,方便找到goal之后的回溯和记录cost。
其次,判断是否为goal,是则跳到下一步;不是则得出所有的子节点,计算其f(n)。全局对比寻找最小f(n)的点(全局最优解),循环这一步。
最后,返回整个Node_list。
评价:该implement没有实现对goal_less情况的应对方式。没有对重复的state处理。goal_test应该针对frontiers(所有子节点),而不是选中的node。
基于Greedy Search的planner
import heapq
import logging
from search import searchspace
from planning_task import Task
from heuristics import BlindHeuristic
def gbfs(task, heuristic=BlindHeuristic):
"""
Searches for a plan in the given task using Greedy Best First Search search.
@param task The task to be solved
@param heuristic A heuristic callable which computes the estimated steps
from a search node to reach the goal.
"""
# a list of current best states, get the initial info and then store the current states
current_state_list = [task.initial_state]
# a data structure storing the heuristic values on the same level
heap = []
# build up a root node
node = searchspace.make_root_node(task.initial_state)
# store the best node option at present
best_node =[node]
while True:
# the best_node as the father node for the current level nodes
father_node_list = best_node
best_state = [] # store the best state option at present
best_node = [] # store the best node option at present
for state_index in range(0, len(current_state_list)):
# get the successors of current_state
successors = task.get_successor_states(current_state_list[state_index])
same_level_Node_list = [] # a list, store the node formed on the some level
heuristic_value_list = [] # a list, store all the heuristic value
if not successors: # if there is no successors, then this search is failed.
return False
# go through all the successors and choose the best as the next state
for successor in successors:
# build up a child node
node = searchspace.make_child_node(father_node_list[state_index], successor[0], successor[1])
same_level_Node_list.append(node)
# calculate the f(n)
f_value = heuristic(node)
# push one heuristic_value into heap
heapq.heappush(heap, f_value)
# push current f(n) into the list
heuristic_value_list.append(f_value)
# go through all the heuristic values
for index in range(0, len(heuristic_value_list)):
# if its' heuristic value is the smallest in all heuristic values
if heuristic_value_list[index] == heap[0]:
best_state.append(successors[index][1]) # then choose it as the next state .
best_node.append(same_level_Node_list[index]) # choose this node as the next node
# refresh the heap list for the next iteration.
heap = []
# choose the final current_best_state as the next state
current_state_list = best_state
# check whether there is a state satisfying the goal state
for current_state in current_state_list:
# this state does not satisfy the goal state
if not task.goal_reached(current_state):
continue
else:
for index in range(0, len(current_state_list)):
# get the final node, which satisfies the goal
if task.goal_reached(current_state_list[index]):
last_node = best_node[index]
# return the solution
return last_node.extract_solution()
首先,把state转化为node,以树为数据结构,方便找到goal之后的回溯和记录cost。
其次,对该点进行goal测试,是则进行下一步,不是则得出所有的子节点,计算其f(n)(与A*的计算方式不同)。同层对比寻找最小f(n)的点(局部最优解),循环这一步。
最后,返回整个Node_list。
注意:当局部的点有相同的f(n)时,应同时拓展这些点直到有高低之分为止
评价:该implement没有实现对goal_less情况的应对方式。没有对重复的state处理。goal_test应该针对frontiers(所有子节点),而不是选中的node