如果 估价值>实际值, 搜索的点数少,搜索范围小,效率高,但不能保证得到最优解。
估价值与实际值越接近,估价函数取得就越好
例如对于几何路网来说,可以取两节点间欧几理德距离(直线距离)做为估价值,即f=g(n)+sqrt((dx-nx)*(dx-nx)+(dy-ny)*(dy-ny));这样估价函数f在g值一定的情况下,会或多或少的受估价值h的制约,节点距目标点近,h值小,f值相对就小,能保证最短路的搜索向终点的方向进行。明显优于Dijkstra算法的毫无无方向的向四周搜索。
算法伪代码:
主要搜索过程伪代码如下:
创建两个表,OPEN表保存所有已生成而未考察的节点(保存这个函数的f(n)值与g(n)值),CLOSED表中记录已访问过的节点(只是为了防止重复访问)。
算起点的估价值;//起始值假设为0
将起点放入OPEN表;//open表起始值为空,随着不断的进行子节点处理,表中值越来越多
while(OPEN!=NULL)
{
从OPEN表中取f(n)最小的节点n;//且这个节点不在closed表中
if(n节点==目标节点)
{
break;
}
for(当前节点n 的每个子节点X) //即图中与n节点连接的节点
{
算X的f(n)值;//即n点open值g(n)+n到x的距离+x的估计值
/*在处理X节点时,假设有m个与其连接的节点已经获取到从0节点到此节点的最短路径,则当前的N节点一定是其中的最短节点,因为N节点的选择依据就是路径最短。而对于与x连接,当前还未处理的节点,在之后处理到那个节点时,会进入X in OPEN语句中,如果这个节点比现在的N还短,那么会更新X值的信息。
疑问:如果节点B按照A节点的路径计算g(n),然后A节点被更新后,是否还需要更新B节点?
答:B按照A进行计算,则A一定是在CLOSED表中的已处理点(即A是B的父节点,子节点OPEN值的计算一定是在父节点的处理回合中进行,所以A一定已经进行了处理)。然而,疑问中提到的假设为A节点被更新,则在更新后A到起始节点的路径中的各个节点的f(n)都小于等于更新前N节点的f(n)(如果不是小于等于,那么也没必要更新了),由于这个路径是在A处理后得出的,那么在处理A之前,一定存在某个节点是在OPEN中,但却没有处理过(不在CLOSED表),如果是这样的话,在当初处理A的时候,这个节点小于A,A一定不会被选中。由此可知,疑问中的情况是不可能出现的。也就是说,A被处理后,A的值不会被更新。节点只有被当做子节点处理中才可能被更新。*/
if(X in OPEN)
{
if( X的f(n)小于OPEN表的f(n) )
{
把n设置为X的父亲;
更新OPEN表中的f(n); //取最小路径的估价值
}
}
if(X in CLOSE)
{
continue;
}
if(X not inboth)
{
把n设置为X的父亲;
求X的f(n);
并将X插入OPEN表中; //还没有排序
}
}//end for
将n节点插入CLOSE表中;
按照f(n)将OPEN表中的节点排序; //实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。
}//end while(OPEN!=NULL)
保存路径,即 从终点开始,每个节点沿着父节点移动直至起点,这就是你的路径;