Heap/Flood Fill/Basic Graph
2020/03/28
Lecture By lawfung
Credit by zolution, qazwsxedcrfvtg14
目錄 目錄
• 合併 Heap ✩✩✩✩✩
• Heap 魔法 ✩✩✩✩
• 建立 Heap ( 理論 )
• 左偏樹 ✩✩✩
• BIBFS ✩✩
• A* ✩✩
• 拓樸排序 ✩✩✩✩✩
• 思考題 ✩
• Cayley's formula ( 理論 )
• Number of binary tree ( 理論 )
Heap
課程影片 課程影片
• Q&A
Heap 小知識 Heap 小知識
世界上的 Heap 有很多種
• 影片中介紹的 Binary heap
• Binomial heap
• Pairing heap
• Thin heap
• Fibonacci heap
• ……
Heap 小知識 Heap 小知識
• 為什麼會有這麼多種 Heap?
• 有的常數比較小
• 有的可以 O(1) 插入
• 有的可以 O(1) 刪除
• 有的可以 O(logN) 合併 ??
• 有的可以 O(1) 合併 ??!!
• 有興趣請自行上網查詢資料
Heap 合併
Heap 合併 Heap 合併
• Heap 合併是什麼 ?
• 簡單來說就是把兩個 Heap 變成一個 Heap
模擬情況 模擬情況
• 現在有 N 個 Heap ,有三種操作
• Push : 把一個元素放進其中一個 Heap
• Pop : 從一個 Heap 中取出最小的元素
• Merge : 合併兩個 Heap
• 假設總操作數最多 Q 次,其中 Push 最多 N 次
Heap 合併 Heap 合併
• 先不管複雜度,來想個最天真的作法吧 ~
• Push 和 Pop 就照一般的做法做
• 合併呢 ?
• 開一個新的 Heap ,把原先兩個 Heap 的元素一個一個的 push 進 去
• 複雜度 O(Q*NlogN)
Heap 合併 Heap 合併
• 那我們換一種方式
• 把其中一個 Heap 的元素一個一個的 push 進另外一個 Heap
• 複雜度 ?
• O(Q*NlogN)
Heap 合併 Heap 合併
• 那…如果我們把比較小的 Heap 慢慢加到另外一個 Heap 中呢 ?
• 複雜度 ?
• O(Q*NlogN)…?
• O(Nlog^2(N)+QlogN) ??!!
• 啟發式合併 !
• 考慮對於每一個元素,它每次被併入一個新的集合,它所處集合的大小至少 是原來的兩倍。所以對每個元素至多進行 logN 次合併操作,總複雜度 N*log N*logN
示意圖 示意圖
黑色 : 需要拿出再放入其他 Heap
紅色 : 當今在的 Heap 被使用為合併後的 Heap
魔法 魔法
• 幾個在 C++ 中關於 Heap 的魔法
• STL
• std::priority_queue
• 黑魔法
• __gnu_pbds::priority_queue
std::priority_queue std::priority_queue
• #include <queue>
• std::priority_queue<int> pque;
• priority_queue<int, vector<int>, greater<int> > lque
__gnu_pbds::priority_queue __gnu_pbds::priority_queue
• #include <ext/pb_ds/priority_queue.hpp>
• __gnu_pbds::priority_queue<int> pque;
• priority_queue<int, greater<int> > lque
• h1.join(h2);
Building Heap Building Heap
• 如果一開始就已經有所有元素了,要建造出一個 Heap
• Insertion of Heap: O(logN)
• 所以 Build a heap of N element: O(NlogN)
• 其實這個 bound 不夠緊,可以壓到 O(N)
• https://www.geeksforgeeks.org/time-complexity-of-building-a-heap/
作法 作法
• 從底層往上,將小的子 Heap 建好後,再將大 Heap 也完成。
• 接下來是要證明複雜度是 O(N)
• 使用公式
at x=
•
示意圖 示意圖
Height Count
3 1
2 2
1 3
0 8
Leftist Tree
為什麼要左偏樹 為什麼要左偏樹
• 可合併堆
• 雖然其實黑魔法也可以
• 合併多快
• O(log(N)+log(M))
定義 定義
• 外節點 :
• 二元樹中,如果 X 的左子樹是空的,
我們就視為 X 的左兒子接了一個外節點。
• 右子樹亦然
S-value S-value
• 也叫做 rank ( 秩 )
• S(X) 定義為距離 X 最近的外節點的距離
• 重要性質 :
• 一棵樹至少有 個點
• 證明 :
• 至少有 1 個點的 S-value 是 s(root)
• 至少有 2 個點的 S-value 是 s(root)-1
• ……
•
左偏樹 左偏樹
1. 它是一顆二元樹
2. 每個節點的數值不大於其父親之值
3. 對於每個點,右子樹的 S-value 不大於左子樹的 S-value
• 因此才叫做左偏
• 根據這個性質,左偏樹上的 S-value ,等於一直往右小孩走,走到外節 點的距離。
示意圖 示意圖
右邊很短 ! 右邊很短 !
• 也就是 O(log N)
• 左偏樹上的 S-value ,等於一直往右小孩走,走到外節點的距離
。
• 所以右邊很短 !
• 這讓我們想往右邊合併去
•
操作 操作
1. 合併兩棵左偏樹
2. 插入
• 把新節點視為一棵樹,將兩棵樹合併
3. 刪除最小值
• 將根刪除,把左右子樹合併
合併 合併
• 合併 兩棵左偏樹 ( 假設的根較小 )
1. 將的根保持為新左偏樹的根,的右子樹和遞迴合併
2. 檢查是否還符合左偏樹性質
( 右子樹的 S-value 不大於左子樹的 S-value) , 若否,交換左右子樹
•
為什麼很快 為什麼很快
• 令為需要合併的兩棵左偏樹的 S-value 和
• K 一開始是 O(log(N)+log(M))
• 每次遞迴下去一次, K 就會減少 1
• 所以複雜度是 O(log(N)+log(M))
•
練習題 練習題
• https://tioj.ck.tp.edu.tw/problems/1429
• 可以用啟發式合併
• 可以用左偏樹
• 可以用黑魔法
• 本人實測
• 左偏樹最快
• 黑魔法次之
• 啟發式合併最慢
• 但是其實也沒差多少 XD
Flood fill
課程影片 課程影片
• Q&A
淹水 淹水
• 模擬「淹水」的過程很麻煩,幾個方向就要寫幾個很大串的 if
,怎麼辦?
• 提示:有沒有發現所有的 if 其實都長得很像?
淹水 淹水
int dx[4] = [-1,0,0,1];
int dy[4] = [0,-1,1,0];
for(int i = 0 ; i < 4; i++)
if(check(x+dx[i], y+dy[i]))
queue.push(x+dx[i], y+dy[i]);
Bidirectional search
雙向搜索 雙向搜索
• 明確知道終點的位置
• 知道反向邊
為甚麼要雙向 為甚麼要雙向
BIBFS BFS
何時使用 何時使用
• 以格狀圖為例子
• 二維時,加快了 50%
• K 維時, BIBFS 只需搜尋個狀態
• 而 BFS 需要搜尋
• 因此 BIBFS 加速為 BFS 的
•
何時使用 何時使用
• 分支因子 (Branching factor)
• 就是出度啦
• 用 b 來表示
• 在實際面的搜索上,狀態很多很雜
• d 步內,就會有 O() 個狀態
• BFS 複雜度就是 O()
• BIBFS 呢
• O()+ O() = O()
•
練習題 練習題
• https://tioj.ck.tp.edu.tw/problems/1198
A* Search
Credit to Theory of Computer Games, 2018 Fall
A* A*
• A-star Algorithm
• 估算最好的選擇會是哪一個 state ,就先搜他
• BFS with Heap!
• f(x) = g(x) + h(x)
• f(x): Evaluation Function( 評價 )
• g(x): Cost Function( 實際已花費 )
• h(x): Heuristic Function( 估算未來需要多少 Cost)
• 當 h(x) 等於 0 時,等同 BFS
Normal BFS
Normal BFS
A* A*
A* A*
• 常在爆搜的情境下用到
• 節省不必要,偏差的 State ,先搜最有可能的 State
• 走迷宮:會 Prefer 往終點方向的 State
• 下棋:會 Prefer 己方子力大的 State
• 解 Puzzle : Prefer 靠近解答的 Move
Heuristic Function Heuristic Function
• 想一想,走迷宮的時候你會怎麼設計 Heuristic Function?
• 歐幾里德距離?
• 曼哈頓距離?
• f(x) = g(x) + h(x)
• f(x): Evaluation Function( 評價 )
• g(x): Cost Function( 實際已花費 )
• h(x): Heuristic Function( 估算未來需要多少 Cost)
A* 一定會找到最佳解嗎?
A* 一定會找到最佳解嗎?
• Admissible Heuristic: Never “Overestimate”
• 不高估的狀況下, f(x) 永遠不會比真實需要的最小值還大
• 根據 Min-Heap ,這個點一定會被搜到,且是最佳解
• We need a lower bound estimation that is as large as pos sible (T.S. Hsu, 2018)
相同的練習題 相同的練習題
• https://tioj.ck.tp.edu.tw/problems/1198
• 重點是 h(x) 要設什麼
Graph
課程影片 課程影片
• Q&A
存圖 存圖
• 當我們需要動態加邊的時候,該怎麼做 ?
• 當我們需要刪邊的時候,該怎麼做 ?
• 還有很多有趣的存圖方式 !
• 其實應該算是原本那兩種的變種
• 我好像也沒會多少
• 啊又用不到
存圖 存圖
• 相鄰串列
• 相鄰矩陣
• 二元搜尋樹
比較 比較
• 相鄰矩陣
• 空間複雜度: O(V2)
• 查詢兩個點之間是否有邊: O(1)
• 遍歷一個點 v 周圍的邊: O(V)
• 增加一條邊: O(1)
• 刪除一條邊: O(1)
• 相鄰串列
• 空間複雜度: O(V+E)
• 查詢兩個點之間是否有邊: O(degree(V))
• 遍歷一個點 v 周圍的邊: O(degree(V))
• 增加一條邊: O(1)
• 刪除一條邊: O(degree(V))
比較 比較
• 二元搜尋樹
• 空間複雜度: O(V+E)
• 查詢兩個點之間是否有邊: O(log(degree(V)))
• 遍歷一個點 v 周圍的邊: O(degree(V))
• 增加一條邊: O(log(degree(V)))
• 刪除一條邊: O(log(degree(V)))
Topological sort
想想看 想想看
• 給你一張有向圖,要怎麼知道這張圖上面有沒有環 ?
• DFS?
• BFS?
拓樸排序 拓樸排序
• 現在有一個工廠,裡面有很多台機器,有些機器所生產 的東西可能會依賴於其他機器,但是保證不會循環。
• 問 : 找出一個機器的執行順序使得過程中不會有機器依 賴於還沒執行過的機器。
• 有向無環圖 (DAG)
How to 拓樸排序 How to 拓樸排序
• Kahn's Algorithm
• 找出一個入度為 0 的點,讓它當第一個,把它從圖上拔掉
• 再找一個入度為 0 的點,讓它當下一個,把它從圖上拔掉
• 一直做
• 拔完了
• 找到一組解
• 拔不完
• 有環
How to 拓樸排序 How to 拓樸排序
• DFS
• 離開序列的逆序
用不太到的思考題
Alice and Bob Alice and Bob
• 有一個遊戲, Alice 跟 Bob 要有限度的心電感應。
• Alice 跟 Bob 可以事前溝通,他們也知道每一回合的形式。
• 主持人會公開 N ,代表圖中有 N 個點。
• Alice 會看到主持人的圖, Bob 則看不到
Alice and Bob Alice and Bob
• 有一個遊戲, Alice 跟 Bob 要有限度的心電感應。
• Alice 跟 Bob 可以事前溝通,他們也知道每一回合的形式。
• 主持人會公開 N ,代表圖中有 N 個點。
• Alice 會看到主持人的圖, Bob 則看不到
• ROUND 1: 主持人給定一張圖, Alice 可以傳一個個字元的 0/
1 字串給 Bob ,而 Bob 必須要還原出主持人的圖
•
Alice and Bob Alice and Bob
• 有一個遊戲, Alice 跟 Bob 要有限度的心電感應。
• Alice 跟 Bob 可以事前溝通,他們也知道每一回合的形式。
• 主持人會公開 N ,代表圖中有 N 個點。
• Alice 會看到主持人的圖, Bob 則看不到
• ROUND 2: 主持人給定一棵樹, Alice 可以傳一個個字元的 0/
1 字串給 Bob ,而 Bob 必須要還原出主持人的樹
•
Alice and Bob Alice and Bob
• 有一個遊戲, Alice 跟 Bob 要有限度的心電感應。
• Alice 跟 Bob 可以事前溝通,他們也知道每一回合的形式。
• 主持人會公開 N ,代表圖中有 N 個點。
• Alice 會看到主持人的圖, Bob 則看不到
• ROUND 3: 主持人給定一棵樹, Alice 可以傳一個個字元的 0/
1 字串給 Bob ,而 Bob 必須要還原出主持人的樹的長相
•
組合樹學
Cayley's formula
Cayley's formula Cayley's formula
• 個有編號的點,形成的樹有種
•
Proof Proof
• https://golem.ph.utexas.edu/category/2019/12/a_visual_telling_of_joyals_pro.html
• 我們想要證明以下兩者可以一一對應
• 在大小為 N 的樹上選出一個起點與一個終點 ( 可以相同 )
• 一個長度為 N 的序列,其中每項的值都是 1~N 之間的自然數
• 第二項的數量是
• 因此樹的數量就會是
•
Proof
Proof
Proof
Proof
Proof Proof
• 原路徑序列 : [20, 4, 3, 17, 15]
• 排序它們 : [ 3, 4, 15, 17, 20]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
15 4 20 17 3
Proof Proof
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
11 15 4 11 20 20 17 11 3
方向一完成 方向一完成
• 所以我們成功的把
”在大小為 N 的樹上選出一個起點與一個終點”
對應到一個序列
• 接下來要證明這個序列可以對應回來
Proof Proof
• 用序列畫出這個有向圖
• 把環拆出來 ( 右圖 ) ,其餘放置 ( 左圖 )
Proof Proof
• 左圖 ( 把方向拿掉 ) 繼續放置
• 用右圖還原出路徑
• 戳到最小值的那個點是起點…
方向二完成 方向二完成
• 所以我們成功的把序列對應回
”在大小為 N 的樹上選出一個起點與一個終點”
• 因此他們是一一對應的
• 因此樹的數量就會是
•
Number of binary tree
想想看 想想看
• 今天給你 N 個相異元素,要求你用這些元素做出一個 Heap
• 這個 Heap 必須是 binary tree
• 但是不必是 complete binary tree
• 這是合法的
• 請問可以做出幾種 Heap
• 答案 為甚麼呢 ?
•
想想看 想想看
• 今天給你 N 個相異元素,要求你用這些元素做出一個 BST (binary search tree)
• 請問可以做出幾種 BST
• 卡塔蘭數
• 有興趣請自行上網搜尋