搜索算法(Search)

1. 概述:
搜索算法是利用計算機的性能優勢來有目的的枚舉一個問題解空間的部分或所有的可能情況,從而求出問題的解的一種方法。在問題求解過程中,人們所面臨的大多數現實問題往往沒有確定性的算法,需要通過搜索算法來解決。
搜索問題一般只需要考慮兩個基本問題:
1、使用合適的狀態空間來表示問題。
2、測試該狀態空間中目標狀態是否會出現

一個問題的基本信息由4部分組成
1、初始狀態集合—–>定義了問題的初始狀態
2、操作符集合—–>把一個問題從一個狀態轉換到另一個狀態的動作集合
3、目標檢測函數—->用來確定一個狀態是不是目標
4、路徑費用函數—->對每條路徑賦予一定費用的函數
其中,初始狀態集合和操作符集合定義了問題的搜索空間

搜索算法的兩個重要問題
搜索什麼和在哪裏搜索
因此搜索可以被分爲兩個階段:狀態空間的生成階段和在該狀態空間中對所求問題的狀態的搜索
搜索可以分爲啓發式搜索和盲目搜索

2. 盲目搜索:
一般是指從當前狀態到目標狀態需要走多少步或者每條路徑的花費並不知道,按照預定的搜索策略進行搜索,終止於目標狀態,由於這種狀態沒有考慮到問題本身的特性,具有很大的盲目性,效率不高。需要提高盲目搜索的效率就需要尋找合理的搜索策略,該邊搜索順序
常用的盲目搜索有:深度優先搜搜(DFS)、廣度優先搜索(BFS)

1、深度優先搜索DFS
深度優先搜索沿着樹的深度遍歷樹的節點,儘可能深的搜索樹的分支
當節點v的所有邊都已經被搜索過,將回溯到發現節點v的那條邊的起始節點
這一過程一直進行到已發現從源節點可達的所有節點爲止。
如果還存在未被發現的節點,則選擇其中一個作爲源節點並重覆上述過程
是一種典型的盲目搜索,如果不進行優化,DFS效率很低,一般要根據題意進行剪枝

DFS實現時一般用到遞歸,使用系統堆棧
void DFS(int v)
{
    visit(v);
    visited[i] = true;
    if (v和u存在邊 && !visited[u])
    {
        DFS(u); 
    }
}

2、廣度優先搜索BFS
是從任意節點V開始,一次搜索其可以擴展的每一個節點V1,V2。。。
當一層節點全部搜索完之後,再依次搜索第一個可擴展節點的所有節點
知道所有節點均被訪問,算法終止。
BFS和樹的層序遍歷很像,搜索順序具有明顯的層次性,一般用隊列實現
注意:先訪問頂點,再把頂點入隊,訪問完該頂點的所有鄰接頂點時,再出第一次訪問的節點,接下來就是重複上述步驟

void BFS(int v)
{
    int w;
    visit(v);               //訪問頂點 
    visited[v] = true;      //頂點V對應的訪問標記置爲1
    queue.push_back(v);     //入隊
    while (!queue.Empty())
    {
        v = queue.pop_back();   //退出隊首元素
        w = firstAdj(v);        //求v的第一個鄰接點,無鄰接點時返回-1
        while (w != -1)
        {
            if (!visited[w])    //沒有訪問過該節點
            {
                visit(w);       //訪問該節點
                queue.push_back(w); //入隊
                visited[w] = true;  //標記置爲1 
            }
            w = nextAdj(v);         //求下一個鄰接點,無鄰接點時返回-1 
        }
    }
}

BFS常用於解決最優可行解的問題,類似最小步數、最短步數等

3. 啓發式搜索:
是在搜索過程中加入了與問題有關的啓發式信息,用於指導搜索朝着最有希望的方向進行,掃除不必要的搜索過程,加速問題求解並得到最優解。
由於啓發式信息根據問題不同而異,因此需要分析問題的條件,尋找可以改變搜索順序和剪枝的條件

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章