美文网首页
启发式寻路算法

启发式寻路算法

作者: wintersweett | 来源:发表于2020-03-31 18:14 被阅读0次

g:实际距离
h:预估距离
曼哈顿距离=g+h
地图上因为只需要知道哪条是最短路径,所以无需知道精确的具体数值来消耗性能
开放列表:白色有字的
关闭列表:黄色有字的
思路:
1、将起点加入openlist,这个开放列表是一个PriorityQueue
2、将所有可以的点(非边界,非障碍物,非在开放列表,也非在关闭列表)(在父节点向八个方向拓展得到的点),加入openlist,当while(!openlist.isEmpty()), 将openList.poll,拿出最小的放入closeList(即关闭列表)
3、找到终点end,while(end!=null){stack.push;end=end.parent}

代码:
public class Astar {
public final static int DIRECT_VALUE = 10;
public final static int OBLIQUE_VALUE = 14;
//开放列表 白格子
private Queue<Node> openList = new PriorityQueue<Node>();
//关闭列表 黄格子
private List<Node> closeList = new ArrayList<Node>();

/**
 * 计算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 Node findNodeInOpen(Coord coord) {
    if (coord == null || openList.isEmpty()) return null;
    for (Node node : openList) {
        if (node.coord.equals(coord)) {
            return node;
        }
    }
    return null;
}

/**
 * 判断是否在close中
 */
private boolean isCoordInClose(Coord coord) {
    return coord != null && isCoordInClose(coord.x, coord.y);
}

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;
}

/**
 * 判断一个位置是否可以选择
 */
private boolean canAddNodeToOpen(MapInfo mapInfo, int x, int y) {
    //是否在地图中
    if (x < 0 || x >= mapInfo.width || y < 0 || y >= mapInfo.hight) return false;
    //判断是否能过
    if (mapInfo.map[y][x] == MapUtils.WALL) return false;
    //判断是否已经被 选择过的
    if (isCoordInClose(x, y)) return false;
    return true;
}

/**
 * 算法开始
 */
public void start(MapInfo mapInfo) {
    if (mapInfo == null) return;
    //清空以前的所有的内容
    openList.clear();
    closeList.clear();
    //开始搜索
    openList.add(mapInfo.start);
    //开始向周围扩展
    moveNodes(mapInfo);
}

private void moveNodes(MapInfo mapInfo) {
    while (!openList.isEmpty()) {
        if (isCoordInClose(mapInfo.end.coord)) {//如果已经是终点了
            //统计结果
            calcPath(mapInfo.map, mapInfo.end);
        }
        //把open中最小的一个取出来 ,放到close中
        Node current = openList.poll();
        closeList.add(current);
        //开始扩展
        addNeighborNodeInOpen(mapInfo, current);
    }
}

private void calcPath(int[][] map, Node end) {
    MapUtils.path = new Path();
    if (end != null) {
        MapUtils.path.moveTo(end.coord.x * 80 + 40, end.coord.y * 80 + 40);
    }
    while (end != null) {//把结果入栈
        MapUtils.path.lineTo(end.coord.x * 80 + 40, end.coord.y * 80 + 40);
        MapUtils.result.push(end);
        end = end.parent;
    }
}

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);
}

/**
 * 核心移动功能
 */
private void addNeighborNodeInOpen(MapInfo mapInfo, Node current, int x, int y, int directValue) {
    if (canAddNodeToOpen(mapInfo, x, y)) {//是否可以通过
        Node end = mapInfo.end;//地图的终点
        Coord coord = new Coord(x, y);//需要填入的位置
        int g = current.g + directValue;
        Node child = findNodeInOpen(coord);
        if (child == null) {//如果能填入数字
            int h = calcH(end.coord, coord);
            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 {
            //如果已经填过的数据,不用理会
        }

    }
}

}

相关文章

  • 百度无人驾驶apollo项目路径规划a*算法分析

    算法分析 车辆路径规划寻路算法有很多,apollo路径规划模块使用的是启发式搜索算法A*寻路算法。 a*算法是一种...

  • JS算法和数据结构

    A-star寻路 寻路模式深度优先搜索广度优先搜索启发式搜索 -> A*算法估价函数 估价函数:f(n) = g(...

  • 启发式寻路算法

    利用曼哈顿距离=g+hg:实际值,即到起点的距离h:预估值,到终点的距离 这个启发式寻路算法逻辑:起点加入开放li...

  • 启发式寻路算法

    1.曼哈顿距离进行估算 g(n)=横竖距离,取10;斜方向取14;值越大,计算的越准确 h(n)=abs(x-x1...

  • 启发式寻路算法

    g:实际距离h:预估距离曼哈顿距离=g+h地图上因为只需要知道哪条是最短路径,所以无需知道精确的具体数值来消耗性能...

  • 博客园转载

    启发式算法(Heuristic Algorithm) 启发式算法(Heuristic Algorithm)有不同的...

  • A* 搜索算法

    启发式搜索算法 要理解 A* 搜寻算法,还得从启发式搜索算法开始谈起。所谓启发式搜索,就在于当前搜索结点往下选择下...

  • 启发式算法

    近期在回顾启发式算法的原理及代码。所谓的启发式算法,描述起来有点抽象。 启发式算法的定义:一个基于直观或经验构造的...

  • Unity学习笔记——A*寻路算法的应用

    初步了解了一些寻路算法后,本以为dijstra是比较合适的寻路算法,今天仔细看了关于A星寻路算法的教程和视频后,我...

  • (3.7学堂在线python学习笔记)

    @[TOC](3.7学堂在线python学习笔记) # 重要笔记 1. 启发式算法 启发式算法(heuristic...

网友评论

      本文标题:启发式寻路算法

      本文链接:https://www.haomeiwen.com/subject/zcfguhtx.html