美文网首页
算法学习:启发式搜索

算法学习:启发式搜索

作者: alex很累 | 来源:发表于2023-11-13 16:01 被阅读0次

    理论

    概念

    启发式搜索(Heuristically Search)又称为有信息搜索(Informed Search),它是利用问题拥有的启发信息来引导搜索,达到减少搜索范围、降低问题复杂度的目的,这种利用启发信息的搜索过程称为启发式搜索。

    估价函数

    启发式函数: h(n),它用来评价哪些结点最有希望的是一个我们要找的结点,h(n) 会返回一个非负实数,也可以认为是从结点n的目标结点路径的估计成本。
    注意:估价函数的选取十分重要,会直接影响到算法的效率。

    代码模板

    有点类似于bfs,但这里使用的是优先队列,估价函数即优先级。

    def AstarSearch(graph, start, end): 
        pq = collections.priority_queue() # 优先级 —> 估价函数
        pq.append([start]) 
        visited.add(start) 
        while pq: 
            node = pq.pop() # can we add more intelligence here ? 
            visited.add(node) 
            process(node) 
            nodes = generate_related_nodes(node) 
            unvisited = [node for node in nodes if node not in visited] 
            pq.push(unvisited)
    

    算法实践

    1091. 二进制矩阵中的最短路径

    问题描述

    给你一个 n x n 的二进制矩阵 grid 中,返回矩阵中最短 畅通路径 的长度。如果不存在这样的路径,返回 -1

    二进制矩阵中的 畅通路径 是一条从 左上角 单元格(即,(0, 0))到 右下角 单元格(即,(n - 1, n - 1))的路径,该路径同时满足下述要求:

    • 路径途经的所有单元格的值都是 0
    • 路径中所有相邻的单元格应当在 8 个方向之一 上连通(即,相邻两单元之间彼此不同且共享一条边或者一个角)。
      畅通路径的长度 是该路径途经的单元格总数。
    示例
    解题思路

    先准备好8个方向的变化变量,然后从(0,0)开始进行类bfs搜索,使用优先队列,估价函数为:到当前位置花费的成本 + x/y坐标和上一个位置差的绝对值的最大值。

    代码示例
    class Solution {
        int len = 0;
        int[][] directions = new int[][]{{-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}};
    
        public int shortestPathBinaryMatrix(int[][] grid) {
            len = grid.length;
            if (grid[0][0] == 1 || grid[len - 1][len - 1] == 1) {
                return -1;
            }
            if (len == 1) {
                return 1;
            }
    
            Queue<Node> queue = new PriorityQueue<>(10, Comparator.comparingInt(Node::cost));
            queue.offer(new Node(0, 0, 1));
            grid[0][0] = 1;
            while (!queue.isEmpty()) {
                Node current = queue.poll();
                for (int i = 0; i < directions.length; i++) {
                    int x = current.x + directions[i][0];
                    int y = current.y + directions[i][1];
                    if (x == len - 1 && y == len - 1) {
                        return current.step + 1;
                    }
                    if (x < 0 || x >= len || y < 0 || y >= len) {
                        continue;
                    }
                    if (grid[x][y] == 0 || grid[x][y] > grid[current.x][current.y] + 1) {
                        grid[x][y] = current.step + 1;
                        Node newNode = new Node(x, y, grid[x][y]);
                        queue.add(newNode);
                    }
                }
            }
            return -1;
        }
    
        class Node {
            public int x;
            public int y;
            public int step;
    
            public Node() {
            }
    
            public Node(int x, int y, int step) {
                this.x = x;
                this.y = y;
                this.step = step;
            }
    
            public int cost() {
                return step + Math.max(Math.abs(len - x - 1), Math.abs(len - y - 1));
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:算法学习:启发式搜索

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