-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4b0bbdf
commit 93d89f6
Showing
8 changed files
with
373 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<classpath> | ||
<classpathentry kind="src" path="src"/> | ||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> | ||
<classpathentry kind="output" path="bin"/> | ||
</classpath> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/bin/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<projectDescription> | ||
<name>A星算法</name> | ||
<comment></comment> | ||
<projects> | ||
</projects> | ||
<buildSpec> | ||
<buildCommand> | ||
<name>org.eclipse.jdt.core.javabuilder</name> | ||
<arguments> | ||
</arguments> | ||
</buildCommand> | ||
</buildSpec> | ||
<natures> | ||
<nature>org.eclipse.jdt.core.javanature</nature> | ||
</natures> | ||
</projectDescription> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
eclipse.preferences.version=1 | ||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 | ||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | ||
org.eclipse.jdt.core.compiler.compliance=1.7 | ||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate | ||
org.eclipse.jdt.core.compiler.debug.localVariable=generate | ||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate | ||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | ||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||
org.eclipse.jdt.core.compiler.source=1.7 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# astar | ||
A星算法Java实现 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,254 @@ | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.PriorityQueue; | ||
import java.util.Queue; | ||
|
||
/** | ||
* | ||
* ClassName: AStar | ||
* @Description: A星算法 | ||
* @author kesar | ||
*/ | ||
public class AStar | ||
{ | ||
public final static int BAR = 1; // 障碍值 | ||
public final static int PATH = 2; // 路径 | ||
public final static int DIRECT_VALUE = 10; // 横竖移动代价 | ||
public final static int OBLIQUE_VALUE = 14; // 斜移动代价 | ||
|
||
/** | ||
* 包含地图所需的所有输入数据 | ||
*/ | ||
static class MapInfo | ||
{ | ||
int[][] maps; // 二维数组的地图 | ||
int width; // 地图的宽 | ||
int hight; // 地图的高 | ||
Node start; // 起始结点 | ||
Node end; // 最终结点 | ||
|
||
public MapInfo(int[][] maps, int width, int hight, Node start, Node end) | ||
{ | ||
this.maps = maps; | ||
this.width = width; | ||
this.hight = hight; | ||
this.start = start; | ||
this.end = end; | ||
} | ||
} | ||
|
||
Queue<Node> openList = new PriorityQueue<Node>(); // 优先队列(升序) | ||
List<Node> closeList = new ArrayList<Node>(); | ||
|
||
public static void main(String[] args) | ||
{ | ||
int[][] maps = { | ||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
{ 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 8, 8, 8, 0, 0 }, | ||
{ 0, 0, 0, 8, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0 }, | ||
{ 0, 0, 0, 8, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0 }, | ||
{ 0, 0, 0, 8, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0 }, | ||
{ 0, 0, 0, 8, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0 } | ||
}; | ||
MapInfo info=new MapInfo(maps,maps[0].length, maps.length,new Node(1, 5), new Node(10, 5)); | ||
new AStar().start(info); | ||
printMap(maps); | ||
} | ||
|
||
/** | ||
* 打印地图 | ||
*/ | ||
public static void printMap(int[][] maps) | ||
{ | ||
for (int i = 0; i < maps.length; i++) | ||
{ | ||
for (int j = 0; j < maps[i].length; j++) | ||
{ | ||
System.out.print(maps[i][j] + " "); | ||
} | ||
System.out.println(); | ||
} | ||
} | ||
|
||
/** | ||
* 开始算法 | ||
*/ | ||
public void start(MapInfo mapInfo) | ||
{ | ||
if(mapInfo==null) return; | ||
// clean | ||
openList.clear(); | ||
closeList.clear(); | ||
// 开始搜索 | ||
openList.add(mapInfo.start); | ||
moveNodes(mapInfo); | ||
} | ||
|
||
/** | ||
* 移动当前结点 | ||
*/ | ||
private void moveNodes(MapInfo mapInfo) | ||
{ | ||
while (!openList.isEmpty()) | ||
{ | ||
if (isCoordInClose(mapInfo.end.coord)) | ||
{ | ||
drawPath(mapInfo.maps, mapInfo.end); | ||
break; | ||
} | ||
Node current = openList.poll(); | ||
closeList.add(current); | ||
addNeighborNodeInOpen(mapInfo,current); | ||
} | ||
} | ||
|
||
/** | ||
* 在二维数组中绘制路径 | ||
*/ | ||
private void drawPath(int[][] maps, Node end) | ||
{ | ||
if(end==null||maps==null) return; | ||
System.out.println("总代价:" + end.G); | ||
while (end != null) | ||
{ | ||
Coord c = end.coord; | ||
maps[c.y][c.x] = PATH; | ||
end = end.parent; | ||
} | ||
} | ||
|
||
/** | ||
* 添加所有邻结点到open表 | ||
*/ | ||
private void addNeighborNodeInOpen(MapInfo mapInfo,Node current) | ||
{ | ||
int x = current.coord.x; | ||
int y = current.coord.y; | ||
// 左 | ||
addNeighborNodeInOpen(mapInfo,current, x - 1, y, DIRECT_VALUE); | ||
// 上 | ||
addNeighborNodeInOpen(mapInfo,current, x, y - 1, DIRECT_VALUE); | ||
// 右 | ||
addNeighborNodeInOpen(mapInfo,current, x + 1, y, DIRECT_VALUE); | ||
// 下 | ||
addNeighborNodeInOpen(mapInfo,current, x, y + 1, DIRECT_VALUE); | ||
// 左上 | ||
addNeighborNodeInOpen(mapInfo,current, x - 1, y - 1, OBLIQUE_VALUE); | ||
// 右上 | ||
addNeighborNodeInOpen(mapInfo,current, x + 1, y - 1, OBLIQUE_VALUE); | ||
// 右下 | ||
addNeighborNodeInOpen(mapInfo,current, x + 1, y + 1, OBLIQUE_VALUE); | ||
// 左下 | ||
addNeighborNodeInOpen(mapInfo,current, x - 1, y + 1, OBLIQUE_VALUE); | ||
} | ||
|
||
/** | ||
* 添加一个邻结点到open表 | ||
*/ | ||
private void addNeighborNodeInOpen(MapInfo mapInfo,Node current, int x, int y, int value) | ||
{ | ||
if (canAddNodeToOpen(mapInfo,x, y)) | ||
{ | ||
Node end=mapInfo.end; | ||
Coord coord = new Coord(x, y); | ||
int G = current.G + value; // 计算邻结点的G值 | ||
Node child = findNodeInOpen(coord); | ||
if (child == null) | ||
{ | ||
int H=calcH(end.coord,coord); // 计算H值 | ||
if(isEndNode(end.coord,coord)) | ||
{ | ||
child=end; | ||
child.parent=current; | ||
child.G=G; | ||
child.H=H; | ||
} | ||
else | ||
{ | ||
child = new Node(coord, current, G, H); | ||
} | ||
openList.add(child); | ||
} | ||
else if (child.G > G) | ||
{ | ||
child.G = G; | ||
child.parent = current; | ||
openList.add(child); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* 从Open列表中查找结点 | ||
*/ | ||
private Node findNodeInOpen(Coord coord) | ||
{ | ||
if (coord == null || openList.isEmpty()) return null; | ||
for (Node node : openList) | ||
{ | ||
if (node.coord.equals(coord)) | ||
{ | ||
return node; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
|
||
/** | ||
* 计算H的估值:“曼哈顿”法,坐标分别取差值相加 | ||
*/ | ||
private int calcH(Coord end,Coord coord) | ||
{ | ||
return Math.abs(end.x - coord.x) | ||
+ Math.abs(end.y - coord.y); | ||
} | ||
|
||
/** | ||
* 判断结点是否是最终结点 | ||
*/ | ||
private boolean isEndNode(Coord end,Coord coord) | ||
{ | ||
return coord != null && end.equals(coord); | ||
} | ||
|
||
/** | ||
* 判断结点能否放入Open列表 | ||
*/ | ||
private boolean canAddNodeToOpen(MapInfo mapInfo,int x, int y) | ||
{ | ||
// 是否在地图中 | ||
if (x < 0 || x >= mapInfo.width || y < 0 || y >= mapInfo.hight) return false; | ||
// 判断是否是不可通过的结点 | ||
if (mapInfo.maps[y][x] == BAR) return false; | ||
// 判断结点是否存在close表 | ||
if (isCoordInClose(x, y)) return false; | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* 判断坐标是否在close表中 | ||
*/ | ||
private boolean isCoordInClose(Coord coord) | ||
{ | ||
return coord!=null&&isCoordInClose(coord.x, coord.y); | ||
} | ||
|
||
/** | ||
* 判断坐标是否在close表中 | ||
*/ | ||
private boolean isCoordInClose(int x, int y) | ||
{ | ||
if (closeList.isEmpty()) return false; | ||
for (Node node : closeList) | ||
{ | ||
if (node.coord.x == x && node.coord.y == y) | ||
{ | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* | ||
* ClassName: Coord | ||
* | ||
* @Description: 坐标 | ||
* @author kesar | ||
*/ | ||
public class Coord | ||
{ | ||
|
||
public int x; | ||
public int y; | ||
|
||
public Coord(int x, int y) | ||
{ | ||
this.x = x; | ||
this.y = y; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) | ||
{ | ||
if (obj == null) return false; | ||
if (obj instanceof Coord) | ||
{ | ||
Coord c = (Coord) obj; | ||
return x == c.x && y == c.y; | ||
} | ||
return false; | ||
} | ||
|
||
@Override | ||
public String toString() | ||
{ | ||
return "Coord [x=" + x + ", y=" + y + "]"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* | ||
* ClassName: Node | ||
* | ||
* @Description: 路径结点 | ||
* @author kesar | ||
*/ | ||
public class Node implements Comparable<Node> | ||
{ | ||
|
||
public Coord coord; // 坐标 | ||
public Node parent; // 父结点 | ||
public int G; // G:是个准确的值,是起点到当前结点的代价 | ||
public int H; // H:是个估值,当前结点到目的结点的估计代价 | ||
|
||
public Node(int x, int y) | ||
{ | ||
this.coord = new Coord(x, y); | ||
} | ||
|
||
public Node(Coord coord, Node parent, int g, int h) | ||
{ | ||
this.coord = coord; | ||
this.parent = parent; | ||
G = g; | ||
H = h; | ||
} | ||
|
||
@Override | ||
public int compareTo(Node o) | ||
{ | ||
if (o == null) return -1; | ||
if (G + H > o.G + o.H) | ||
return 1; | ||
else if (G + H < o.G + o.H) return -1; | ||
return 0; | ||
} | ||
|
||
@Override | ||
public String toString() | ||
{ | ||
return "Node [coord=" + coord + "]"; | ||
} | ||
|
||
} |