51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 2386|回复: 2
打印 上一主题 下一主题

A*算法实现

[复制链接]
  • TA的每日心情
    慵懒
    2015-1-8 08:46
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]测试小兵

    跳转到指定楼层
    1#
    发表于 2007-11-16 17:23:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    在游戏编程中广泛使用了A*算法。 就比如红警里面你框一辆坦克然后在目的地上点一下鼠标,不管多远坦克都会自动跑到目标点上(前提是目标点是可以到达的畅通路径)。在这个过程中坦克起始位置和终点位置中间的路径已经由程序计算完成。而这个程序的算法我们称之为最优路径算法。       是下面是最优算法A*原理的实现,当然只是原理算法的实现,只供学习和研究其效率一般,没有实现算法和数据结构的优化,负责的程序员应该进一步的优化它。 好了下面我们还是来看看如何实现吧。
    地图中每一块都有3个属性
    G = 移动代价。
    H = 实际代价,离到终点的实际距离。
    F = G+H
    A* 就是寻找具有最小F值能到达终点的路径。

    下面我们开始吧
    先定义地图数据 0是可走1是不可行走
      int[][] map = {
          {
          0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {
          0, 1, 1, 1, 1, 0, 0, 1, 0, 0}, {
          0, 1, 0, 0, 1, 0, 0, 0, 0, 0}, {
          0, 1, 0, 0, 1, 1, 1, 1, 1, 0}, {
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      };

    需要维护两个列表一个是开放列表还有一个封闭列表
    Vector open = new Vector();       // 开放列表
      Vector close = new Vector();      // 封闭列表

    定义节点类
      class Node {
        int x;
        int y;
        int g;     // G = 移动代价,沿着到父块而生成路径移动的代价。
        int h;     // H = 从格子中给定 的方块到最终目标 B点的评估移动代价。         
        int f;     //  估价
        Node father;
        Node(Node node, int sx, int sy, int ex, int ey) {
          if (node != null) {  // 新建子节点
            father = node;    // 设置父节点
            x = sx;            // 当前x
            y = sy;           // 当前y
            h = (getABS(sx - ex) + getABS(sy - ey))*10; // 实际代价 当前块移动到终点块的绝对距离。
            g = node.g + 10;                                         // 代价推算 当前块移动代价=父块移动代价+移动代价
            f = g + h;                                                   // 估价
          }
          else {                 // 根节点
            x = sx;
            y = sy;
            h = 0;
            g = 0;
            f = 9999;
          }
        }
      }

    private int getABS(int v) {
        if (v < 0) {
          return -v;
        }
        return v;
      }

      // 开始寻路
      public void xunLu(int sx, int sy, int ex, int ey) {
        boolean flag = true;  // 是否存在于open list中
        int minIndex = 0;     // 具有最小F值对象的的open list下标
        int newX = 0;
        int newY = 0;
        /**
         * 1 添加开始方块到开放列表。
         *   初始化根接点,把根节点放入开放列表.
         */
        Node minNode = new Node(null, sx, sy, ex, ey);
        open.add(minNode);
        while (open.size() != 0) {
          /**
           *  2 查找开放列表中具有最小F值的方块。
           */
          minNode = ((Node)open.get(0));
          minIndex = 0;
          for (int i = 1; i < open.size(); i++) {
             if (minNode.f > ( (Node) open.get(i)).f) {
                minNode = ( (Node) open.get(i));
                minIndex = i;
             }
          }
          /**
           * 3 把最小F值的方块从开放列表中取出然后放入封闭列表。
           */
          if (minNode != null) {
              close.add(minNode);
              open.remove(minIndex);
          }
            /**
             *  4 如果目前找到的最小F值块是终点就返回。
             */
            if (minNode.x == ex && minNode.y == ey) {
              do {
                minNode = minNode.father;
              }
              while (get != null);
              return;
            }
            /**
             *  5 对最小F值块(即上面刚刚放入封闭列表里面) 的8个相邻方块的进行判断.
             *    将4或8个方向,可以走的放入开放列表内.
             */
            for (int i = 0; i < 4; i++) {
              flag = true;
              newX = minNode.x + t[0];
              newY = minNode.y + t[1];
              /**
               *5。1 地图是否越界 如果它不可行走,或者存在于封闭列表,忽略它。
               */
              if(newY < 0 || newY > 4 || newX < 0 || newX > 9) {
                continue;
              }
              if (map[newY][newX] == 0) {    // 判断是否是可以移动
                for (int k = 0; k < close.size(); k++) {  
                  if ( (((Node) close.get(k)).x == newX) &&
                       (((Node) close.get(k)).y == newY) ) {
                    flag = false;
                    break;
                  }
                }
                if(flag) {
                  for(int ii = 0; ii < open.size(); ii++) {  
                    if( ((Node)open.get(ii)).x == newX &&  ((Node)open.get(ii)).y == newY) {
                      open.remove(ii);
                      break;
                    }
                  }
                  open.add(new Node(minNode, newX,newY, ex, ey));
                }
              }
            }
          }
        }
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

  • TA的每日心情

    2019-12-27 13:32
  • 签到天数: 15 天

    连续签到: 1 天

    [LV.4]测试营长

    2#
    发表于 2011-6-8 14:15:30 | 只看该作者
    以前的帖子顶上去
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    3#
    发表于 2011-6-8 15:10:30 | 只看该作者
    路过学习,留下脚印~~
    回复 支持 反对

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-24 21:06 , Processed in 0.069998 second(s), 27 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表