这是被神化的算法。。。。用得到的地方不多f'(n) = g'(n) + h'(n)算法的伪程序如下:Best_First_Search(){ Open = [起始节点]; Closed = []; while (Open表非空) { 从Open中取得一个节点X,并从OPEN表中删除。 if (X是目标节点) { 求得路径PATH; 返回路径PATH; } for (每一个X的子节点Y) { if (Y不在OPEN表和CLOSE表中) { 求Y的估价值; 并将Y插入OPEN表中; } //还没有排序 else if (Y在OPEN表中) { if (Y的估价值小于OPEN表的估价值) 更新OPEN表中的估价值; } else //Y在CLOSE表中 { if (Y的估价值小于CLOSE表的估价值) { 更新CLOSE表中的估价值; 从CLOSE表中移出节点,并放入OPEN表中; } } 将X节点插入CLOSE表中; 按照估价值将OPEN表中的节点排序; }//end for }//end while}//end func 先看搜索主函数:void AstarPathfinder::FindPath(int sx, int sy, int dx, int dy){ NODE *Node, *BestNode; int TileNumDest; //得到目标位置,作判断用 TileNumDest = TileNum(sx, sy); //生成Open和Closed表 OPEN = ( NODE* )calloc(1,sizeof( NODE )); CLOSED=( NODE* )calloc(1,sizeof( NODE )); //生成起始节点,并放入Open表中 Node=( NODE* )calloc(1,sizeof( NODE )); Node->g = 0; //这是计算h值 // should really use sqrt(). Node->h = (dx-sx)*(dx-sx) + (dy-sy)*(dy-sy); //这是计算f值,即估价值 Node->f = Node->g+Node->h; Node->NodeNum = TileNum(dx, dy); Node->x = dx; Node->y = dy; // make Open List point to first node OPEN->NextNode=Node; for (;;) { //从Open表中取得一个估价值最好的节点 BestNode=ReturnBestNode(); //如果该节点是目标节点就退出 // if we've found the end, break and finish break; if (BestNode->NodeNum == TileNumDest) //否则生成子节点 GenerateSuccessors(BestNode,sx,sy); } PATH = BestNode;} 再看看生成子节点函数:void AstarPathfinder::GenerateSuccessors(NODE *BestNode, int dx, int dy){ int x, y; //哦!依次生成八个方向的子节点,简单! // Upper-Left if ( FreeTile(x=BestNode->x-TILESIZE, y=BestNode->y-TILESIZE) ) GenerateSucc(BestNode,x,y,dx,dy); // Upper if ( FreeTile(x=BestNode->x, y=BestNode->y-TILESIZE) ) GenerateSucc(BestNode,x,y,dx,dy); // Upper-Right if ( FreeTile(x=BestNode->x+TILESIZE, y=BestNode->y-TILESIZE) ) GenerateSucc(BestNode,x,y,dx,dy); // Right if ( FreeTile(x=BestNode->x+TILESIZE, y=BestNode->y) ) GenerateSucc(BestNode,x,y,dx,dy); // Lower-Right if ( FreeTile(x=BestNode->x+TILESIZE, y=BestNode->y+TILESIZE) ) GenerateSucc(BestNode,x,y,dx,dy); // Lower if ( FreeTile(x=BestNode->x, y=BestNode->y+TILESIZE) ) GenerateSucc(BestNode,x,y,dx,dy); // Lower-Left if ( FreeTile(x=BestNode->x-TILESIZE, y=BestNode->y+TILESIZE) ) GenerateSucc(BestNode,x,y,dx,dy); // Left if ( FreeTile(x=BestNode->x-TILESIZE, y=BestNode->y) ) GenerateSucc(BestNode,x,y,dx,dy);} 看看最重要的函数:void AstarPathfinder::GenerateSucc(NODE *BestNode,int x, int y, int dx, int dy){ int g, TileNumS, c = 0; NODE *Old, *Successor; //计算子节点的 g 值 // g(Successor)=g(BestNode)+cost of getting from BestNode to Successor g = BestNode->g+1; // identification purposes TileNumS = TileNum(x,y); //子节点再Open表中吗? // if equal to NULL then not in OPEN list, else it returns the Node in Old if ( (Old=CheckOPEN(TileNumS)) != NULL ) { //若在 for( c = 0; c < 8; c++) // Add Old to the list of BestNode's Children (or Successors). if( BestNode->Child[c] == NULL ) break; BestNode->Child[c] = Old; //比较Open表中的估价值和当前的估价值(只要比较g值就可以了) // if our new g value is < Old's then reset Old's parent to point to BestNode if ( g < Old->g ) { //当前的估价值小就更新Open表中的估价值 Old->Parent = BestNode; Old->g = g; Old->f = g + Old->h; } } else //在Closed表中吗? // if equal to NULL then not in OPEN list, else it returns the Node in Old if ( (Old=CheckCLOSED(TileNumS)) != NULL ) { //若在 for( c = 0; c< 8; c++) // Add Old to the list of BestNode's Children (or Successors). if ( BestNode->Child[c] == NULL ) break; BestNode->Child[c] = Old; //比较Closed表中的估价值和当前的估价值(只要比较g值就可以了) // if our new g value is < Old's then reset Old's parent to point to BestNode if ( g < Old->g ) { //当前的估价值小就更新Closed表中的估价值 Old->Parent = BestNode; Old->g = g; Old->f = g + Old->h; //再依次更新Old的所有子节点的估价值 // Since we changed the g value of Old, we need // to propagate this new value downwards, i.e. // do a Depth-First traversal of the tree! PropagateDown(Old); } } //不在Open表中也不在Close表中 else { //生成新的节点 Successor = ( NODE* )calloc(1,sizeof( NODE )); Successor->Parent = BestNode; Successor->g = g; // should do sqrt(), but since we don't really Successor->h = (x-dx)*(x-dx) + (y-dy)*(y-dy); // care about the distance but just which branch looks Successor->f = g+Successor->h; // better this should suffice. Anyayz it's faster. Successor->x = x; Successor->y = y; Successor->NodeNum = TileNumS; //再插入Open表中,同时排序。 // Insert Successor on OPEN list wrt f Insert(Successor); for( c =0; c < 8; c++) // Add Old to the list of BestNode's Children (or Successors). if ( BestNode->Child[c] == NULL ) break; BestNode->Child[c] = Successor; }}