package algorithm.bsf.maze; import java.util.ArrayList; import algorithm.bsf.maze.logger.ConsoleLogger; import algorithm.bsf.maze.logger.IMapLogger; import algorithm.bsf.maze.logger.IMapLogger.MoveType; /** * 维基百科定义:<br> * 广度优先搜索算法(Breadth-First-Search),又译作宽度优先搜索,或横 * 向优先搜索,简称BFS,是一种图形搜索演算法。简单的说,BFS是从根节点开 * 始,沿着树的宽度遍历树的节点,如果发现目标,则算法中止。广度优先搜索 * 的实现一般采用open-closed表。<p> * * @author Fan Hongtao * @created 2009-3-15 */ public class BreadthFirstSearch { private IMapLogger logger = null; public BreadthFirstSearch(IMapLogger logger) { super(); this.logger = logger; } /** * 寻找出路(最短路径) * @param map 表示地图的数组(要求地图的最外一圈都是围墙) * @param start 开始结点 * @param stop 终止结点 * @return 找到的路径。如果找不到路径,则返回 null */ public ArrayList<Node> searchPath(int[][] map, final Node start, final Node stop) { logger.logMap(map); ArrayList<Node> list = new ArrayList<Node>(); Node curr = start.clone(); list.add(curr); Node next = curr; map[next.getX()][next.getY()] = 2; while (!next.equals(stop)) { if (list.isEmpty()) { return null; // 找不到路径 } curr = list.remove(0); // 永远取第一个结点进行判断 for (int i = 0; i < Node.PATH_NUM; i++) { next = curr.move(i); if (map[next.getX()][next.getY()] != PathState.EMPTY) { continue; } map[next.getX()][next.getY()] = map[curr.getX()][curr.getY()] + 1; logger.logMove(curr, next, MoveType.SEARCH); if (next.equals(stop)) { break; } list.add(next); } } logger.logMap(map); // 已经找到出口, 从终点反向找回起点 ArrayList<Node> path = new ArrayList<Node>(); path.add(0, stop); Node pre = curr; for (int i = map[curr.getX()][curr.getY()]; i > 2; i--) { path.add(0, curr); for (int j = 0; j < Node.PATH_NUM; j++) { pre = curr.move(j); if (map[pre.getX()][pre.getY()] == i - 1) { break; } } curr = pre; } path.add(0, start); return path; } /** * @param args */ public static void main(String[] args) { // String fileName = (args.length > 0) ? args[0] : "maze.txt"; String fileName = (args.length > 0) ? args[0] : null; Env.setInputFileName(fileName); IMapLogger logger = new ConsoleLogger(); BreadthFirstSearch search = new BreadthFirstSearch(logger); Map map = new Map(); map.initMap(); ArrayList<Node> path = search.searchPath(map.getMap(), map.start, map.stop); logger.logPath(path); } }