R*-Tree 通过边界框索引任意几何对象。在您的情况下,由于您只有点,因此边界框的最小值和最大值是相同的。每个 R*-Tree 都有一个类似 rtree.add_element(object, boundingbox) 的函数。 object 将是数据点的索引,boundingbox 将如上所述。
连接点是 DBSCAN 的regionQuery 部分。数据点 p 的 regionQuery(p) 返回所有满足 euclideanDistance(p,q) ≤ ε(参数ε值由用户提供)。
天真地,您可以计算所有数据点到 p 的距离,这需要 O(n) 时间来获取一个数据点,从而查询所有 n 数据点需要 o(n²) 时间。或者,您可以预先计算一个矩阵,该矩阵包含所有数据点之间的欧几里德距离。然后这需要 O(n²) 的空间,而 regionQuery 只需在该矩阵中查找一个点。
R*-Tree 使您能够在 O(log n) 时间内查找坐标范围内的数据点。然而,R*-Tree 只允许查询形式为
"所有点,其中:[0.3 ; 0.5] 中的坐标 1 和 [0.8 ; 1.0] 中的坐标 2"
而不是
"所有点 q 其中:euclideanDistance(p,q) ≤ ε"
因此,您在 R*-Tree 中查询每个坐标是 p±ε 的相应坐标的点,然后计算所有匹配点到查询点 p 的欧式距离。但是,不同之处在于,与计算 p 到 all 点的欧几里德距离相比,要检查的点要少得多。因此,您的一个 regionQuery 的时间复杂度现在是 O(log n * m),其中 m 是您的 R 返回的点数*-树。如果你选择 ε 小,你会从你的 R*-tree 中得到很少的匹配点,并且 m 会很小。因此,对于一个 regionQuery,您的时间复杂度接近 O(log n),因此对于每个 regionQuery,您的时间复杂度接近 O(n * log n)数据点。在另一个极端,如果您选择的 ε 太大以至于它将包含您的大部分数据点,m 将接近 n,因此,每个 regionQuery 所需的时间数据点再次接近 O(n * log n * n) = O(n² * log n ),因此,与天真的方法相比,您一无所获。
因此,至关重要的是选择足够小的 ε,以使每个点在 ε 的欧几里德距离内只有几个其他点。