算法之A星算法(寻路)

1.启发式搜索:启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无谓的搜索路径,提高了效率。在启发式搜索中,对位置的估价是十分重要的。采用了不同的估价可以有不同的效果。

  启发算法有: 蚁群算法遗传算法模拟退火算法等。

2.估价算法:从当前节点移动到目标节点的预估损耗。

  预估算法有:曼哈顿(manhattan)等。

3.算法特点:理论上时间是最优的,但空间增长是指数型的。

4.java实现:上下左右移动

  1 package cn.liushaofeng.algorithm;
  2 
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 
  6 /**
  7  * A Star Algorithm
  8  * @author liushaofeng
  9  * @date 2015-8-24 下午11:05:48
 10  * @version 1.0.0
 11  */
 12 public class AstarAlgorithm
 13 {
 14     private List<Node> openList = null;
 15     private List<Node> closeList = null;
 16     private int[][] map;
 17 
 18     /**
 19      * default constructor
 20      * @param map data map
 21      */
 22     public AstarAlgorithm(int[][] map)
 23     {
 24         this.map = map;
 25         this.openList = new ArrayList<Node>();
 26         this.closeList = new ArrayList<Node>();
 27     }
 28 
 29     /**
 30      * find path
 31      * @param srcNode source node
 32      * @param desNode destination node
 33      * @return node path
 34      */
 35     public Node findPath(Node srcNode, Node desNode)
 36     {
 37         init(srcNode);
 38         do
 39         {
 40             if (openList.isEmpty())
 41             {
 42                 break;
 43             }
 44 
 45             Node node = openList.get(0);
 46             List<Node> aroundPoint = getAroundPoint(srcNode, node, desNode);
 47             openList.addAll(aroundPoint);
 48             closeList.add(node);
 49             openList.remove(node);
 50 
 51         } while (!findDes(desNode));
 52 
 53         return findNodePath(desNode);
 54     }
 55 
 56     private Node findNodePath(Node desNode)
 57     {
 58         for (Node node : openList)
 59         {
 60             if (node.getX() == desNode.getX() && node.getY() == desNode.getY())
 61             {
 62                 return node;
 63             }
 64         }
 65         return null;
 66     }
 67 
 68     private boolean findDes(Node desNode)
 69     {
 70         for (Node node : openList)
 71         {
 72             if (node.getX() == desNode.getX() && node.getY() == desNode.getY())
 73             {
 74                 return true;
 75             }
 76         }
 77         return false;
 78     }
 79 
 80     private void init(Node srcNode)
 81     {
 82         openList.add(srcNode);
 83     }
 84 
 85     // top bottom left and right, four points
 86     private List<Node> getAroundPoint(Node srcNode, Node nextNode, Node desNode)
 87     {
 88         int x = srcNode.getX();
 89         int y = srcNode.getY();
 90 
 91         int[] xData = new int[2];
 92         int[] yData = new int[2];
 93         if (x - 1 >= 0)
 94         {
 95             xData[0] = x - 1;
 96         }
 97         if (x + 1 < map.length)
 98         {
 99             xData[1] = x + 1;
100         }
101 
102         if (y - 1 >= 0)
103         {
104             yData[0] = y - 1;
105         }
106         if (y + 1 < map[0].length)
107         {
108             yData[1] = y + 1;
109         }
110 
111         List<Node> tmpList = new ArrayList<Node>();
112 
113         for (int i : xData)
114         {
115             Node node = new Node(i, y, srcNode);
116             if (!isObstacle(node) && !inClosetList(node))
117             {
118                 calcWeight(srcNode, node, desNode);
119                 tmpList.add(node);
120             }
121         }
122 
123         for (int i : yData)
124         {
125             Node node = new Node(x, i, srcNode);
126             if (!isObstacle(node) && !inClosetList(node))
127             {
128                 calcWeight(srcNode, node, desNode);
129                 tmpList.add(node);
130             }
131         }
132 
133         return tmpList;
134     }
135 
136     private void calcWeight(Node parentNode, Node node, Node desNode)
137     {
138         node.setG(parentNode.getG() + 10);
139         int h = Math.abs(node.getX() - desNode.getX()) + Math.abs(node.getY() - desNode.getY());
140         node.setWeight(node.getG() + h * 10);
141     }
142 
143     private boolean inClosetList(Node nextNode)
144     {
145         for (Node node : closeList)
146         {
147             if (node.getX() == nextNode.getX() && node.getY() == nextNode.getY())
148             {
149                 return true;
150             }
151         }
152         return false;
153     }
154 
155     private boolean isObstacle(Node nextNode)
156     {
157         return map[nextNode.getX()][nextNode.getY()] == 1;
158     }
159 
160     public static void main(String[] args)
161     {
162         int[][] map =
163         {
164         { 0, 0, 0, 0, 0, 0, 0 },
165         { 0, 0, 0, 0, 0, 0, 0 },
166         { 0, 0, 0, 1, 0, 0, 0 },
167         { 0, 0, 0, 1, 0, 0, 0 },
168         { 0, 0, 0, 1, 0, 0, 0 },
169         { 0, 0, 0, 0, 0, 0, 0 },
170         { 0, 0, 0, 0, 0, 0, 0 } };
171 
172         AstarAlgorithm astar = new AstarAlgorithm(map);
173         Node pathNode = astar.findPath(new Node(3, 1, null), new Node(3, 5, null));
174         System.out.println(pathNode == null ? "Can not find path!" : pathNode.toString());
175     }
176 }
查看代码

数据模型

  1 package cn.liushaofeng.algorithm;
  2 
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 
  6 /**
  7  * Node
  8  * @author liushaofeng
  9  * @date 2015-8-24 下午09:48:53
 10  * @version 1.0.0
 11  */
 12 public class Node
 13 {
 14     private Node parentNode;
 15     private int x;
 16     private int y;
 17 
 18     private int weight;
 19     private int g;
 20 
 21     /**
 22      * default constructor
 23      * @param x x point
 24      * @param y y point
 25      * @param parentNode parent node
 26      */
 27     public Node(int x, int y, Node parentNode)
 28     {
 29         this.x = x;
 30         this.y = y;
 31         this.parentNode = parentNode;
 32     }
 33 
 34     public int getG()
 35     {
 36         return g;
 37     }
 38 
 39     public void setG(int g)
 40     {
 41         this.g = g;
 42     }
 43 
 44     public Node getParentNode()
 45     {
 46         return parentNode;
 47     }
 48 
 49     public void setParentNode(Node parentNode)
 50     {
 51         this.parentNode = parentNode;
 52     }
 53 
 54     public int getX()
 55     {
 56         return x;
 57     }
 58 
 59     public void setX(int x)
 60     {
 61         this.x = x;
 62     }
 63 
 64     public int getY()
 65     {
 66         return y;
 67     }
 68 
 69     public void setY(int y)
 70     {
 71         this.y = y;
 72     }
 73 
 74     public int getWeight()
 75     {
 76         return weight;
 77     }
 78 
 79     public void setWeight(int weight)
 80     {
 81         this.weight = weight;
 82     }
 83 
 84     @Override
 85     public String toString()
 86     {
 87         return getPath();
 88     }
 89 
 90     private String getPath()
 91     {
 92         List<Node> dataList = new ArrayList<Node>();
 93         Node node = this;
 94         while (node != null)
 95         {
 96             dataList.add(node);
 97             node = node.getParentNode();
 98         }
 99 
100         StringBuffer sb = new StringBuffer();
101         for (int i = dataList.size() - 1; i >= 0; i--)
102         {
103             if (i == 0)
104             {
105                 sb.append("(" + dataList.get(i).getX() + "," + dataList.get(i).getY() + ")");
106             } else
107             {
108                 sb.append("(" + dataList.get(i).getX() + "," + dataList.get(i).getY() + ")->");
109             }
110         }
111         return sb.toString();
112     }
113 }
查看代码

 

 代码待调试。

posted @ 2015-08-26 00:35  liushaofeng.cn  阅读(1637)  评论(0编辑  收藏  举报