在 KD 树中搜索速度慢
我正在实现一个 KD 树来将地图上的点聚类成组。我一直在使用 Wikipedia 的 KD-tree 文章 作为参考。搜索返回正确的最近邻点,但比我预期的要慢。这是我的代码:
- (FDRKDTree *)nnSearchForPoint:(id <MKAnnotation>)point best:(FDRKDTree *)best {
// consider the current node
distToPoint = [self distanceBetweenAnnotations:self.location and:point];
if (distToPoint < best.distToPoint) {
best = self;
}
// search near branch
int axis = depth % 2;
FDRKDTree *child = nil;
if (axis) {
if (point.coordinate.latitude > location.coordinate.latitude)
child = rightChild;
else
child = leftChild;
} else {
if (point.coordinate.longitude > location.coordinate.longitude)
child = rightChild;
else
child = leftChild;
}
if (child != nil)
best = [child nnSearchForPoint:point best:best];
child = nil;
//search the away branch - maybe
if (axis) {
if (fabs(point.coordinate.latitude - self.location.coordinate.latitude) <
best.distToPoint) {
if (point.coordinate.latitude > location.coordinate.latitude)
child = leftChild;
else
child = rightChild;
}
} else {
if (fabs(point.coordinate.longitude - self.location.coordinate.longitude) <
best.distToPoint) {
if (point.coordinate.longitude > location.coordinate.longitude)
child = leftChild;
else
child = rightChild;
}
}
if (child != nil) {
best = [child nnSearchForPoint:point best:best];
}
return best;
}
我的问题是我对“简单比较”的解释,看看搜索点和当前节点的分割坐标之间的差异是否小于从搜索点到当前节点的距离(整体坐标)当前最佳。”是正确的。我将其解释为:
if (fabs(point.coordinate.latitude - self.location.coordinate.latitude)
best.distToPoint)
和
if (fabs(point.坐标.经度 - self.location.坐标.经度)
best.distToPoint)
分别。也欢迎任何其他建议。
谢谢。
I'm implementing a KD-tree to cluster points a map into groups. I've been using Wikipedia's KD-tree article as a reference. The search returns the correct nearest neighbor point, but it is slower than I expected. Here is my code:
- (FDRKDTree *)nnSearchForPoint:(id <MKAnnotation>)point best:(FDRKDTree *)best {
// consider the current node
distToPoint = [self distanceBetweenAnnotations:self.location and:point];
if (distToPoint < best.distToPoint) {
best = self;
}
// search near branch
int axis = depth % 2;
FDRKDTree *child = nil;
if (axis) {
if (point.coordinate.latitude > location.coordinate.latitude)
child = rightChild;
else
child = leftChild;
} else {
if (point.coordinate.longitude > location.coordinate.longitude)
child = rightChild;
else
child = leftChild;
}
if (child != nil)
best = [child nnSearchForPoint:point best:best];
child = nil;
//search the away branch - maybe
if (axis) {
if (fabs(point.coordinate.latitude - self.location.coordinate.latitude) <
best.distToPoint) {
if (point.coordinate.latitude > location.coordinate.latitude)
child = leftChild;
else
child = rightChild;
}
} else {
if (fabs(point.coordinate.longitude - self.location.coordinate.longitude) <
best.distToPoint) {
if (point.coordinate.longitude > location.coordinate.longitude)
child = leftChild;
else
child = rightChild;
}
}
if (child != nil) {
best = [child nnSearchForPoint:point best:best];
}
return best;
}
My question is if my interpretation of "a simple comparison to see whether the difference between the splitting coordinate of the search point and current node is less than the distance (overall coordinates) from the search point to the current best." is correct. What I interpret this as:
if (fabs(point.coordinate.latitude - self.location.coordinate.latitude) <
best.distToPoint)
and
if (fabs(point.coordinate.longitude - self.location.coordinate.longitude) <
best.distToPoint)
respectively. Any other advice is also welcome.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
假设您的
distToPoint
是sqrt((x1-x0)**2+(y1-y0)**2)
,您所做的对我来说看起来相当不错。我用 Python 实现了该算法,这可能有助于交叉检查您的版本并澄清维基百科文章的一些要点:https://gist.github.com/863301
What you've done looks pretty good to me, assuming your
distToPoint
issqrt((x1-x0)**2+(y1-y0)**2)
. I implemented the algorithm in Python which may help to cross-check your version and clarify some of the Wikipedia article points:https://gist.github.com/863301