R-树相关技术

空间索引是对存储在介质上的数据位置信息的描述,用来提高系统对数据获取的效率。GIS涉及的各种海量复杂数据存储于外存,如果对磁盘上的数据的位置不加以记录和组织,每查询一个数据项都要扫描整个数据文件,则这种访问磁盘的代价将严重影响系统的效率。因此索引的建立与处理至关重要。此外GIS所表现的地理数据多维性使得传统的B树索引不再适合,因为B树所针对的字符、数字等传统数据类型是在一个良序集之中,即都是在一个维度上,集合中任给两个元素,都可以在这个维度上确定其关系只可能是大于、小于、等于三种,若对多个字段进行索引,必须指定各个字段的优先级形成一个组合字段,而地理数据的多维性,在任何方向上并不存在优先级问题,因此B树并不能对地理数据进行有效的索引,所以需要研究特殊的能适应多维特性的空间索引方式。

1984年Guttman发表了《R树:一种空间查询的动态索引结构》[1]一种高度平衡树,由中间节点和叶节点组成,实际数据对象的最小外接矩形存储在叶节点中,中间节点通过聚集其低层节点的外接矩形形成,包含所有这些外接矩形。其后,人们在此基础上针对不同空间运算提出了不同改进,才形成了一个繁荣的索引树族,是目前流行的空间索引。

R树是一种采用对象界定技术的高度平衡树,是B 树在 k 维空间上的自然扩展,它将空间对象按范围划分,每个结点都对应一个区域和一个磁盘页,非叶结点的磁盘页中存储其所有子结点的区域范围,非叶结点的所有子结点的区域都落在它的区域范围之内;叶结点的磁盘页中存储其区域范围之内的所有空间对象的外接矩形。每个结点所能拥有的子结点数目有上、下限,下限保证对磁盘空间的有效利用,上限保证每个结点对应一个磁盘页,当插入新的结点导致某结点要求的空间大于一个磁盘页时,该结点一分为二。R树是一种动态索引结构,即:它的查询可与插入或删除同时进行,而且不需要定期地对树结构进行重新组织。

R-Tree数据结构

(1)R-Tree是n叉树,n称为R-Tree的扇(fan)

(2)每个结点对应一个矩形。

(3)叶子结点上包含了小于等于n的对象,其对应的矩为所有对象的外包矩形。

(4)非叶结点的矩形为所有子结点矩形的外包矩形。

R-tree具有以下性质:

(1)除根节点外,每个节点的项数介于最小项数m和最大项数M之间;

(2)根节点至少有两个孩子,除非它是叶子节点;

(3)所有叶子节点位于同一层;

(4)同一节点中项,其排列没有顺序要求

R-Tree的的评价标准为:

(1)位置上相邻的结点尽量在树中聚集为一个父结点。

(2)同一层中各兄弟结点相交部分比例尽量小。

R树是一种用于处理多维数据的数据结构,用来访问二维或者更高维区域对象组成的空间数据.R树是一棵平衡树。树上有两类结点:叶子结点和非叶子结点。每一个结点由若干个索引项构成。对于叶子结点,索引项形如(Index,Obj_ID)。其中,Index表示包围空间数据对象的最小外接矩形MBR,Obj_ID标识一个空间数据对象。对于一个非叶子结点,它的索引项形如(Index,Child_Pointer)。 Child_Pointer指向该结点的子结点。Index仍指一个矩形区域,该矩形区域包围了子结点上所有索引项MBR的最小矩形区域。一棵R树的如图1所示。

 

 

R-Tree算法描述

(I)插入算法

     基本思想:找到合适的叶子节点,插入之,若需分裂,则由下至上调整MBR值。算法如下:

     I1: 调用ChooseLeaf来选择一个合适的叶子节点L以容纳需插入项E

     I2: 若L中还能容纳E,则加入之;否则调用SplitNode来获取两个节点L和LL,它们包含E和L中原有的所有项

     I3: 调用AdjustTree,传递参数L,LL(若产生了分裂)

     I4: 若节点分裂向上传播导致根节点的分裂,则生成新的根节点。

算法ChooseLeaf: 选择一个合适的叶子节点以放置新项E。合适的评价标准是插入E后的节点MBR面积增加度最少。

     C1: 设N指向根结点root

     C2: 若N是叶子节点,返回N   

     C3: 若N不是叶子节点,让F表示N中的一项,该项F容纳E后,则N在面积上只需作面积最小扩展

     C4: 设N指向叶子节点,则返回C2.

算法AdjustTree: 从叶子节点向根节点进行调整

     A1: 设N=L,若L进行了分裂,则设NN=LL

     A2: 若N为根节点,则返回

     A3: 设P为N的双亲节点,EN为节点P中指向N的项,调整项EN的MBR

     A4: 若NN存在,创建一个新项ENN,使其指向NN,同时计算出ENN的MBR.将ENN加入P,若不能容纳则调用SplitNode产生节点P和PP,包含ENN和原来P中所有项

     A5: 设N=P, NN=PP, 转至A2.

算法SplitNode: 将M+1项分成两组,将它们加入到两个新节点。

判断节点分裂好坏的一个标准为:分裂后,两个新节点对应的MBR的面积之和最小。下图展示了节点分裂的一个例子。

一个时间复杂度为二次(Quadratic)的分裂算法如下:

      S1: 调用PickSeeds选出两项,将它们分别作为两组的第一个元素;

      S2: 若所有项都已分配完,则返回;若一组中的项如此之少,以至于将剩下的所有项添至其中才能满足项数达到m的要求,则进行分配且返回;

      S3: 调用PickNext选择下一项,将其分配到某组中,该组在容纳该项后,MBR只需作最小面积扩展,转至S2.

算法PickSeeds:

      PS1: 对每一项E1和E2,计算d=area(E1和E2合并之后的MBR) – area(E1) – area(E2);

      PS2:选择d值最大的一对项。

算法PickNext:

      PN1:对每一项E,计算d1=<将E加入组1后MBR增加的面积>,同理计算d2;

      PN2:选出d1和d2值差距最大的项。

(2)R-tree删除算法

算法DeleteEntry E)从R-tree中删除项E

D1:调用FindLeaf来寻找存放E的叶子结点L ;若没有找到则停止;

D2:从L中删去E;

D3:调用CondenseTree,传递参数L :

D4::若根结点只有一个孩子,则让该孩子结点成为新根节点。

算法FindLeaf (NODE  T,  Entry  E )

FL1:若T不是叶子结点,则对于T中每一个与E相重叠的项,将该项所指的结点作参数,递归调用FindLeaf 

FL2:若T是叶子结点,则检查T中是否有与E相等的项,若有,则返回T

算法CondenseTree :传递参数结点L ,该结点进行了删除项的操作

CT1:设N=L ,将存储被删结点的集合Q置为空;

CT2:若N是根,转至CT6;否则,设P为N的父节点,EN为P中指向N的项;

CT3:若N中的项数小于m,在P中删除EN,并把N加入到集合Q中;

CT4:若N没有被删除,调整EN的MBR;

CT5:设N=P,转向CT2;

CT6:重新插入集合Q中所有节点中的所有项,对于叶子节点中的项仍插入到叶子节点

中,但对于中间节点的项需要插入到其原来所在的那一层。

R树主要变体

R树最初由Guttman于1984年提出,其后,人们在此基础上针对不同的空间操作需求提出了各种改进方案。经过二十多年的发展,不断产生的R树变体逐渐形成了一个枝繁叶茂的空间索引R树家族。

1 R+树[2]

在Guttman的工作的基础上,许多R树的变种被开发出来, Sellis等提出了R+树[10],R+树与R树类似,主要区别在于R+树中兄弟结点对应的空间区域无重叠,这样划分空间消除了R树因允许结点间的重叠而产生的“死区域”(一个结点内不含本结点数据的空白区域),减少了无效查询数,从而大大提高空间索引的效率,但对于插入、删除空间对象的操作,则由于操作要保证空间区域无重叠而效率降低。同时R+树对跨区域的空间物体的数据的存储是有冗余的,而且随着数据库中数据的增多,冗余信息会不断增长。

2 R*树[3]

在1990年,Beckman和Kriegel提出了最佳动态R树的变种——R*树[11]。R*树和R树一样允许矩形的重叠,但在构造算法R*树不仅考虑了索引空间的“面积”,而且还考虑了索引空间的重叠。该方法对结点的插入、分裂算法进行了改进,并采用“强制重新插入”的方法使树的结构得到优化。但R*树算法仍然不能有效地降低空间的重叠程度,尤其是在数据量较大、空间维数增加时表现的更为明显。R*树无法处理维数高于20的情况。

发布了64 篇原创文章 · 获赞 64 · 访问量 23万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章