先分析一下来自网上的一段代码:
在此算法中,g(n)表示从起点到任意顶点n的实际距离,h(n)表示任意顶点n到目标顶点的估算距离。 因此,A*算法的公式为:f(n)=g(n)+h(n)。 这个公式遵循以下特性:
- 如果h(n)为0,只需求出g(n),即求出起点到任意顶点n的最短路径,则转化为单源最短路径问题,即Dijkstra算法
- 如果h(n)<=“n到目标的实际距离”,则一定可以求出最优解。而且h(n)越小,需要计算的节点越多,算法效率越低。
function A*(start,goal)
closedset := the empty set //已经被估算的节点集合,首先设置为空
openset := set containing the initial node //将要被估算的节点集合
g_score[start] := 0 //g(n) 这里表示start点到start点的距离.
h_score[start] := heuristic_estimate_of_distance(start, goal) //h(n): 估计start点到目标点的距离
f_score[start] := h_score[start]
while openset is not empty
x := the node in openset having the lowest f_score[] value //取出具有估计函数最小值的那个函数
if x = goal //[如果取到目标点,直接返回]
return reconstruct_path(came_from,goal)
remove x from openset //相当于弹出要取的点
add x to closedset //加入到已取点集中.
foreach y in neighbor_nodes(x) //foreach=for each //处理每个邻居点.
if y in closedset //如果已经在已取点集中,直接接着走
continue
tentative_g_score := g_score[x] + dist_between(x,y) //临时更新起点到y点的距离
if y not in openset //有两种情况要放到估算的点的集合里面去:1 没有在估算点集里面
add y to openset
tentative_is_better := true
else if tentative_g_score < g_score[y] //新值比旧值要小
tentative_is_better := true
else
tentative_is_better := false
if tentative_is_better = true //如果要加入到估算点集中去
came_from[y] := x //设置前结点
g_score[y] := tentative_g_score //更新起点到y点的实际值
h_score[y] := heuristic_estimate_of_distance(y, goal) //估计y到目标点的估计值
f_score[y] := g_score[y] + h_score[y] //更新f评估计函数值。
return failure
function reconstruct_path(came_from,current_node)
if came_from[current_node] is set
p = reconstruct_path(came_from,came_from[current_node])
return (p + current_node)
else
return current_node
经过理解上面的注意,应该对A*算法有了解了,还是做几个题吧。
http://acm.hdu.edu.cn/showproblem.php?pid=1043
http://acm.uva.es/p/v6/652.html
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=217
http://acm.pku.edu.cn/JudgeOnline/problem?id=1077
ELJudge 8 puzzle
ELJudge 15 puzzle