A算法描述及JAVA实现

抱着学习的态度,偶先复习了一下以前学数据结构的时候用栈+遍历的方法实现了一个迷宫寻路问题,然后用A*算法来做同样的事~~简单起见,只用了一个比较简单的迷宫~反正思路是一样的嘛~~

A*算法的思想请看蓝色月光的贴子:
http://www.blueidea.com/tech/multimedia/2005/3121_3.asp

A*算法搜索过程中设置两个表:OPEN和CLOSED。

    OPEN表保存了所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。

   算法中有一步是根据估价函数重排OPEN表。这样循环中的每一步只考虑OPEN表中状态最好的节点。

A*算法伪码描述如下:


Astar_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

上面的伪码可以说是一个模板了~呵呵~~偶用JAVA实现的A*算法也大概就是用这个模板做的~~ FLASH AS也差不多吧~~


下面是JAVA源码:

//一个很简单的迷宫问题算法
import java.util.*;

class Node{
    
    boolean attainability; //节点是否可达到
    int x,y; //节点的位置信息
    int direction = 1;
    int score;
    String id = " ";
    //Node leftNode,rightNode,upNode,downNode;    
    //Node fatherNode;    
}

public class Puzzle {    
    Node[][] maze = null; //迷宫数组
    Node startNode,endNode; //起始点,结束点
    
    public Puzzle(){
        //初始化迷宫数组~并指定起始点和结束点
        maze = new Node[7][9];
        
        for(int i=0;i<7;i++)
            for(int j=0;j<9;j++){
                maze[i][j] = new Node();
                
                maze[i][j].attainability = true;
                maze[i][j].x = i;
                maze[i][j].y = j;
        }
        startNode = maze[3][2];
        startNode.id = "&";
        endNode = maze[3][6];
        endNode.id = "@";
        for(int i=0;i<7;i++){
            maze[i][0].attainability = false;
            maze[i][8].attainability = false;
        }
        for(int j=0;j<9;j++){
            maze[0][j].attainability = false;
            maze[6][j].attainability = false;
        }
        maze[4][3].attainability = false;
        maze[2][4].attainability = false;
        maze[3][4].attainability = false;
        maze[4][4].attainability = false;
    }
    
    private void printMaze(){
        
        for(int i=0;i<7;i++){
            for(int j=0;j<9;j++){
                
                if(maze[i][j].attainability)
                    if(maze[i][j] == startNode)
                        System.out.print("& ");
                    else if(maze[i][j] == endNode)
                        System.out.print("@ ");
                    else System.out.print(maze[i][j].id + " ");
                
                else
                    if(i==0 || i==6 || j==0 ||j==8 || (i==4&&j==3) ||(i==2&&j==4) ||(i==3&&j==4) ||(i==4&&j==4))
                        System.out.print("# ");
                    else System.out.print(maze[i][j].id + " ");
            }
            System.out.println();
        }
    }
    
    public void getPath(){
        Stack s = new Stack();
        Node curpos = startNode;
        //int curstep = 1;
        do{
            if(curpos.attainability){
                curpos.attainability = false;
                if(curpos!=startNode && curpos!=endNode)
                    curpos.id = "%";
                s.push(curpos);
                if(curpos == endNode) printMaze();
                Node tmp = nextPos(curpos,1);
                curpos = maze[tmp.x][tmp.y];
            //    curpos.id++;
            //    curstep++;
            }
            else{
                Node e = (Node)s.pop();
                while(e.direction == 4 && !s.empty()){
                    e.attainability = false;
                    e = (Node)s.pop();
                }
                if(e.direction < 4){
                    e.direction++;
                    s.push(e);
                    Node tmp = nextPos(e,e.direction);                    
                    curpos = maze[tmp.x][tmp.y];
                }
            }
        }while(!s.empty());
    }
    
    private Node nextPos(Node pos, int i){
        //按东南西北的顺序
        Node tmp = new Node();
        tmp.direction = pos.direction;
        tmp.attainability = pos.attainability;
        int x = pos.x;
        int y = pos.y;
        if(i == 2 && x<maze.length-1){     //南
            x = x+1;                        
            tmp.y = pos.y;
            tmp.x = x;            
        }
        else if(i == 4 && x != 0){     //北
            x = x-1;
            tmp.y = pos.y;
            tmp.x = x;
        }
        else if(i == 1 && y<maze[0].length-1){    //东
            y = y+1;
            tmp.x = pos.x;
            tmp.y = y;
        }
        else if(i == 3 && y != 0){    //西
            y = y - 1;
            tmp.x = pos.x;
            tmp.y = y;
        }
        return tmp;
    }
    
    public void Astar(){
        getScore();
        
        Stack open = new Stack(); //初始开启列表
        open.push(startNode);
        
        Stack close = new Stack(); //初始关闭列表
        while(open.size()!=0){
            Node x = (Node)open.pop();
            if(x == endNode)
                break;
            Node[] t = null;
            if(x.attainability){
                t = getNear(x);
            
                for(int i=0;i<t.length;i++){
                    if(t[i] != null){
                        if(open.search(t[i]) == -1 && close.search(t[i]) == -1)
                            open.push(t[i]);
                        else if(open.search(t[i]) != -1){
                            sort(open);
                        }
                        else{
                            if(t[i].score < ((Node)close.peek()).score){
                                sort(close);
                                open.push(close.pop());
                            }
                        }                    
                    }
                }
                close.push(x);
                sort(open);
            }
        }
        int a = close.size();
        for(int i=0;i<a;i++){
            Node tmp = (Node)close.pop();
            tmp.id = "%";
            maze[tmp.x][tmp.y] = tmp;
        }
        printMaze();
    }
    
    
    private void sort(Stack s) {
        // 对一个栈里的元素按score排序,值最少的放在最上面。
        Node[] t = new Node[s.size()];
        Node tmp = null;
        int x = s.size();
        for(int i=0;i<x;i++){
            t[i] = (Node)s.pop();
        }
        for(int i=0;i<t.length-1;i++)
            for(int j=i+1;j<t.length;j++){
                if(t[i].score < t[j].score){
                    tmp = t[i];
                    t[i] = t[j];
                    t[j] = tmp;
                }
            }
        for(int i=0;i<t.length;i++)
            s.push(t[i]);
    }

    private void getScore(){
        for(int i=0;i<maze.length;i++)
            for(int j=0;j<maze[i].length;j++){
                maze[i][j].score = Math.abs(endNode.x - maze[i][j].x) + Math.abs(endNode.y - maze[i][j].y);
            }
    }
    private Node[] getNear(Node e){
        
        Node leftNode = (e.y!=0 ? maze[e.x][e.y-1] : null);
        Node rightNode = (e.y!=maze[0].length-1 ? maze[e.x][e.y+1] : null);
        Node upNode = (e.x!=0 ? maze[e.x-1][e.y] : null);
        Node downNode = (e.x!=maze.length-1 ? maze[e.x+1][e.y] : null);
        Node[] t =  {leftNode,rightNode,upNode,downNode};
        
        return t;
    }
    
    public static void main(String[] args){
        Puzzle p = new Puzzle();
        System.out.println("初始的迷宫如下:(其中&代表起点,@代表终点,#代表障碍)");
        p.printMaze();    //输出初始化的迷宫
        System.out.println();
        System.out.println("简单的一条寻路路径如下:(按东南西北的顺序遍历寻路)");
        p.getPath();        //输出搜寻从起始点到结束点的路径
        
        p = new Puzzle();
        System.out.println();
        System.out.println("用A*算法寻路路径如下:");
        p.Astar();
        
        
    }
}

运行


 

来源: http://bbs.blueidea.com/forum-2-1.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值