Các chỉ mục sẽ nằm tại các nút lá chứa các điểm dữ liệu, khi đó việc tìm kiếm không gian sẽ thực hiện trên một số lượng nhỏ các nút. Một cơ sở dữ liệu không gian bao gồm tập hợp của các bộ đại diện cho các đối tượng trong không gian, mỗi bộ có một nhận biết duy nhất, ta cóthể dùng nhận biết này để truy xuất nó. Các node lá trong R-Tree chứa các đầu vào mẫu tin chỉ mục với khuôn dạng (I, tuple-identifier) trong đó tuple- identifier tham khảo đến một bộ trong cơ sở dữ liệu và I là hình chữ nhật n chiều, hình này là khung giới hạn nhỏ nhất MBR của các chỉ mục đối tượng không gian.
I = (I0, I1,… In).
n - số chiều không gian
Ii - một khoảng biên khép kín [a,b], mô tả phạm vi của đối tượng cùng với chiều i.
Một node không phải là node lá (Internal node) chứa các phần tử như sau (I, child-pointer), child-point là địa chỉ của node thấp hơn trong R-Tree và I bao phủ tất cả các hình chữ nhật trong các phần tử của các node thấp hơn.
a. Tìm kiếm trong cấu trúc dữ liệu tổ chức dưới dạng R-Tree
Thuật toán tìm kiếm duyệt cây từ gốc (root) đi xuống theo cách tương tự như B-tree. Tuy nhiên khi thăm một node sẽ có nhiều hơn một cây con dưới node đó cần được tìm kiếm, vì lý do đó thuật toán không thể bảo đảm thực hiện tốt trong các trường hợp xấu nhất. Tuy nhiên với nhiều kiểu của dữ liệu, thuật toán cập nhật sẽ duy trì hình dạng của cây, cho phép thuật toán tìm kiếm loại đi các vùng không liên quan của không gian được đánh chỉ mục, và kiểm tra duy nhất dữ liệu gần vùng tìm kiếm. Chúng ta sẽ biểu diễn phần hình chữ nhật của một chỉ mục E là EI, và phần nhận dạng dữ liệu hay child- pointer là Ep.
Cho R-tree có root là T, tìm tất cả các mẫu tin chỉ mục mà có các hình chữ nhật chồng lên một hình chữ nhật cần tìm S.
- S1 [Tìm kiếm trên cây con] Nếu T là một node lá, kiểm tra mỗi mục E
để xác định xem Ei có trùng lên S hay không. Với tất cả các mục trùng nhau, thực hiện tìm kiếm trên cây mà node root của nó được chỉ bởi Ep.
- S2 [Tìm kiếm trên node lá] NếuT là một lá, kiểm tra tất cả các mục E
để xác định EI có trùng lên S hay không. Nếu trùng E là một record đủ tiêu chuẩn.
b. Chèn (Insertion)
Việc thêm các chỉ mục cho các bộ dữ liệu mới giống như thêm trong B- tree là các chỉ mục mới được thêm vào cho các lá, các node chứa quá số lượng sẽ bị tách ra và quá trình tách này sẽ lan truyền lên phía trên cây.
Thuật toán Chèn (Insert):
Thêm một mục nhập chỉ mục mới E vào trong R-tree
- I1: [Tìm vị trí cho dữ liệu mới] dùng thuật toán chọn lá (ChooseLeaf)
để chọn một node lá L để thêm E.
- I2: [Thêm dữ liệu cho node lá] nếu L có chỗ cho một entry khác, thêm
E nếu không thì dùng thuật toán chia node (SplitNode) để có được L và LL chứa E và tất cả các mục nhập của L.
- I3: [Lan truyền các thay đổi lên phía trên] Dùng thuật toán điều chỉnh
cây (AdjustTree) trên L, đồng thời bỏ qua LL nếu việc phân chia đã được thực hiện.
- I4: [Tăng trưởng cây] nếu phân chia node lan truyền làm cho root phân
chia, tạo ra một root mới, mà con của root mới này là 2 node kết quả.
c. Thuật toán Chọn lá (ChooseLeaf)
Chọn một node lá mà node lá này đặt một chỉ mục mới E.
- CL2: [Kiểm tra lá] Nếu N là một lá, trả về N.
- CL3: [Chọn cây con] Nếu N không phải là một lá, cho F là phần tử
trong N mà các hình chữ nhật của nó FI cần mở rộng lá để tính EI. Giải quyết các hạn chế bằng cách chọn phần tử với hình chữ nhật có diện tích nhỏ nhất.
- CL4: [Đi xuống cho đến khi một node lá được tìm thấy] tập N là node
con được chỉ đến bởi Fp và lặp lại từ CL2.
d. Thuật toán điều chỉnh cây (AdjustTree)
Đi lên từ một node lá L đến root, điều chỉnh hình chữ nhật bao phủ và lan truyền phân chia các node chia khi cần thiết.
- AT1: [Khởi tạo] cho tập N=L, nếu L đã được phân chia trước đó, tập
NN là kết quả của node thứ hai.
- AT2: [Kiểm tra nếu thực hiện] Nếu N là root, ngưng.
- AT3: [Điều chỉnh vùng phủ hình chữ nhật trong mục nhập cha] Cho P
là node cha của N và cho EN là các entry của N trong P. Điều chỉnh EN
I để cho nó bao sát xung quanh tất cả các hình chữ nhật entry trong N.
- AT4: [Lan truyền node bị tách lên phía trên] Nếu N có NN (partner) kết
quả từ một phân chia mới nhất, tạo một entry mới ENN P trỏ đến NN và ENN I bao quanh tất cả các hình chữ nhật trong NN, thêm ENN vào
P nếu có chỗ. Nếu không dùng SplitNode đểtạo ra P và PP chứa ENN
và tất cả các entry của P.
- AT5: [Di chuyển đến mức kết tiếp]. Cho tập N=P và tập NN=PP nếu có
sự phân chia xảy ra. Lặp lại bước AT2.
e. Xóa (Deletion)
Thay đổi vị trí chỉ mục của record E từ R-tree.
- D1: [Tìm node chứa record] thực hiện thuật toán FindLeaf để xác định
- D2: [Xóa record] Xóa E từ L.
- D3: [Lan truyền thay đổi] dùng thuật toán CondenseTree bỏ qua L.
- D4: [Rút ngắn cây] Nếu root có duy nhất một con sau khi cây đã được
điều chỉnh, tạo con cho root mới.
f. Thuật toán tìm lá (FindLeaf)
Cho R-tree có root là T, tìm node lá chứa đầu vài chỉ mục E.
- FL1: [Tìm cây con] nếu T không phải là node lá, kiểm tra mỗi entry F
trong T để xác định, nếu FI chồng lấp với EI. Với mỗi entry thực hiện thuật toán FindLeaf trên cây mà root của nó được trỏ đến bởi Fp cho đến khi E được tìm thấy hay tất cả các entry đã được kiểm tra.
- FL2: [Tìm node lá cho mục cho record] Nếu T là lá, kiểm tra mỗi entry
để xem nếu nó phù hợp với E, nếu E được tìm thấy trả về T.
g. Thuật toán Gom cây (CondenseTree)
Cho một node lá L, mộtentry được xóa từ node lá này, loại ra node này nếu nó có quá ít các chỉ mục và xây dựng lại các entry của nó. Lan truyền việc loại node này lên trên khi cần thiết. Điều chỉnh các hình chữ nhậtbao phủ trên đường dẫn đến root, làm cho các hình chữ nhật này nhỏ hơn nếu có thể.
- CT1: [khởi tạo] cho tập N=L, tập Q là tập của các node bịloạibỏ, Q là
tập rổng.
- CT2: [Tìm entry cha] nếu N và root, nhảy tới bước CT6. Nếu không thì
cho P là cha của N, và cho EN là các entry của N trong P.
- CT3: [Loại node không đủ (Eliminate under-full node)] Nếu N có ít
hơn m entry, xóa EN khỏi P và thêm N vào tập Q.
- CT4: [Điều chỉnh hình chữ nhật bao phủ] Nếu N không bị loại bỏ, điều
chỉnh EN I để chứa sát lại các entry trong N.
- CT5: [Di chuyển lên trên một mức trong cây] Cho tập N=P và lặp lại
- CT6: [Chèn lại các entry bị mồ côi (Re-insert orphaned entries)].
Chèn lại vào tất cà các phần tử của các node trong tập Q. Các entry từ các node lá bị loại bỏ được chèn lại vào trong các lá của cây như đã được mô tả trong thuật toán Insert, nhưng các entry từ các node có mức cao hơn phải được đặt cao hơn trong cây, vì vậy các lá của các cây con phụ thuộc vào chúng sẽ nằm trên cùng mức như các lá của cây mẹ.
h. Cập nhật (Update)
Nếu một bộ dữ liệu được cập nhật để cho hình chữ nhật bao phủ nó bị thay đổi, bản ghi chỉ mục của nó phải bị xóa, cập nhật và chèn lại, vì vậy nó sẽ phải tìm cách để đặt đúng vị trí trong cây.
Một cách tìm kiếm khác so với cách được mô tả ở trên có thể hữu ích hơn, ví dụ để tìm tất cả các đối tượng dữ liệu được chứa hoàn toàn trong một vùng tìm kiếm, hoặc tất cả các đối tượng chứa vùng tìm kiếm.
Các bước thực hiện có thể được thực hiện bằng các biến đổi dễ hiểu trên thuật toán đã cho. Tìm một phần tử cụ thể mà nhận dạng của nó đã được biết trước cần đến thuật toán xóa và được thực hiện bằng thuật toán FindLeaf. Các biến đổi của phạm vi xóa, trong phạm vi này, tất cả các đối tượng dữ liệu trên diện tích liên quan được xóa đi, cũng được R-tree cung cấp khá tốt.
i. Thuật toán tách node (Node Splitting)
Để thêm một phần tử mới, một node chứa đầy M các chỉ mục, cần phải phân chia tập hợp của M+1 các phần tử thành 2 node. Sự phân chia nên được thực hiện theo cách làm cho nó không chắc có thể thực hiện được việc phân chia cả hai node mới sẽ cần được kiểm tra trên việc tìm kiếm thứ tự. Khi đó sự quyết định thăm một node phụ thuộc vào hình chữ nhật bao phủ nó có chồng lên diện tích tìm kiếm. Tổng số diện tích của hai hình chữ nhật bao phủ sau khi tách có thể được giảm đến mức tối thiểu. Hình dưới đây minh họa
điều này. Diện tích của các hình chữ nhật trong trường hợp “bad split”lớn hơn nhiều so với trường hợp “good split”.
Hình 2.3. Trƣờng hợp phân chia node (a) bad split, (b) good split.
Cùng tiêu chuẩn đã được dùng trong thủ tục ChooseLeaf để quyết định xem nơi nào có thể chèn một chỉ mục mới vào tại mỗi mức trong cây, cây con được chọn là một cây mà hình chữ nhật bao phủ của nó phải được mở rộng ít
Bad nhất khi chèn chỉ mục mới vào.
Chúng ta quay lại thuật toán phân chia tập M+1 phần tử thành hai nhóm cho mỗi node mới.
Hình 2.4. Phân chia phần tử thành các nhóm node mới
j. Thuật toán A Quadractic Cost
Thuật toán này cố gắng tìm một vùng được tách ra có diện tích nhỏ, nhưng không bảo đảm là có thể tìm được một vùng có thể có diện tích nhỏ nhất. Chi phí là bậc 2 theo M và tuyến tính theo số lượng của các chiều.
Thuật toán chọn 2 phần tử trong số M+1 phần tử làm phần tử đầu tiên của hai nhóm mới, bằng cách chọn này, hai phần tử mới này có thể làm lãng phí diện tích lớn nhất nếu cả hai được đặt trong cùng một nhóm. Như vậy diện tích hình chữ nhật bao phủ cả hai phần tử, trừ đi diện tích của chính các phần tử, sẽ là lớn nhất. Các phần tử còn lại được gán vào các nhóm cùng lúc. Tại mỗi bước, việc mở rộng diện tích đòi hỏi phải thêm mỗi phần tử còn lại cho mỗi nhóm được tính toán, và phần tử được gán thì sẽ xuất hiện một sự khác biệt lớn nhất giữa hai nhóm.
k. Thuật toán Quadratic Split
Phân chia một tập M+1 các chỉ mục thành hai nhóm.
- QS1: [chọn phần tử đầu tiên cho mỗi nhóm] Áp dụng thuật toán
PickSeeds để chọn hai phần tử làm các phần tử đầu tiên của các nhóm. Gán mỗi phần tử cho một nhóm.
- QS2: [Kiểm tra nếu đã thực hiện] Nếu tất cả các phần tử đã được gán,
ngừng. Nếu một nhóm có một vài phần tử mà tất cả những phần tử còn lại phải được gán vào nó theo thứ tự để cho nhóm này có m nhỏ nhất, gán các phần tử và ngừng.
- QS3: [Chọn phần tử để gán] Thực hiện thuật toán PickNext để chọn
phần tử kế tiếp để gán. Thêm phần tử này vào nhóm mà hình chử nhật bao phủ của nó sẽ phải mở rộng ít nhất để chứa phần tử này. Giải quyết các hạn chế bằng cách thêm phần tử vào nhóm có diện tích nhỏ nhất, khi đó nhóm này có các phần tử ít hơn nhóm khác. Lặp lại QS2.
l. Thuật toán PickSeeds
Chọn hai phần tử làm phần tử đầu tiên của các nhóm.
- PS1: [Tính toán sự thiếu hiệu quả của việc nhóm các phần tử với nhau]
Cho mỗi cặp các phần tử E1 và E2 , tạo một hình chữ nhật J bao gồm E1I và E2I Tính d = area(J) – area (E1I) - area(E2I).
- PS2: [Chọn cặp gây lãng phí nhất] Chọn cặp có d lớn nhất.
m. Thuật toán PickNext
Chọn một mục còn lại để phân loại vào một nhóm.
- PN1: [Xác định giá trị của việc đặt mỗi phần tử trong mỗi nhóm] Cho
mỗi phần tử E chưa được phân nhóm, tính d1 = diện tích được yêu cầu tăng trong hình chữ nhật bao phủ của nhóm 1 để bao gồm EI, tính toán
d2 tương tự như trên cho nhóm 2.
- PN2: [Tìm phần tử thích hợp nhất cho một nhóm] Chọn bất kỳ phần tử
nào có sự khác biệt lớn nhất giữa d1 và d2.
o. Thuật toán LinearPickSeeds
Chọn hai phần tử làm các phần tử đầu tiên của các nhóm.
- LPS1: [Tìm các hình chữ nhật xa nhất theo tất cả các chiều] Theo mỗi
chiều, tìm các phần tử mà hình chữ nhật của nó có cạnh dưới cao nhất và có cạnh trên thấp nhất. Ghi lại việc phân chia.
- LPS2: [Điều chỉnh hình dạng của cụm hình chữ nhật] Chuẩn hóa việc
phân chia bằng cách chia chiều rộng của toàn bộ các tập theo chiều tương ứng.
- LPS3: [Chọn cặp cách xa nhất] Chọn cặp có sự phân chia được chuẩn
hóa lớn nhất theo bất kỳ chiều nào.
2.2. Các phƣơng pháp lập chỉ mục
Nhiều thập kỷ qua có rất nhiều phương pháp tổ chức dữ liệu không-thời gian được nghiên cứu và phát triển. Phương pháp tổ chức dữ liệu không-thời gian chủ yếu tập trung vào 02 hướng là: (1) lập chỉ mục quá khứ, (2) lập chỉ mục hiện tại và dự đoán tương lai. Trong phần này tôi sẽ tìm hiểu và phân tích một số phương pháp tổ chức dữ liệu dựa trên cấu trúc cơ bản của các phương pháp lập chỉ mục.
2.2.1. Lập chỉ mục quá khứ tiến trình không-thời gian
Dữ liệu lịch sử của đối tượng chuyển động là rất hữu ích trong các ứng dụng như lập kế hoạch và quản lý tài nguyên. Tuy nhiên trong cơ sở như vậy không gian để lưu trữ thông tin vị trí của đối tượng là rất lớn khi đối tượng chuyển động. Do đó vấn đề quyết định là dữ liệu lịch sử nào là tốt nhất và lưu trữ chúng như thế nào để đạt hiệu quả cao.
Trong phần này sẽ mô tả cấu trúc lập chỉ mục của dữ liệu quá khứ từ các tiến trình không-thời gian. Có thể hiểu đơn giản tiến trình là một quá trình mà đối tượng giữ lại các kích thước và vị trí của nó từ thời điểm nó được chèn vào cơ sở dữ liệu đến thời điểm nó bị được xoá khỏi cơ sở dữ liệu. Sự kết thúc và thay đổi của một tiến trình chỉ đơn giản là các đối tượng được bổ sung và xoá khỏi cơ sở dữ liệu.
x x x x x t t1 t2 t3 t4 t5 S(t1) S(t2) S(t3) S(t4) S(t5) y y y y y o2 o2 o2 o2 o3 o3 o3 o3 o1 o1 o1 o1 o1 Query region Q
Hình 2.5. Mô tả tổng quan một tiến trình không-thời gian
Hình 2.5 mô tả một trường hợp thể hiện sự di chuyển của các đối tượng và sự thay đổi như thu nhỏ/mở rộng của các đối tượng trong những điểm thời gian khác nhau. Tuy nhiên trong trường hợp tổng quát sự thay đổi này không xác định được rõ ràng như sự chèn/xóa đối tượng. Xem xét một ví dụ của 1 đối tượng di chuyển từ vị trí A tại thời điểm ti đến một vị trí C trong thời gian kế tiếp ti+1. Cách đơn giản nhất để mô tả cho hành động này là xoá đối tượng từ vị trí A tại thời điểm t
Điều này nó tạo ra 02 bản ghi (record) cho đối tượng: một bản ghi để lưu vị trí A với khoảng thời gian tồn tại (lifetime) kết thúc tại ti+1 và một bản ghi để lưu vị trí C với khoảng thời gian tồn tại bắt đầu tại ti+1. Thời gian tồn tại của đối tượng đã được chia nhỏ thành 2 bản ghi với khoảng thời gian liên tiếp và không chồng chéo. Tuy nhiên, cách tiếp cận này là không hiệu quả nếu đối tượng liên tục thay đổi vị trí hay kích thước của nó theo thời gian dẫn đến việc nó sẽ phải tạo ra số lượng lớn các bản ghi chèn vào cơ sở dữ liệu, dẫn đến không gian lưu trữ lớn.
Có một cách tốt hơn để giải quyết cho việc này là chỉ lưu trữ các hàm mô tả của kích thước hoặc vị trí của các đối tượng di chuyển. Hàm mô tả được sử dụng như các hàm tuyến tính theo thời gian vì các đối tượng có thể thay đổi hay được thu nhỏ/mở rộng theo thời gian. Các bản ghi mới được chèn vào chỉ khi đối tượng có sự thay đổi vị trí hay kích thước của nó. Các bản ghi mới sẽ duy trì thời gian tồn tại của đối tượng dưới một hàm chuyển động/kích thước mới. Trong trường hợp tổng quát số lượng N chèn vào tương