Ở đây ta sẽ thiết kế ra một chương trình tạo dữ liệu với các đối tượng dàn đều trong không gian hai chiều theo phạm vi [0, 10000] trên mỗi trục. Sau đó mỗi đối tượng được gán một VBR, do đó:
- Trên mỗi một chiều, mức độ vận tốc bằng không (đối tượng là không thay đổi kích thước không gian khi nó chuyển đông).
- Giá trị vận tốc trong khoảng [-50, 50].
- Vận tốc thay đổi tối đa trong mỗi lần cập nhật là 5.
File dữ liệu được tạo ra là một file text chứa các bản ghi của đối tượng. Trong file dữ liệu các đối tượng được tạo ra một cách ngẫu nhiên tại mốc thời gian t0 (bao gồm chỉ mục của đối tượng, mbr, vận tốc, thời điểm của đối tượng). Sau đó tại một mốc thời gian t1, t2, t3,… một số ngẫu nhiên các đối tượng được tạo ra với vận tốc thay đổi.
Các bản ghi có thể được mô tả với kiểu cấu trúc, trong đó Oid là các chỉ mục cho đối tượng, mbr là một mảng với 4 phần tử mô tả vị trí và kích cỡ của đối tượng, vbr (velocity bounding rectangle) là một một mảng với 4 phần tử mô tả mô tả các cạnh của mbr và ref là một giá trị cho thời gian mà ở đó đối tượng được chèn hay được cập nhật.
struct MovingObject
{ int Oid; // chỉ mục đối tượng
float mbr[4]; //vị trí và kích thước của đối tượng float vbr[4]; //Vận tốc của đối tượng trên mỗi hướng.
Bảng 3.1 mô tả ví dụ của 5 đối tượng chuyển động tại thời điểm 0. Cột đầu tiên là chỉ mục của đối tượng, bốn cột tiếp theo tương ứng với trục X và Y (vị trí và kích thước của đối tượng), 4 cột tiếp theo tương ứng với tốc độ của đối tượng và cột cuối cùng là thời điểm hiện tại.
Bảng 3.1. Dữ liệu của một số đối tƣợng chuyển động tại thời điểm hiện tại
Oid X1 X2 Y1 Y2 Vx1 Vx2 Vy1 Vy2 time
0 2108.2 2108.3 8522.5 8522.5 -21.5 -21.5 -13.9 -13.9 0 1 2806.7 2806.7 5814.8 5814.8 -49.8 -49.8 6.8 6.8 0 2 9968.1 9968.1 1870.4 1870.4 34.7 34.7 41.5 41.5 0 3 910.5 910.5 7318.2 7318.2 -3.0 -3.0 -39.8 -39.8 0 4 4271.0 4271.0 4824.4 4824.4 44.9 44.9 -26.4 -26.4 0 3.2. Thiết kế file chỉ mục.
Một file chỉ mục là tập của các khối (trang đĩa), cấu trúc của file bao gồm bao gồm 2 phần.
Phần đầu tiên là tiêu đề block chứa thông tin về cấu trúc của file trên đĩa như thể hiện trong bảng 3.2 và thông tin của TPR-tree trong bảng 3.3.
Phần thứ hai là tập của block dữ hiệu tương ứng với nút trong chỉ mục cây. Mỗi block dữ liệu bao gồm thông tin dữ liệu (block information) và tập của các phần tử dữ liệu (phần tử data). Bảng 3.4 minh họa thông tin của block tương ứng với mức của nút và số các phần tử hiện tại trong block. Bảng 3.5 minh họa một phần tử bởi hình chữ nhật, vận tốc và con trỏ tới một cây con.
Bảng 3.2. Thông tin cấu trúc của file trên đĩa
Data types Data Description
Int Blocklength; // độ dài block
Bảng 3.3. Thông tin của TPR-tree
Data types Data Description
Int Dimension; //số chiều không gian
Int Num_of_data; //số đối tượng chuyển động Int Num_of_dnodes; //số nút lá (leaf node)
Int Num_of_inodes; //số nút trung gian (internal nodes) Int Root; // block chưa nút root
Bool Root_is_data; // false nếu độ sâu ≥ 1
Float T //chiều thời gian (Horizon time)
Float Time //thời gian hiện tại
Bảng 3.4. Thông tin Block
Data types Data Description
Char Level; //cấp của nút
Int Number_entries; // số phần tử trong nút
Bảng 3.5. Thông tin phần tử
Data types Data Description
Float Bounces // tọa độ góc trái và phải
Float Velocity //vận tốc
Int Son // địa chỉ của nút con
3.3. Thiết kế chƣơng trình.
Trong phần này tôi sẽ thiết kế một TPR-tree có nguồn gốc từ cấu trúc của R-tree vì TPR-tree là mở rộng của R-tree. Để làm rõ thiết kế của chương trình tôi trình bày 2 biểu đồ: biểu đồ đầu tiên là biểu đồ lớp minh họa tất cả
lớp và các mối quan hệ của chúng, biểu đồ thứ hai là biểu đồ tuần tự minh họa nhiệm vụ giữa các lớp chính.
3.3.1. Biểu đồ lớp
Bởi vì TPR-tree là mở rộng của R*-tree, do đó kiến trúc của chúng thiết kế tương tự như của R-tree. Như thể hiện trong bảng 3.6, chúng ta có 3 lớp chính: Rtree (tương ứng với cây), RTNode (tương ứng với nút cây),, Phần tử
(tương ứng với các phần tử của nút). Bảng 3.7 minh họa nhiệm vụ chi tiết của mỗi lớp. Để xử lý truy nhập file, lớp BlockFile chứa tất cả các dữ liệu hoạt động xử lý. Mặc dù thử nghiệm của tôi không sử dụng bộ nhớ cache để test, nhưng vẫn thiết kế lớp Cache, trong đó Cacheable là các khối bộ nhớ. Bộ nhớ đệm (cache) giúp tăng hiệu suất truy vấn bằng cách lưu trữ các khối đĩa thường được truy nhập trong bộ nhớ chính. Bên cạnh các lớp chính, các lớp còn lại hỗ trợ hoạt động của R-tree và TPR-tree. Lớp linList, SortedLinList
được sử dụng cho hoạt động xóa và chèn trong việc lưu trữ các phần tử hay các nút bị xóa tạm thời (các phần tử hay các nút này sau đó được chèn vào cây). Các đối tượng Struc được sử dụng như các thành phần dữ liệu của các hoạt động.
Bảng 3.6. Chức năng của các lớp
Class name Description
RTree Lớp chính cho các chỉ mục đối tượng, nó chứa tất cả các chức năng thao tác và truy vấn cho các chỉ mục. RTNode Lớp mức thấp, trong đó xác định một giao diện node-
action để cho phép điều chỉnh thiết kế của nút.
Phần tử Lớp định nghĩa phần tử của đối tượng cũng như thao tác phần tử.
Cache, Cacheable Lớp hỗ trợ cây sử dụng bộ nhớ cache.
CachedBlockfile hay không với bộ nhớ cache. LinList,
SortedLinlist
Lớp danh sách liên kết kép hỗ trợ hoạt động lưu trữ tạm thời trong việc xóa và chèn lại các phần tử.
Linkable, Slink Cấu trúc danh dách liên kết kép để lưu trữ danh sách tạm thời.
Movingobject Một cấu trúc mảng hỗ trợ tất cả các hoạt động của đối tượng chuyển động như chèn, xóa.
TPRsortMBR Một cấu trúc hỗ trợ thuật toán chèn lại để lưu trữ danh sách theo khoảng cách từ tâm của MBR.
a. Class Rtree: là một lớp cơ bản của cây, nó chứa tất cả các chức năng thao
tác và truy vấn của cây. Sử dụng để xây dựng một cây TPR-tree từ một file giả lập được tạo. TPR-tree được xây dựng từ các tập dữ liệu:
dsfname: tên file cần tạo tfname: tên file được tạo b_len: độ dài của block c: bộ nhớ đệm
T: cây được xây dựng trong khoảng [0, T] dimension: chiều
qmbrlen: độ dài của MBR qvbr: độ dài của VBR qst: mốc thời gian bắt đầu qed: mốc thời gian kết thúc
Trong Class Rtree xây dựng một số chức năng chính như:
- Insert (Entry* d): thực hiện chèn một phần tử vào cây TPR-tree. - Load_root: tạo một node root.
- Moving_sect (Entry *_e1, Entry *_e2, float _st, float _ed): phát hiện 2 vùng di chuyển giao nhau.
- Choose_path (Entry *_newe): tìm nút lá khi gia tăng diện tích MBR.
- Check_path (Entry *_newe, float _minpen): kiểm tra đường dẫn nhận được từ choose_path đã thực sự tối ưu chưa.
- Delete_entry (Entry *_olde): xoá phần tử từ cây hiện tại - Update (char *_dsfname, int _update_time): cập nhật lại cây.
b. Class RTnode: dùng để tạo ra nút trên đĩa, tái tạo nút trên đĩa. Trong Class
Rtree xây dựng một số chức năng chính như: - RTNode (RTree *rt): để tạo ra nút trên đĩa
- RTNode (RTree *rt, int _block): tái tạo nút trên đĩa.
- Choose_subtree (Entry *_newe): thực hiện chọn cây con tốt nhất để chèn các phần tử.
- Enter (Entry *d): nhập các phần tử vào nút.
- FindLeaf (Entry *_q): thực hiện tìm các nút lá để chèn các phần tử.
- Get_mbr(): thực hiện khởi tạo mảng và trả lại mbr của nút ở thời gian hiện tại của cây TPR.
- Get_vmbr(): Chức thực hiện khởi tạo mảng và trả lại vbr của nút ở thời gian hiện tại của cây TPR.
- Insert (Entry *d, RTNode **_sn): chèn các phần tử vào nút.
- RangeQuery (Entry *_q, float _st, float _ed, int& _rsltcnt): thực hiện đưa ra kết quả của một truy vấn.
- Get_subtree_num_entries(): đưa ra số phần tử của cây con. - Model_split (RTNode *_new_nd): chức năng chia nút.
- Init_new_entries (int _size): chức năng khởi đầu cho mộ mảng các phần tử - Update_parent_entry (int _pos): cập nhật MBR, VBR tới nút con.
- Past_mbr (float *_mbr, float *_vbr, float _time, int _dim): chức năng điều chỉnh mbr theo vbr ở thời điểm t0.
- Future_mbr (float *_mbr, float *_vbr, float _time, int _dim): chức năng tạo mbr ở khoảng thời gian tương lai.
- Delete_entry (Entry *_olde): xóa phần tử ở cây hiện tại
c. Class Entry: Lớp định nghĩa phần tử của đối tượng cũng như thao tác của
các phần tử. Lớp có một số chức năng sau:
- Enlarge (Entry *_e1, Entry *_e2): chức năng lấp đầy mbr và vbr của phần tử hiện tại.
- Gen_Linkable(): chức năng tạo ra một cấu trúc linkable từ các phần tử. Các đối tượng linkable được sử dụng trong linklist.
3.3.2. Biểu đồ tuần tự
Biểu đồ này mô tả hoạt động tương tác tuần tự giữa các lớp, như là các hoạt động Insert (Phần tử), Delete (Phần tử), RangeQuery. Hình 3.2 liệt kê tất cả các hoạt động chính của mỗi lớp, ví dụ như lớp RTNode chỉ sử dụng hoạt động truy cập đĩa.
Hình 3.2. Biểu đồ tuần tự
Một số thuật toán sử dụng:
AlgorithmInsert (e) /* Input: e là một Entry để thực hiện chèn */
1. Re-insertedi= false for all levels 1 ≤ i ≤ h-1 (h là độ cao của cây) 2. Intialize an entry re-insertion list Lreinsert
3. Invoke ChoosePath to find the leaf node N to insert e 4. Invoke Node Insert (N,e)
5. For each entry e’ in the Lreinsert
6. Invoke ChoosePath to find the leaf node N to insert e’ 7. Invoke Node Insert (N,e)
End Insert
b. Thuật toán chèn một Node.
AlgorithmNode Insert (N, e) /* Input: N là nút để thực hiện chèn entry */
1. If N is a leaf node
2. Enter the information of e 3. If N overflows
4. If Re-inserted= false //no Re-inserted at leaf level yet
5. Invoke Pick Worst to select a set Sworst of entries 6. Remove entries in Sworst from N; add them toLreinsert 7. Re-inserted0=true
8. Else
9. Invoke Node Split to split N into itself anh N’
10.Let P be the parent of N
11.Node Insert (P, Ø) or Node Insert (P, N’) if N has been split
12.Else //N is a non-leaf node
13.Similar to line 2-9 except that (i) the MBR/VBR of the affected child node is adjusted, and (ii) in lines 4,7 replace Re-inserted0 with Re-insertedi where I is the level of N
c. Thuật toán xóa một phần tử từ Node.
AlgorithmDelete (E,N) /* Input: xóa một entry từ nút N */
1. If N is a leaf node
2. Search all entries of N to find E.mbr 3. Else /* N is an internal node
4. Find all entries of N that cver E.mbr
5. Follow the corresponding subtrees until the leaf L that contains E is found 6. Remove E from L
7. Endif
8. Invoke CondenseTree (L) 9. If the root has only one child 10.Remove the root
11.Set as new root its only child 12.Endif
End Delete
3.4. Một số kết quả thử nghiệm chƣơng trình 3.4.1. Form chƣơng trình
Chương trình demo thử nghiệm TPR-tree được viết trên ngôn ngữ C# của Microsoft visual Studio 2008, chạy trên máy tính PC với hệ điều hành Windows. Chương trình thiết kế với một số chức năng chính như sau:
- Form chính của chương trình: bao gồm 3 phần Cấu hình dữ liệu, Tạo cây dữ liệu TPR-Tree và Truy vấn dữ liệu, các quá trình sẽ được thực hiện tuần tự từ việc tạo dữ liệu đến việc truy vấn dữ liệu.
Hình 3.3. Form chính của chƣơng trình
- Cấu hình dữ liệu: trong phần này sử dụng để sinh ra các dữ liệu giả lập của các đối tượng chuyển động, nó tạo ra các file dữ liệu ngẫu nhiên dựa vào các tham số đầu vào như: số lượng đối tượng sẽ tạo, số mốc thời gian, tỷ lệ đối tượng trên khoảng thời gian. Dữ liệu tạo ra được đặt tên và lưu dưới dạng file với đuôi *.data.
Hình 3.4. Form cấu hình dữ liệu
- Tạo cây dữ liệu TPR-tree: trong phần này cây dữ liệu sẽ được tạo ra từ các dữ liệu giả lập, ta sẽ chọn file số liệu từ dữ liệu ngẫu nhiên để tạo lên một cây dữ liệu TPR-tree, sau đó sẽ ghi cây dữ liệu dưới dạng file *.tpr (file Index). Kết quả của việc tạo cây sẽ đưa ra các thông số liên quan đến việc tạo cây như: Cost of update, Node Internal, Node data, Data.
Hình 3.5. Form tạo cây Rtree
- Truy vấn dữ liệu: trong phần này dữ liệu sẽ được truy vấn dựa trên các file index, ta sẽ chọn file để thực hiện các truy vấn. Dữ liệu đầu vào truy vấn là số lần thực hiện truy vấn, khoảng thời gian truy vấn, giá trị MBR cần truy vấn và giá trị VBR cần truy vấn.
Hình 3.6. Form truy vấn dữ liệu
Kết quả của việc truy vấn sẽ được đưa ra màn hình bên phải với các thông số về: giá trị nút đi qua sau mỗi lần truy vấn, Avg data entries (trung bình số đối tượng tìm được trong tương lai), Avg node accesses (trung bình số nút đi qua để có kết quả).
Hình 3.7. Form kết quả nhận đƣợc sau khi truy vấn
3.4.2. Thử nghiệm
Quá trình thử nghiệm là thực hiện trên cây TPR-tree, mục tiêu của quá trình thử nghiệm là so sánh việc kết quả đạt được khi thực hiện truy vấn các mốc thời gian trong tương lai với các khối lượng dữ liệu khác nhau. Giả định rằng các đối tượng di chuyển là tương tự nhau tại mỗi mốc thời gian truy vấn. Mỗi một truy vấn gồm ba tham số truy vấn: Kính thước không gian của đối tượng (qrlen), vận tốc của đối tượng trên một chiều (qvlen) và khoảng thời gian truy vấn (qTlen). Trong thử nghiệm này sẽ test phạm vi truy vấn qrlen là [100, 100], qvlen là {-10, 10, -10, 10}, và khoảng thời gian qTlen từ [0, T]. Việc test sẽ thực hiện truy vấn ngẫu nhiên 100 lần sau đó lấu giá trị trung bình của mỗi lần truy vấn. Lưu ý rằng các truy vấn ở đây đều có kích thước, vectơ vận tốc và theo khoảng thời gian nghĩa là bản thân các truy vấn cũng là các cửa sổ chuyển động.
Bảng 3.7 mô tả giá trị đạt được trong tương lai khi thực hiện truy vấn tại những khoảng thời gian khác nhau 10, 20, 30, 40, 50 với khối lượng dữ liệu là 10000 (10k) đối tượng.
Bảng 3.8 mô tả giá trị đạt được trong tương lai khi thực hiện truy vấn tại những khoảng thời gian khác nhau 10, 20, 30, 40, 50 với khối lượng dữ liệu là 30000 (30k) đối tượng.
Bảng 3.9 mô tả giá trị đạt được trong tương lai khi thực hiện truy vấn tại những khoảng thời gian khác nhau 10, 20, 30, 40, 50 với khối lượng dữ liệu là 50000 (50k) đối tượng.
Trong các bảng dữ liệu, cột 1 thể hiện độ dài của khoảng thời gian truy vấn (T size), cột 2 thể hiện giá trị trung bình của số đối tượng tìm được trong tương lai (Avg data entries), cột 3 thể hiện giá trị trung bình của số nút đi qua để có kết quả (Avg node accesses), cột 4 thể hiện số nút trung gian (Internal nodes), cột 5 thể hiện số nút dữ liệu (Data nodes).
Bảng 3.7. TRP-tree tại khoảng thời gian khác nhau với 10k
T size Avg data
retrieves
Avg Node access
Internal
node Data node Data
10 7,81 23,44 34 532 10000
20 17,27 33,59 33 526 10000
30 28,00 44,20 33 553 10000
40 41,80 54,90 32 525 10000
50 56,37 67,09 32 525 10000
Bảng 3.8. TRP-tree tại khoảng thời gian khác nhau với 30k
T size Avg data
retrieves
Avg Node access
Internal
node Data node Data
10 23,31 42,13 96 1609 30000
20 51,73 62,43 95 1648 30000
30 88,18 87,03 95 1621 30000
40 127,13 113,32 94 1604 30000
Bảng 3.9. TRP-tree tại khoảng thời gian khác nhau với 50k