A*算法:一种典型的人工智能启发式搜索算法,被广泛应用在最优路径求解和一些策略设计的问题中。
启发式搜索:与DFS和BFS这类盲目型搜索最大的不同,就在于当前搜索结点往下选择下一步结点时,可以通过一个启发函数来进行选择,选择代价最小(大)的结点作为下一步搜索结点,以求得问题的最小(大)值。
选择代价最小(大):STL库中的数据结构priority_queue。
估价函数:f(n)=g(n)+h(n) f(n)是结点n的估价函数值,g(n)是从初始结点到n结点的实际代价,h(n)是从n结点到目标结点最佳路径的估计代价,因为真正代价h*(n)显然目前无法求出,但对最小值问题,要求h(n)<=h*(n);对最大值问题,要求h(n)>=h*(n)。显然,g(n)是已知的,g(n)代表了搜索的广度优先趋势,而h(n)体现了搜索的启发信息。
g(n):一般取起始结点到当前结点的距离; h(n):一般取当前结点到目标结点的曼哈顿距离;
DFS和BFS:显然,A*算法与它们的联系就在于,当g(n)=0时,该算法类似于DFS;当h(n)=0时,该算法类似于BFS,没有一点启发信息,可以认为BFS是“最烂的”A*算法。
IDA*算法:这种算法被称为迭代加深A*算法,可以有效的解决A*空间增长带来的问题,基本不怎么花费内存,甚至可以不用到优先级队列。
时间复杂度:通常比较难以估算其复杂度,建议通过实际测试,边比较边学习,同时还应该统计搜索过程中的状态数,以便得到更清晰的结果。
实现:
创建两个表“开启列表”OPEN和“关闭列表”CLOSED;
void ASTAR()
{
CLOSE与OPEN初始化为空,将起始结点放入OPEN表;
while(OPEN!=NULL)
{
从OPEN表中取估价值f最小的结点CurrentNode;
将CurrentNode结点从OPEN表中删除;
if(CurrentNode结点==目标结点)
{
求得路径PATH;
break;
}
for(CurrentNode结点的每一个子结点NewNode)
{
if(NewNode不在OPEN表和CLOSED表中)
{
求NewNode的估价值f;
将NewNode插入OPEN表中;
}
else if(NewNode在OPEN表中)
{
if(NewNode的估价值f小于OPEN表中结点的估价值)
更新OPEN表中的估价值;//取最小路径的估价值
}
else //NewNode在CLOSED表中
{
if(NewNode的估价值f小于CLOSED表中结点的估价值)
{
更新CLOSED表中的估价值;
从CLOSED表中移出结点,并把NewNode放入OPEN表中;
}
}
将CurrentNode结点插入CLOSED表中;
按照估价值将OPEN表中的结点排序;
}//for
}//while
}