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 }

 

 

 

posted on 2014-02-24 17:15  wjw334  阅读(336)  评论(0编辑  收藏  举报

导航