增强版A*算法

本代码是读了《漫画算法》一书中的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-

输出
在这里插入图片描述

发布了80 篇原创文章 · 获赞 133 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/chekongfu/article/details/100532176