本代码是读了《漫画算法》一书中的A*算法之后稍微做了一点改进,不同点在于原来的算法只能在地图内找最小路径,改进后的算法除了在地图内找最小路径,还可以通过穿透找最小路径,比如当路径来到最左边的时候,可以从最右边出来,当到达最下边的时候,可以从最上边出来,最后给了一个演示的例子,看图很容易懂。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class AStar {
private static ArrayList<Grid> openList = new ArrayList<Grid>();
private static ArrayList<Grid> closeList = new ArrayList<Grid>();
private static int n;
private static char[][] map = null;
public static Grid aStarSearch(Grid start, Grid end) {
ArrayList<Grid> closeList = new ArrayList<Grid>();
openList.add(start);
while (openList.size() > 0) {
Grid currentGrid = findMinGird();
openList.remove(currentGrid);
closeList.add(currentGrid);
List<Grid> neighbors = findNeighbors(currentGrid);
for (Grid grid : neighbors) {
grid.initGrid(currentGrid, end);
openList.add(grid);
}
for (Grid grid : openList){
if ((grid.x == end.x) && (grid.y == end.y)) {
return grid;
}
}
}
return null;
}
private static Grid findMinGird() {
Grid tempGrid = openList.get(0);
for (Grid grid : openList) {
if (grid.f < tempGrid.f) {
tempGrid = grid;
}
}
return tempGrid;
}
private static ArrayList<Grid> findNeighbors(Grid grid ) {
int max = map.length-1;
ArrayList<Grid> neighborList = new ArrayList<Grid>();
int[][] directions = {{-1,0},{0,1},{1,0},{0,-1}};
for(int[] direction:directions) {
int neighborX = grid.x+direction[0];if(neighborX<0) {neighborX=max;}else if(neighborX>max) {neighborX=0;}
int neighborY = grid.y+direction[1];if(neighborY<0) {neighborY=max;}else if(neighborY>max) {neighborY=0;};
if(isValidGrid(neighborX,neighborY)){
neighborList.add(new Grid(neighborX, neighborY));
}
}
return neighborList;
}
private static boolean isValidGrid(int x, int y) {
if(map[x][y] == '#'){//障碍物
return false;
}
if(containGrid(openList, x, y)){
return false;
}
if(containGrid(closeList, x, y)){
return false;
}
return true;
}
private static boolean containGrid(List<Grid> grids, int x, int y) {
for (Grid n : grids) {
if ((n.x == x) && (n.y == y)) {
return true;
}
}
return false;
}
static class Grid {
public int x;
public int y;
public int f;
public int g;
public int h;
public Grid parent;
public Grid(int x, int y) {
this.x = x;
this.y = y;
}
public void initGrid(Grid parent, Grid end){
this.parent = parent;
if(parent != null){
this.g = parent.g + 1;
}else {
this.g = 1;
}
int xL = Math.abs(this.x - end.x) ;
int yL = Math.abs(this.y - end.y);
int h1 = xL + yL; int h2 = n-xL+yL;int h3 = n-yL + xL;
this.h = Math.max(Math.max(h1, h2) , h3);
this.f = this.g + this.h;
}
}
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
n = sc.nextInt();
map = new char[n][n];
int startX = 0, startY=0, endX=0, endY=0;
for(int i=0; i<n; i++) {
String input = sc.next();
char[] chars = input.toCharArray();
for(int j=0; j<n; j++) {
map[i][j] = chars[j];
if('S' == chars[j]){ startX = i; startY = j; } else if( 'E' == chars[j] ) { endX = i; endY = j; }
}
}
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
System.out.print(map[i][j]+"\t");
}
System.out.println();
}
System.out.println();
Grid startGrid = new Grid(startX, startY);
Grid endGrid = new Grid(endX, endY);
Grid resultGrid = aStarSearch(startGrid, endGrid);
ArrayList<Grid> path = new ArrayList<Grid>();
while (resultGrid != null) {
path.add(new Grid(resultGrid.x, resultGrid.y));
resultGrid = resultGrid.parent;
}
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[0].length; j++) {
if (containGrid(path, i, j)&&map[i][j]=='-') {
System.out.print("*\t");
} else {
System.out.print(map[i][j] + "\t");
}
}
System.out.println();
}
}
}
输入
10
----------
----------
---#------
-S-#------
---#-E----
---#------
----------
----------
----------
----------
10
----------
----------
---#------
-S-#------
---#------
---#------
----------
----------
----------
--------E-
输出