R*树:一种高效且健壮的点和矩形访问方法(The R*-tree: an efficient and robust access method for points and rectangles)转载

   
注意:这是转载新浪博客的一篇英文文献翻译,很不错,可惜新浪博客凉凉了,就转到scdn上,下面全是作者的内容,原文链接:http://blog.sina.com.cn/s/blog_672446ba0100uy2f.html
这篇文章发布于1990年。相比R树那篇论文,这一篇要晦涩得多。主要的内容是对R树的改进。
    我原本打算全文翻译的,但是实在是太耗时间了,所以前面翻译的还算比较认真,后面的质量就越来越差了,差不多算是鸟语了。翻译这篇东西花了一周,虽说有我效率太低的原因,可是实在太久了,以后再也不干全文翻译这种事了。现在这个篇幅大概有一万多字,比R树那一篇要完整,主要内容都翻译出来了。

摘要
    R树是最为著名的矩形访问方法(Access method)之一,其算法的基本原理是对中间节点的外接矩形面积进行启发式<* 译者注:其实我不明白什么是启发式,也不明白R树哪里启发式了?*>的优化。我们在一个标准实验平台下对各种数据、各种查询、各种操作进行了大量的实验,并根据实验结果设计了R*树。R*树可以对路径中每个外接矩形的面积、边长(margin)和叠加程度进行综合优化,并将整个路径上所有外界矩形的优化结果合并起来考虑。(原文是incorporates a combined optimization of area, margin and overlap of each enclosing rectangle in the directory)。我们在标准的实验平台下对两种数据结构进行了详细的性能比较,结果证明,与现有的各种R树变种相比,R*树都有明显的性能优势。这里的R树变种包括Guttman的线性R树、二次R树(或者叫平方R树),也包括Greene的R树变种。R*树具有全面的性能优势,不论是针对矩形数据还是针对多维点数据、不论是查询操作还是地图叠加等各种空间操作,R*树的性能优势均有所表现。从实际应用的角度来讲,R*树在下面两个方面对用户有强烈的吸引力:第一,R树不论对点还是其他各种空间数据都能提供有效的支持;第二,R*树的实现代价仅比R树略高。

1、引言
    本文将对复杂的空间对象进行近似,并在此基础上研究空间访问方法(Spatial Access Method,SAMs)。对空间对象的近似是用空间对象的最小外包矩形来表示的,外包矩形的各边与数据空间的各坐标轴平行。这种近似方法比较简单,但它有一个重要的特性,即这种方法可以用少量的字节来代表复杂的空间对象。虽然这种近似方法会导致大量的信息丢失,但空间对象的最小外包矩形仍然保存了对象的一些必要的几何属性,包括空间对象的位置、空间对象在各坐标轴方向的扩展范围。
    <* 译者注:下面这一段没看懂,可能是这样翻译*>从我们列出的参考文献【SK 88】中我们知道,已知的空间访问方法所组织的最小外包矩形是基于一种底层的点访问方法(Point Access Method,PAM),点访问方法使用了下面三种技术中的一种:切割(clipping),转换(transformation),重叠区(overlapping region)。储存矩形的最著名的空间访问方法是R树。按照我们的分类原则,R树的基础是一种点访问方法B+树。B+树使用了重叠区方法<* 译者注:B+树使用了重叠区方法吗?*>,因此R树很容易实现,这种特性有助于R树的普及
    R树算法基于启发式优化,所使用的优化标准(optimization criteria)是:最小化中间节点中的每个外接矩形的面积。这是一种最直接的优化标准,但并没有证据证实这是最佳的优化标准。这种优化标准会带来类似下述的一些疑问:为什么不最小化最小外包矩形的边或者重叠区(而最小化最小外包矩形的面积)?为什么不优化存储空间的利用率?为什么不同时优化上述的所有内容?上述几种标准能不能以一种消极的方式进行交互(interact in a negative way)?只有使用工程学的方法才能找出各种优化原则之间的最佳结合
    采取工程学方法的必要条件是要有一个标准的实验平台,供我们用各种不同的数据、不同的查询、不同的操作来运行大量的实验。我们实现了这样一个标准的实验平台,并使用这个平台来进行性能对照,尤其是对点访问方法进行性能对照。<* 译者注:为什么是对点访问方法进行性能对照呢?另外,原文在这里标了一个参考文献【KSSS 89】*>
    作为我们研究的结果,我们设计了一种新的R树变种,称为R*树,在所有的实验中,R*树表现出的性能都比现有的各R树变种更出色。在很多与现实相近的数据和操作中,R*树所表现出的性能优势是相当可观的。除了常规的点查询、矩形求交、矩形邻接查询(rectangle enclosure query)外,我们还分析了R*树在地图叠加操作时的性能。我们调用了空间链接(Spatial join)操作,因为空间链接是在地理和环境数据库系统中最重要的操作之一。
    本文按如下结构组织:第二章中,我们介绍了R树原则,包括它的优化标准;第三章中,我们介绍了Guttman和Greene提出的R树的几种变种;第四章中,我们详细介绍了我们所涉及的R*树;第五章中,我们说明了R*树与R树各变种进行对比的结果;第六章总结全文。

2、R树的算法原则和可能的优化标准
    R树的结构与B+树类似,它可以完整地存储多维矩形而不需要将其切成若干块,也不需要将其转换为更高维的点。
    在R树的非叶节点中,条目(entry)的存储形式是{cp,Rectangle}。其中,cp是一个指针,指向这个条目对应的子节点在R树中的存储位置;Rectangle是一个最小外包矩形,它是“这个条目对应的子节点中的所有条目的矩形”的最小外包矩形。叶节点中条目的存储形式是{Oid,Rectangle},其中Oid指向数据库中的一条记录,描述了一个空间对象;Rectangle是这个空间对象的外接矩形。另外,叶节点中条目也可能以这种形式存储:{dataobject,Rectangle},<* 作者注:这可能意味着R树直接保存空间对象,而不是与另外的一个数据库向连*>。后一种存储方式的基本结构与前一种类似。下文主要讨论前一种存储方式。
    记M是一个节点中条目数的上限,规定一个参数m作为节点中条目数的下限,要求2 <= m <= M/2。则R树具有如下性质:
# 根节点如果不是叶节点,那它至少有两个子节点
# 一个非叶节点如果不是根节点,那它的子节点数都介于m与M之间
# 一个叶节点如果不是根节点,那他包含的条目数介于m与M之间
# 所有的叶子节点都在同一层
    R树、R*树都是完全动态的,插入、删除操作可以与查询操作混合进行,而且不需要进行定期的全局重建。很显然,这种结构允许不同子树的最小外包矩形发生重叠,因此这种结构在进行精确匹配搜索(exact match query)的时候会产生多条搜索路径。对于这个问题可以参看参考文献【Gut 84】。稍后本文将会论证上述允许重叠区域的技术并不一定导致较差的平均检索性能。另外,本文引入一个术语“路径矩形”(Directory Rectangle),其几何含义是“包围若干下级矩形的最小外包矩形”。(原文是which is geometrically the minimum bounding rectangle of the underlying rectangles).
    R树主要是下面这个问题。对给定的任意一组矩形,将其分为若干个子集,每个子集中的矩形数介于m与M之间,然后对子集动态建立外包盒,要求这样建成的R树应当能高效地支持任意大的查询矩形提出的任意一种检索操作。现在已经知道,能够影响检索性能的参数有很多个,且这些参数间会以一种复杂的方式相互影响。因此,对任意一个参数的优化都有可能对其他参数造成影响,从而使得R树的整体性能发生恶化。此外,由于每个最终记录的矩形(原文是data rectangle)会有不同的大小和形状、路径矩形会动态地变大和缩小,所以很难确定对某个参数进行的某种优化是否真的能够成功。因此,我们使用了基于大量不同实验的启发式解决方法来解决这个问题。上述的大量不同实验是在一个系统化的框架中完成的。
    本章将讨论与检索性能有密切关系的几个参数。此外,本章还会分析这几个参数间的相互依存关系、个参数的优化标准
    原则O1:路径矩形所覆盖的面积应该最小化。也就是说,被最小外包矩形所覆盖、但是没有被其下级矩形(原文是enclosed Rectangle)所覆盖的区域,不妨称之为“死空间(dead space)”,应当最小化。考虑到在进行空间操作的时候,我们需要决定树里的哪些路径要被遍历,而最小化的路径矩形覆盖面积可以令我们在树的较高层次忽略掉不需要遍历的路径,因此这一操作有助于提升性能。
    原则O2:不同路径间矩形的重叠应当最小化。这个操作也可以减少需要被遍历的路径数目。
    原则O3:路径矩形的边长应当最小化。这里所谓的边长是指矩形的所有边或棱的长度之和<* 译者注:含义类似于周长*>。面积确定的情况下边长最小的形状是正方形。因此如果最小化边长而不是最小化面积,将会是路径矩形更接近正方形。如果查询矩形是较大的正方形,那么最小化的边长可以提供较高性能(这句话原文是Essentially queries with large quadratic query rectangles will profit from this optimization)。更重要的是,最小化边长可以在根本上改善树的结构。正方形更容易被包围,因此如果某层的外包盒更接近正方形,那么其上一层的路径矩形就会相对较小。因此如果按照各边的长度的方差来给矩形分组,将边的方差较小的分为一组并构建外包盒,则这种分组方法可以减少路径矩形的面积。(这句话的原文是Thus clustering rectangles into bounding boxes with only little variance of the lengths of the edges will reduce the area of directory rectangle)
    原则O4:存储时的空间利用率应当优化。较高的存储空间利用率可以令树的高度保持较低,所以通常会减低查询成本。有证据表明,查询矩形越大受这个参数的影响就越大,因为如果检索涉及的结果有很多,那么每个节点中的矩形数目就会对检索性能产生较大影响。(这句话原文是这样的:Evidently, query types with large query rectangles are influenced more since the concentration of rectangles in several nodes will have a stronger effect if the number of found keys is high)。
    如果要令路径矩形的面积和互相之间的重叠面积较小,就需要减小对节点中矩形存储数目的限制,因此最小化这两个参数会导致较低的存储效率。另外,如果要做到O1或者O2,就需要以更自由的方法选择每个矩形的分组,而这将导致上层矩形的形状变得不像正方形。如果要做到O1,那么路径矩形间的重叠就会增加,因为这会降低数据空间的覆盖程度。<* 译者注:我没有理解这句话的逻辑,那个原则导致什么降低了?原文是the overlap between directory rectangles may be affected in a positive way since the covering of the data space is reduced*>。至于对几何形状的优化,如果要最小化边长,就会降低存储效率。然而,由于接近正方形的路径矩形更容易包围起来(packing better),所以这容易保证较高的存储效率<* 译者注:这是什么逻辑?*>显然,对于一个充分大的查询矩形来说,存储效率对性能的影响另外三个参数O1-O3的影响大得多。

3、R树的变种
    R树是一种动态的结构。因此所有优化检索性能的方法都是在插入新的数据矩形的时候实施的。插入算法会调用另外两个算法,在这两个算法中一些关键的决策能保证较高的检索性能。这两个算法分别是算法ChooseSubTree和算法Split。算法ChooseSubtree从根开始运算,向下一直检索至叶节点,在每一层都选择最适合容纳新条目的子树。如果算法ChooseSubtree最终找到的节点已经保存了M个条目,不能再插入更多条目了,则调用算法Split。算法Split会用最适当的方法把M+1个条目分配到两个节点当中去。
    下面我们将分析和讨论现有的各种R树变种提出算法ChooseSubtree和算法Split。首先考虑Guttman提出的最普通的R树。

——————————————
算法ChooseSubtree
步骤CS1:记N为根节点
步骤CS2:如果N是叶节点则返回N,否则选择N中最适合插入新数据的条目,选择标准是当插入新数据时,相应矩形的面积增加最小。如果某两个条目插入新数据后面积增加程度相等,则选择其中面积较小的那个。
步骤CS3:将N置为步骤CS2中选出的条目所指向的那个节点,返回步骤CS2继续运算
——————————————

    很明显,这种优化方法是试图最小化路径矩形的覆盖面积,也就是前述的原则O1。这个操作可能还会降低矩形间的重叠,对CPU的消耗也相对较低。
    Guttman讨论了三种Split算法,其时间复杂度分别与节点中的条目数成指数、平方、线性关系。三种算法的设计原则都是减小分裂后产生的两个矩形的覆盖面积。指数分裂算法可以得出面积最小的分裂结果,但是会消耗过多的CPU时间。其他的两个算法都是试图得出近似最优的结果。在Guttman的实验中,线性分裂算法的结果与平方分裂算法的结果表现出了相近的检索性能。我们也实现了基于线性分裂算法的R树和基于平方分裂算法的R树,但是我们用不同分布、不同叠加状况、不同的M和m、不同数目的数据记录进行了大量测试后认为,基于平方分裂的R树产生了更好的性能。本文第5章详细列出了测试结果。基于我们的实验结果,本文仅详细讨论平方分裂算法。

—————————————–
算法QuadraticSplit:把M+1个条目分成两组
步骤QS1:调用算法PickSeeds选择两个条目,分别作为两组的第一个条目
步骤QS2:循环调用算法DistributeEntry,直至所有的条目都已经被分配到某一组、或者某一组已经有了M-m+1个条目
步骤QS3:如果还有余下的条目,则将其全部放入条目较少的那个组里,以保证这个组里的条目数大于下限m
——————————————
算法PickSeeds
步骤PS1:对于每一对条目E1和E2,生成其最小包围矩形R,计算d = area(R) – area(E1.Rectangle) – area(E2.reactangle)。
步骤PS2:选择得出的D最大的那一组E1和E2
——————————————
算法DistributeEntry:
步骤DE1:调用算法PickNext选择一个要被分配的条目
步骤DE2:将选出的条目插入一个组中,选择组的原则是加入这个条目后外包矩形的面积增加较小。如果插入新条目后两个组外包矩形的面积相当,则选择插入外包矩形面积较小的那个组里。若两个组的面积也相当,则插入条目较少的那个组里
——————————————
算法PickNext:
步骤PN1:对于尚未分组的每个条目E,计算d1 = 当把E插入第一组时外包矩形面积增加的程度,d2 = 插入第二组时外包矩形面积增加的程度
步骤PN2:返回d1和d2面积之差的绝对值最大的那个条目
——————————————

    算法PickSeeds把如果放在一起会产生最多面积浪费的两个矩形选出来。在这种情况下(原文是In this sense,没有说明是什么情况)两个距离最远的矩形会被选出来。值得一提的是,如果需要被分裂的矩形大小差距很大或者它们之间有大量重叠,那选出来的种子(seeds)通常是面积较小的矩形。算法DistributeEntry把剩余的条目根据“面积最小”的标准进行分配。算法PickNext选择在相应情况下对面积影响最大的条目(entry with the best area-goodness-value)。
    这套算法中,如果算法PickSeeds选出的是较小的种子,就有可能产生问题。如果有一个d维矩形,它在d-1维里与种子相距很远,但是在剩下的那一维里与种子的坐标很接近,那么这个矩形将优先被分配到相应的种子那一组里。这种插入导致的“面条形”外包矩形的面积增加会很小,但这个矩形的长度很长。这会导致糟糕的分裂结果<*。 译者注:这显然是因为算法只考虑了面积,没有考虑其他因素 *>。另外,算法倾向于把第一个+ 1个待分配的矩形与第一个个待分配的矩形放入同一个种子中。这个因为当第一个矩形放入某种种子后,种子的外包矩形就会变大,那么再放入下一个条目的时候外包矩形的面积增加幅度可能相对较小。这种恶性循环有可能一直进行。另一个问题 是,如果一个组中保存的条目数到达上限M-M + 1,那么剩下的条目不管其形状如何都会被分配到另外一个组里。第4.3节的图1 <* 图略,下同 * >显示的例子显示了上述的所有问题。这些问题可能使分裂的结果又较大的重叠,也可能使条目的分配不均匀,而后者会降低存储效率。
    我们用基于平方分裂算法的ř树测试了不同的米值,米值分别为中号值的20%,30%,35%,40%,45%。结果表明当米是中号的40%时检索性能最好。
    在比较 - [R树与其他保存矩形的数据结构的时候,格林提出了下面这个替代的分裂算法。为了选择插入新条目的最佳路径,他使用了古特曼的算法ChooseSubtree。

--------------
算法GreeneSplit:把M + 1个条目分为两组
步骤DS1:调用算法ChooseAxis,以决定接下来的分裂操作要与哪个轴垂直
步骤DS2:调用算法分配
--------------
算法ChooseAxis:
步骤CA1:调用PickSeeds(见第5页

测试使用了六个数据文件,包含大概10万个2维矩形。矩形坐标在0到1之间。数据文件的性质用下面几个参数来表示。第一,矩形中心的分布情况。第二, N,矩形数。第三,μ,矩形的平均面积第四,NV。

σ/μ,其中σ表示面积的方差,NV表示面积的标准差.NV与分布无关,矩形的面积与平均面积的差距越大则NV越大,原文还说了依据,NV可以表示平均的重叠面积。

    下面罗列了F1至F6一共六套数据。
    测试使用了三种方式。第一,矩形相交查询,给定一个矩形,要求返回与其相交的所有矩形。第二,点查询,给定一个点,要求返回所有包含这个点的矩形。第三,包含查询,给定一个矩形,要求返回所有包含这个矩形的矩形。
    测试了每次查询需要的磁盘访问次数,为了测试建立树算法的性能还测试了每次插入算法的磁盘访问次数,树建立完成后的存储效率。另外,用空间链接(Spatial Join)操作代表叠加操作进行了测试。对于空间链接的定义是,如果文件甲中的一个记录与文件乙中的记录相交,则返回一个空间链接结果。对于空间链接结果,测试其每次操作的磁盘访问次数。
5.2,对结果的分析
    R *树性能显然更好
第一,R *树最为健壮。这里的健壮指的是它比其他各种ř树变种的各方面性能都要好。
第二,R *树在使用较小的查询矩形的时候性能更好,这是因为随着查询矩形面积变大,存储效率的影响会变大。
第三,在进行查询的时候,R *树的性能是线性ř树的400%,是格林的ř树变种的200%,是平方ř树的180%。
第四,跟预期的相同,R *树的存储效率最好。
第五,令人惊奇的是,虽然使用了强制插入的方法,但是平均插入时间不仅没有提高,还有所降低
第六,空间链接操作获得的性能提升比其他查询获得的性能提升要高。对空间链接操作,R *树比平方ř树高出147%,比格林的ř树高出171%,比线性ř树高出261%。
5.3,一种高效的点访问方法
    这一节的主要内容是测试R *树对于访问点数据的性能。之前的访问都是矩形数据。
    仍然测试存储效率,插入时间消耗,查询时间消耗。
    结果表明R *树对于访问点的性能提升比访问矩形的性能提升更好.R *树甚至比双层四叉树(是不是这个意思?原文2-level grid)性能更好。双层四叉树仅在插入操作方面的性能更好,因此看起来它更适合需要经常插入的情景。

6,总结
    实验表明,本文所提出的R *树不论是访问数据库中的多维点还是多维空间数据都有很好的效果。在所有的实验里,R *树的性能都比其他ř树变种高。对于点数据的访问,性能提升更明显.R *树甚至于比双层四叉树更好。
    R *树主要是考虑降低面积,边长,路径矩形的重叠。因为综合考虑了三者,R *树即使面对分布非常不规则的数据时也表现得十分稳定。又由于强制插入算法的使用,避免了不必要的分裂,R *树得到了动态的重构,存储效率得到了提升.R *的实现代价仅比ř树的实现代价稍高

   
在接下来的工作中,我们将研究,如果是参考文献【SK90】所述的那样使用前缀< 原文是前缀,是什么意思? >或者使用格网逼近(grid
近似值),能不能提高删除。也会继续改善R *树,使其能更有效的管理多边形。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值