算法學(xué)習(xí):啟發(fā)式搜索

理論

概念

啟發(fā)式搜索(Heuristically Search)又稱為有信息搜索(Informed Search),它是利用問題擁有的啟發(fā)信息來引導(dǎo)搜索,達(dá)到減少搜索范圍、降低問題復(fù)雜度的目的,這種利用啟發(fā)信息的搜索過程稱為啟發(fā)式搜索。

估價(jià)函數(shù)

啟發(fā)式函數(shù): h(n),它用來評價(jià)哪些結(jié)點(diǎn)最有希望的是一個(gè)我們要找的結(jié)點(diǎn),h(n) 會(huì)返回一個(gè)非負(fù)實(shí)數(shù),也可以認(rèn)為是從結(jié)點(diǎn)n的目標(biāo)結(jié)點(diǎn)路徑的估計(jì)成本。
注意:估價(jià)函數(shù)的選取十分重要,會(huì)直接影響到算法的效率。

代碼模板

有點(diǎn)類似于bfs,但這里使用的是優(yōu)先隊(duì)列,估價(jià)函數(shù)即優(yōu)先級。

def AstarSearch(graph, start, end): 
    pq = collections.priority_queue() # 優(yōu)先級 —> 估價(jià)函數(shù)
    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)

算法實(shí)踐

1091. 二進(jìn)制矩陣中的最短路徑

問題描述

給你一個(gè) n x n 的二進(jìn)制矩陣 grid 中,返回矩陣中最短 暢通路徑 的長度。如果不存在這樣的路徑,返回 -1 。

二進(jìn)制矩陣中的 暢通路徑 是一條從 左上角 單元格(即,(0, 0))到 右下角 單元格(即,(n - 1, n - 1))的路徑,該路徑同時(shí)滿足下述要求:

  • 路徑途經(jīng)的所有單元格的值都是 0 。
  • 路徑中所有相鄰的單元格應(yīng)當(dāng)在 8 個(gè)方向之一 上連通(即,相鄰兩單元之間彼此不同且共享一條邊或者一個(gè)角)。
    暢通路徑的長度 是該路徑途經(jīng)的單元格總數(shù)。
示例
解題思路

先準(zhǔn)備好8個(gè)方向的變化變量,然后從(0,0)開始進(jìn)行類bfs搜索,使用優(yōu)先隊(duì)列,估價(jià)函數(shù)為:到當(dāng)前位置花費(fèi)的成本 + x/y坐標(biāo)和上一個(gè)位置差的絕對值的最大值。

代碼示例
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));
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容