• A搜索算法简介


    概念

    A搜索算法(A Search Algorithm)是一种启发式搜索算法,用于在图形或网络中找到最短路径。它结合了广度优先搜索和贪婪算法的特点,通过评估每个节点的代价函数来决定下一步的移动。A搜索算法用于寻找最短路径问题,例如在地图上找到两个地点之间的最短路径,或在游戏中找到角色移动的最佳路径。

    算法特点

    • 使用启发函数(估计函数)来评估每个节点的代价,以确定下一步的移动方向。
    • 综合考虑了节点的实际代价和预估代价,以找到最优解。
    • 使用开放列表和关闭列表来追踪搜索过程中的节点,避免重复扩展相同的节点。
    • 可以根据具体问题选择不同的启发函数,以调整算法的性能和效果。

    优点

    • 能够找到最优解(如果启发函数是准确的)。
    • 可以在较短的时间内找到较好的解决方案。
    • 可以应用于不同类型的问题,如路径规划、游戏AI等。

    缺点

    • 启发函数的选择会影响算法的性能和结果。
    • 在某些情况下,可能会陷入局部最优解而无法找到全局最优解。
    • 对于复杂的问题,算法的时间和空间复杂度可能较高。

    适用场景

    • 地图路径规划问题,如导航系统。
    • 游戏中的角色移动路径规划。
    • 人工智能领域的搜索问题。

    实现代码

    1. import java.util.*;
    2. class Node {
    3. int x, y; // 节点的坐标
    4. int f, g, h; // f = g + h
    5. Node parent; // 父节点
    6. public Node(int x, int y) {
    7. this.x = x;
    8. this.y = y;
    9. }
    10. }
    11. public class AStarSearch {
    12. private int[][] map; // 地图
    13. private int startX, startY; // 起始点坐标
    14. private int endX, endY; // 终点坐标
    15. private PriorityQueue openList; // 开放列表
    16. private Set closedSet; // 封闭列表
    17. public AStarSearch(int[][] map, int startX, int startY, int endX, int endY) {
    18. this.map = map;
    19. this.startX = startX;
    20. this.startY = startY;
    21. this.endX = endX;
    22. this.endY = endY;
    23. openList = new PriorityQueue<>(Comparator.comparingInt(node -> node.f));
    24. closedSet = new HashSet<>();
    25. }
    26. public List findPath() {
    27. Node startNode = new Node(startX, startY);
    28. startNode.g = 0;
    29. startNode.h = calculateH(startX, startY);
    30. startNode.f = startNode.g + startNode.h;
    31. openList.offer(startNode);
    32. while (!openList.isEmpty()) {
    33. Node currentNode = openList.poll();
    34. closedSet.add(currentNode);
    35. if (currentNode.x == endX && currentNode.y == endY) {
    36. return getPath(currentNode);
    37. }
    38. List neighbors = getNeighbors(currentNode);
    39. for (Node neighbor : neighbors) {
    40. if (closedSet.contains(neighbor)) {
    41. continue;
    42. }
    43. int g = currentNode.g + 1; // 相邻节点的移动代价为1
    44. if (!openList.contains(neighbor) || g < neighbor.g) {
    45. neighbor.g = g;
    46. neighbor.h = calculateH(neighbor.x, neighbor.y);
    47. neighbor.f = neighbor.g + neighbor.h;
    48. neighbor.parent = currentNode;
    49. if (!openList.contains(neighbor)) {
    50. openList.offer(neighbor);
    51. }
    52. }
    53. }
    54. }
    55. return null; // 未找到路径
    56. }
    57. private int calculateH(int x, int y) {
    58. // 使用距离绝对值作为启发函数
    59. return Math.abs(x - endX) + Math.abs(y - endY);
    60. }
    61. private List getNeighbors(Node node) {
    62. int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    63. List neighbors = new ArrayList<>();
    64. for (int[] direction : directions) {
    65. int newX = node.x + direction[0];
    66. int newY = node.y + direction[1];
    67. if (newX >= 0 && newX < map.length && newY >= 0 && newY < map[0].length && map[newX][newY] == 0) {
    68. neighbors.add(new Node(newX, newY));
    69. }
    70. }
    71. return neighbors;
    72. }
    73. private List getPath(Node endNode) {
    74. List path = new ArrayList<>();
    75. Node currentNode = endNode;
    76. while (currentNode != null) {
    77. path.add(0, currentNode);
    78. currentNode = currentNode.parent;
    79. }
    80. return path;
    81. }
    82. public static void main(String[] args) {
    83. int[][] map = {
    84. {0, 0, 0, 0, 0},
    85. {1, 1, 0, 1, 1},
    86. {0, 0, 0, 0, 0},
    87. {0, 1, 1, 1, 0},
    88. {0, 0, 0, 0, 0}
    89. };
    90. int startX = 0;
    91. int startY = 0;
    92. int endX = 4;
    93. int endY = 4;
    94. AStarSearch astar = new AStarSearch(map, startX, startY, endX, endY);
    95. List path = astar.findPath();
    96. if (path != null) {
    97. for (Node node : path) {
    98. System.out.println("(" + node.x + ", " + node.y + ")");
    99. }
    100. } else {
    101. System.out.println("未找到路径");
    102. }
    103. }
    104. }

  • 相关阅读:
    (九)通过逻辑处理器串联请求/遍历list结果/foreach控制器
    处理服务器返回的utc 时间转正标准时间
    ucosii初认识==ucosii
    远程连接centos 7 图形化桌面
    JuiceFS 在多云架构中加速大模型推理
    VPS与云主机指南:了解五个主要区别
    亚马逊云科技加速大语言模型的创新应用
    vite项目运行后只显示主机地址
    通过汇编实现在屏幕中间输入字符,enter结束,退格键删除字符
    MySQL 流程控制 的详细讲解
  • 原文地址:https://blog.csdn.net/aidscooler/article/details/133610315