这是一个通用的编程问题,即使代码是用Java编写的。请随时用任何语言回答!
我有一个迭代的对象列表,我想检查它们是否在距离阈值范围内。为了做到这一点,我必须重新遍历整个列表以检查每个对象的距离。我粗略地这样做(伪代码):
for (int i = 0; i < objects.size(); i++) {
for (int j = 0; j < objects.size(); j++) {
if (i == j) {
continue;
}
if (dist(objs[i], objs[j]) < 100) {
// Do something.
}
}
}
有没有办法优化这个?我知道我可以使用距离平方来避免平方根,但我发现它并没有帮助那么多。这是我目前的距离函数:
Math.sqrt(((vector.x-this.x)*(vector.x-this.x)) + ((vector.y-this.y)*(vector.y-this.y)));
如果屏幕底部有一个物体,一个在顶部,它们显然不是彼此靠近,那么它们怎么能互相忽视呢?
谢谢!
答案 0 :(得分:2)
您可以通过一种简单的方法来限制您检查j
的值。如果您已经检查了B点和A点之间的距离,则无需检查A点和B点之间的距离。这应该将支票数量减少一半(作为副作用,您不再需要检查是否{{ 1}})。
i==j
答案 1 :(得分:1)
考虑将对象划分为大小为threshold
x threshold
的单元格(例如,在您的示例中为100x100)。您可以在一次传递中执行此分区(即O(n)),并将其表示为Map<Cell, List<Point>>
(其中Point
是原始对象的类型)。
现在依次查看每个单元格,从左上角到右下角。对于每个单元格,您只需要针对同一单元格或紧邻单元格中的点测试每个点(并且您不需要比较先前比较的单元格,因此在单元格内与单元格进行比较右边和下面的细胞)。在最坏的情况下,你什么都不保存(分区的成本有点小),但如果这些点合理地均匀分布,这平均会减少比较次数。
答案 2 :(得分:0)
@edit我误解了这个问题。在悲观情况下你不能更快地完成它,bcs你可以有满足距离要求的O(n ^ 2)对