zoukankan      html  css  js  c++  java
  • A*算法

    来源参考 http://blog.csdn.net/crayondeng/article/details/12342989

    假设有人想从A点移动到一墙之隔的B点,如下图,绿色的是起点A,红色是终点B,蓝色方块是中间的墙。

    选择路径中经过哪个方格的关键是下面这个等式:

    F = G + H

    这里:
        * G = 从起点A,沿着产生的路径,移动到网格上指定方格的移动耗费。
        * H = 从网格上那个方格移动到终点B的预估移动耗费。这经常被称为启发式的

    参考java代码:

      1 package com.java;
      2 
      3 import java.util.ArrayList;
      4 import java.util.Collections;
      5 import java.util.Comparator;
      6 
      7 public class TestAStar {
      8 
      9     /**
     10      * A*方法总结
     11      * 
     12      * 好,现在你已经看完了整个说明,让我们把每一步的操作写在一起:
     13      * 
     14      * 1,把起始格添加到开启列表。 2,重复如下的工作: a) 寻找开启列表中F值最低的格子。我们称它为当前格。 b) 把它切换到关闭列表。 c)
     15      * 对相邻的8格中的每一个? 如果它不可通过或者已经在关闭列表中,略过它。反之如下。
     16      * 如果它不在开启列表中,把它添加进去。把当前格作为这一格的父节点。记录这一格的F,G,和H值。
     17      * 如果它已经在开启列表中,用G值为参考检查新的路径是否更好
     18      * 。更低的G值意味着更好的路径。如果是这样,就把这一格的父节点改成当前格,并且重新计算这一格的G和F值
     19      * 。如果你保持你的开启列表按F值排序,改变之后你可能需要重新对开启列表排序。
     20      * 
     21      * d) 停止,当你 把目标格添加进了关闭列表(注解),这时候路径被找到,或者 没有找到目标格,开启列表已经空了。这时候,路径不存在。
     22      * 3.保存路径。从目标格开始,沿着每一格的父节点移动直到回到起始格。这就是你的路径 F = G + H
     23      */
     24 
     25     /**
     26      * @param args
     27      */
     28     public static void main(String[] args) {
     29         TestAStar ts = new TestAStar();
     30         ts.initBarrierList();
     31         ts.startAstarroad(new PointHolder(1, 2), new PointHolder(5, 2));
     32 
     33     }
     34 
     35     int sp = 10;
     36     int spA = 14;
     37 
     38     int hang = 5;
     39     int lie = 7;
     40 
     41     ArrayList<PointHolder> barrierList = new ArrayList<PointHolder>();
     42 
     43     public void initBarrierList() {
     44         PointHolder ph = new PointHolder(3, 1);
     45         barrierList.add(ph);
     46         ph = new PointHolder(3, 2);
     47         barrierList.add(ph);
     48         ph = new PointHolder(3, 3);
     49         barrierList.add(ph);
     50     }
     51 
     52     ArrayList<PointHolder> openList = new ArrayList<PointHolder>();
     53     ArrayList<PointHolder> closeList = new ArrayList<PointHolder>();
     54 
     55     public void startAstarroad(PointHolder srcph, PointHolder desph) {
     56 
     57         // 当前点
     58         PointHolder curph = null;
     59         // 加入open
     60         openList.add(srcph);
     61 
     62         while (true) {
     63 
     64             if (openList.isEmpty()) {
     65                 System.out.println("not find the point");
     66                 return;
     67             }
     68 
     69             if (closeList.indexOf(desph) > 0) {
     70                 System.out.println("find");
     71                 int ch = closeList.indexOf(desph);
     72                 closeList.get(ch).printPath();
     73                 return;
     74             }
     75             // 排序
     76             Collections.sort(openList, new ComparatorPh(desph));
     77             // 找最小的当前点
     78             if (openList.size() > 0) {
     79                 curph = openList.get(0);
     80             }
     81             
     82             // 当前点加入close
     83             closeList.add(curph);
     84             openList.remove(0);
     85             // 打印
     86             curph.toStringPoint();
     87             // 找周围点
     88             ArrayList<PointHolder> shipphs = getCatShipPh(curph);
     89             for (PointHolder shipph : shipphs) {
     90                 shipph.prePoint = curph;
     91             }
     92             // 周围点在openlist中,比较最优H 加入open list
     93             for (PointHolder shipph : shipphs) {
     94                 int ch = openList.indexOf(shipph);
     95                 if (ch >= 0) {
     96                     int shipph_H = shipph.getH(desph);
     97                     int openph_H = openList.get(ch).getH(desph);
     98                     if (shipph_H < openph_H) {
     99                         openList.get(ch).prePoint = shipph.prePoint;
    100                     }
    101                 } else {
    102                     openList.add(shipph);
    103                 }
    104             }
    105 
    106         }
    107 
    108     }
    109 
    110     // 得到可到达的点的集合
    111     ArrayList<PointHolder> getCatShipPh(PointHolder ph) {
    112         ArrayList<PointHolder> mList = new ArrayList<TestAStar.PointHolder>();
    113         int x = ph.x;
    114         int y = ph.y;
    115         boolean uEnable = false;// 上是否可用
    116         boolean dEnable = false;
    117         boolean lEnable = false;
    118         boolean rEnable = false;
    119         //
    120         PointHolder ph1 = new PointHolder(x, y - 1);
    121         if (validatePointHolder(ph1)) {
    122             uEnable = true;
    123             if (!closeList.contains(ph1))
    124                 mList.add(ph1);
    125         }
    126         //
    127         ph1 = new PointHolder(x, y + 1);
    128         if (validatePointHolder(ph1)) {
    129             dEnable = true;
    130             if (!closeList.contains(ph1))
    131                 mList.add(ph1);
    132         }
    133         //
    134         ph1 = new PointHolder(x - 1, y);
    135         if (validatePointHolder(ph1)) {
    136             lEnable = true;
    137             if (!closeList.contains(ph1))
    138                 mList.add(ph1);
    139         }
    140         //
    141         ph1 = new PointHolder(x + 1, y);
    142         if (validatePointHolder(ph1)) {
    143             rEnable = true;
    144             if (!closeList.contains(ph1))
    145                 mList.add(ph1);
    146         }
    147         // 左上
    148         ph1 = new PointHolder(x - 1, y - 1);
    149         if (validatePointHolder(ph1) && uEnable && lEnable) {
    150             if (!closeList.contains(ph1))
    151                 mList.add(ph1);
    152         }
    153         // 右上
    154         ph1 = new PointHolder(x + 1, y - 1);
    155         if (validatePointHolder(ph1) && uEnable && rEnable) {
    156             if (!closeList.contains(ph1))
    157                 mList.add(ph1);
    158         }
    159         // 左下
    160         ph1 = new PointHolder(x - 1, y + 1);
    161         if (validatePointHolder(ph1) && lEnable && dEnable) {
    162             if (!closeList.contains(ph1))
    163                 mList.add(ph1);
    164         }
    165         // 右下
    166         ph1 = new PointHolder(x + 1, y + 1);
    167         if (validatePointHolder(ph1) && rEnable && dEnable) {
    168             if (!closeList.contains(ph1))
    169                 mList.add(ph1);
    170         }
    171         return mList;
    172     }
    173 
    174     /***
    175      * 校验 是否符合
    176      * 
    177      * @param ph
    178      * @return
    179      */
    180     boolean validatePointHolder(PointHolder ph) {
    181         if (ph == null)
    182             return false;
    183         // 是否范围内
    184         if (ph.x < 0 || ph.x >= 7 || ph.y < 0 || ph.y >= 5)
    185             return false;
    186         // 是否不可用
    187         if (barrierList.contains(ph))
    188             return false;
    189         return true;
    190     }
    191 
    192     public static class PointHolder {
    193 
    194         public PointHolder(int x, int y) {
    195             this.x = x;
    196             this.y = y;
    197         }
    198 
    199         public int x;
    200         public int y;
    201         // 前一个节点
    202         PointHolder prePoint;
    203         public int H;
    204 
    205         public int getH(PointHolder desPh) {
    206 
    207             return Math.abs(desPh.x - x) + Math.abs(desPh.y - y);
    208         }
    209 
    210         public int getG() {
    211             PointHolder ph = this;
    212             int g = 0;
    213             while (ph != null) {
    214                 g++;
    215                 ph = ph.prePoint;
    216             }
    217             return g;
    218         }
    219 
    220         @Override
    221         public boolean equals(Object obj) {
    222             PointHolder ph = (PointHolder) obj;
    223             if (ph.x == x && ph.y == y) {
    224                 return true;
    225             } else {
    226                 return false;
    227             }
    228         }
    229 
    230         public void toStringPoint() {
    231             System.out.println("P(" + x + "," + y + ")");
    232         }
    233 
    234         public void printPath() {
    235             ArrayList<PointHolder> mList = new ArrayList<TestAStar.PointHolder>();
    236             PointHolder ph = this;
    237             while (ph != null) {
    238                 mList.add(ph);
    239                 ph = ph.prePoint;
    240             }
    241 
    242             for (int i = 0; i < mList.size(); i++) {
    243                 mList.get(i).toStringPoint();
    244             }
    245 
    246         }
    247     }
    248 
    249     public class ComparatorPh implements Comparator<PointHolder> {
    250         PointHolder desPh;
    251 
    252         public ComparatorPh(PointHolder desPh) {
    253             this.desPh = desPh;
    254         }
    255 
    256         @Override
    257         public int compare(PointHolder o1, PointHolder o2) {
    258             int f1 = o1.getG() + o1.getH(desPh);
    259             int f2 = o2.getG() + o1.getH(desPh);
    260             return f1 - f2;
    261         }
    262 
    263     }
    264 
    265 }
  • 相关阅读:
    P1288 取数游戏II
    设置ip的bat
    oracle 服务器配置
    查看硬盘空间
    oracle 备份还原相关_转贴
    ssh 乱码
    inno setup regedit
    db locked ?
    用户控件和页面
    什么是接口?接口有哪些好处,抽象类(abstract)和接口(interface)的区别
  • 原文地址:https://www.cnblogs.com/wjw334/p/A-star.html
Copyright © 2011-2022 走看看