iT邦幫忙

2023 iThome 鐵人賽

DAY 21
0
自我挑戰組

資料結構與演算法-CS61B學習筆記系列 第 21

Day21-Rage Search (QuadTree, k-d Tree, Uniform Partitioning)

  • 分享至 

  • xImage
  •  

在此之前我們探討過如何達到add, get, contain, delete等操作的資料結構,這章節要來談談range search的操作:

// Suppose we have a Set that will contain nth T type elements.
// {1, 4, 5, 6, 9, 11, 14, 17, 20}
select(int i) -> find ith smallest item.
ex: 
select(0) -> 1
select(3) -> 6

rank(T t) -> find t item's rank in the set.
ex:
rank(1) -> 0
rank(6) -> 3

subSet(T from, T to) -> find all items between from & to.
ex:
subSet(4, 9) -> {4, 5, 6, 9}
subSet(3, 12) -> {4, 5, 6, 9, 11}
subSet(12, 13) -> {}

nearest(T x) -> the item closest to x
ex:
nearest(6) -> 6
nearest(8) -> 9
nearest(10) -> 9 or 11

其實就跟get類似,我們只要多紀錄目標與當前node的距離就好了:

01

而其他select, rank, subSet也可以用類似的概念做到。

在此之前我們探討的功能都只針對一維的資料來進行,也就是每個元素都可以很明確地做到comparable,2一定大於1,zebra一定大於apple等等,所以接下來我們要探討的問題先鎖定在如何在二維中去找出nearest的做法。

下圖的範例是我們在宇宙中有這些黃點,我們要找出最靠近那批漂浮在宇宙中的馬的黃點:

02

我們有辦法建立二維的tree嗎? 試試根據x軸或y軸為基準來建立,就會如下圖所示:

03

如果如下圖範例,我們想找到x軸小於-1.5的node,我們其實可以不用走遍所有的node來確認,因為BST的結構,我們根本就不用去找A點右側的那串,因為A點本身的-1就已經大於-1.5了。這個判斷的行為我們稱為Pruning,在中文裡這個字是修剪樹枝的那個修剪。

04

可是這樣只能限於x軸的判斷,好像還是不夠周全,所以接著我們來介紹QuadTree。

Quad取自於quadratic,四邊形,代表tree會有四個面向來進行展開,在二維中就是四個方位:

05

以下我們來實際用一個範例感受Quadtree的運作,假設我們想找出下圖綠色框框中包含了哪些節點,該如何進行呢?一個關鍵的概念就是不斷去prune不在目標方位上的點,所以以下面的範例而言,我們就可以prune掉NW, SE, SW了:

06

如下圖由root A出發,並prune掉非目標方向的方位:

07

所以下一個點來到B,並判斷B是否在綠框中?沒錯,所以加入results中:

08

接著要來看我們之後要探索的方向有哪些?發現四個方位都在綠框中,所以四個方向等等都要探索:

09

首先探索NW:

10

再來換NE:

11

再來SE:

12

再來是SW,SW方向上就進行到點C了:

13

點C判斷完後,再來看要從哪個方向探索,發現只有NE在綠框中:

14

可是NE方向上沒有其他點了,故結束:

15

除了QuadTree可以處理二維資料外,還有另一種結構可以進行,就是k-d Tree。

k-d Tree其概念就是每一層判斷大小的基準會不斷交替x軸與y軸,比如第一層根據y軸判斷,那下一層會依據x軸判斷,不斷反覆:

16

我們來看一個nearest的範例,我們想找到跟目標點(1, 7)最接近的點是誰?

從root A出發,A與目標的距離為4.5

17

紀錄完距離後,接著往下一個點進行,該從哪個點開始呢?先從靠近目標的開始,所以從左半端先:

18

點E與目標的距離更好,於是更新best result,接著來看看該從哪個方向探索?先往靠近目標的來,所以是往上:

19

但點E上方沒有其他點了,故結束探索。接著是個關鍵的問題,我們有必要探索點E的下方嗎?有沒有可能存在更近的點?

20

答案是有可能!如果有存在點的x方向與目標更近,就有可能有比點E更靠近了,所以我們需要繼續探索這個方向:

21

可惜這邊沒有其他點存在:

22

再來回到root,右側有可能存在更靠近的點嗎?確實有可能!所以我們繼續探索右側:

23

右側第一個點是點B,其距離沒有比當前best result好,故跳過。接著往靠近目標點的方向探索:

24

到點C,距離也沒有當前的好,繼續往靠近目標點方向探索:

25

到點D,也沒更靠近,再繼續往靠近目標點方向探索:

26

沒有其他點了!

27

接下來思考,我們有必要往點D的下方探索嗎?會發現沒必要,因為那個方向上不可能存在比點E更靠近的距離,所以就可以prune掉這個方向:

28

在來回到點C,點C右側有可能有更靠近的點嗎?沒可能,所以也可以prune掉:

29

回到點B,點B下方會有更靠近的點嗎?沒可能,所以也prune掉:

30

然後就回到點A,就結束了~所有good side跟bad side的可能性都探索完了。

31

我們回到一開始宇宙馬的問題,除了利用quad tree來進行range search外,我們也可以用另一個想法進行,假設整個宇宙我們切分成以下16的區域,而我們知道宇宙馬最靠近的區域會是綠框,這樣一來我們就只要計算5, 6, 9, 10這四個子區域的點就好了,不需要搜尋所有16個區域的點。

32

以下是uniform和quad tree的比較,可以發現他們的差別在於對於空間的劃分,quad tree或kd tree根據每個點切出4或2個子空間;而uniform把整個空間切成一定的數量。

33

Slides are from Josh Hug CS61B
license
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License


上一篇
Day20-Minimum spanning tree - Kruskal’s algorithm
下一篇
Day22-Topological Sort - Intro
系列文
資料結構與演算法-CS61B學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言