Tree Search(樹狀搜尋)

一、什麼是 Tree Search(樹狀搜尋)? 在人工智慧(AI)與演算法中,許多問題都可以表示成一棵樹(圖一): 起點(A) / | \ B C D /|\ | / \ E F G H I J 每個節點(Node)代表一種狀態(State)。 例如: 迷宮中的位置 棋局的盤面 路徑規劃中的城市 遊戲中的決策 搜尋演算法的目的: 從起點找到目標節點(Goal Node) 二、Breadth First Search (BFS) 核心思想 先搜尋離起點最近的節點。 一層一層往外擴展。 Level 0: A Level 1: B C D Level 2: E F G H I J 搜尋順序: A B C D E F G H I J 圖一結果: A → B → C → D → E → F → G → H → I → J 使用資料結構 Queue(佇列) FIFO: First In First Out 先進先出 例如: Queue: A 取出A 加入B,C,D Queue: B,C,D BFS特性 優點 如果邊權重相同: BFS一定找到最短路徑。 缺點 需要大量記憶體。 假設每個節點有10個子節點: 深度5: 10^5 = 100000 需要保存很多節點。 時間複雜度 O(V + E) V = Vertex(節點數) E = Edge(邊數) 三、Depth First Search (DFS) 核心思想 一路往下走到底。 不能走才回頭。 A | B | E 然後: A | B | F 搜尋順序 圖一結果: A B E F G C H D I J 使用資料結構 Stack(堆疊) LIFO Last In First Out 後進先出 例如: push(B) push(C) push(D) pop() => D DFS特性 優點 記憶體需求小。 只需保存: 目前路徑 即可。 缺點 可能找到很差的解。 例如: A ├── Goal └── 巨大子樹 DFS可能先跑完整個巨大子樹。 時間複雜度 O(V+E)...

高中生程式解題系統:後序運算法

題目連結 https://zerojudge.tw/ShowProblem?problemid=d016

後序表示法的運算方式如下:
從後序表示法的前方開始讀取,
若是運算元則放進堆疊裡,
若是運算子,則從堆疊取出兩個運算元進行運算,並將結果存回堆疊,
若讀取完畢,則堆疊的最頂端即為此後序表示式的運算結果。

例子可看底下影片的動畫說明:

底下程式碼是用STL裡的stack來做。此外,程式碼的寫法是可以改善的。

程式碼:
#include <iostream>
#include <string>
#include <sstream>
#include <stack>

using namespace std;

int main(){

    string input;

    while( getline(cin, input) )
    {
        stack<int> value;

        stringstream strStream(input);
        string token;
        int inStack;
        int outStack;

        while( strStream >> token )
        {
            switch(token[0])
            {
                case '+':
                    outStack = value.top();
                    value.pop();
                    inStack = value.top();
                    value.pop();
                    inStack += outStack;
                    value.push(inStack);
                    break;
                case '-':
                    outStack = value.top();
                    value.pop();
                    inStack = value.top();
                    value.pop();
                    inStack -= outStack;
                    value.push(inStack);
                    break;
                case '*':
                    outStack = value.top();
                    value.pop();
                    inStack = value.top();
                    value.pop();
                    inStack *= outStack;
                    value.push(inStack);
                    break;
                case '/':
                    outStack = value.top();
                    value.pop();
                    inStack = value.top();
                    value.pop();
                    inStack /= outStack;
                    value.push(inStack);
                    break;
                case '%':
                    outStack = value.top();
                    value.pop();
                    inStack = value.top();
                    value.pop();
                    inStack %= outStack;
                    value.push(inStack);
                    break;
                default:
                    inStack = atol(token.c_str());
                    value.push(inStack);
                    break;
            }
        }

        inStack = value.top();
        cout << inStack << endl;
    }

    return 0;
}
若您覺得文章寫得不錯,請點選文章上的廣告,來支持小編,謝謝。

留言

這個網誌中的熱門文章