每 n 次优化时的距离检查
Distance check at every nth optimization
虽然代码在 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)));
如果屏幕底部有一个物体,屏幕顶部有一个物体,它们显然彼此不靠近,怎么会忽略彼此呢?
谢谢!
@edit 我误解了这个问题。在悲观的情况下你不能做得更快,因为你可以有 O(n^2) 对满足距离要求
优化它的一个简单方法是限制您检查的 j
的值。如果您已经检查了 B 点和 A 点之间的距离,则无需检查 A 点和 B 点之间的距离。这应该将检查次数减少一半(作为副作用,您不再需要检查 i==j
).
for (int i = 0; i < objects.size(); i++) {
for (int j = i+1; j < objects.size(); j++) {
if (dist(objs[i], objs[j]) < 100) {
// Do something.
}
}
}
考虑将对象划分为大小为 threshold
xthreshold
的单元格(例如,您的示例中为 100x100)。您可以一次性执行此分区(即 O(n)),并将其表示为 Map<Cell, List<Point>>
(其中 Point
是原始对象的类型)。
现在依次查看每个单元格,从左上角到右下角,按行。对于每个单元格,您只需要针对同一单元格或紧邻单元格中的点测试每个点(并且您不需要比较之前比较过的单元格,因此在单元格内进行比较,并与单元格进行比较右侧,以及下方的单元格)。在最坏的情况下,您什么都不会节省(并且进行分区会花费一点点),但如果点合理均匀分布,这将平均减少比较次数。
虽然代码在 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)));
如果屏幕底部有一个物体,屏幕顶部有一个物体,它们显然彼此不靠近,怎么会忽略彼此呢?
谢谢!
@edit 我误解了这个问题。在悲观的情况下你不能做得更快,因为你可以有 O(n^2) 对满足距离要求
优化它的一个简单方法是限制您检查的 j
的值。如果您已经检查了 B 点和 A 点之间的距离,则无需检查 A 点和 B 点之间的距离。这应该将检查次数减少一半(作为副作用,您不再需要检查 i==j
).
for (int i = 0; i < objects.size(); i++) {
for (int j = i+1; j < objects.size(); j++) {
if (dist(objs[i], objs[j]) < 100) {
// Do something.
}
}
}
考虑将对象划分为大小为 threshold
xthreshold
的单元格(例如,您的示例中为 100x100)。您可以一次性执行此分区(即 O(n)),并将其表示为 Map<Cell, List<Point>>
(其中 Point
是原始对象的类型)。
现在依次查看每个单元格,从左上角到右下角,按行。对于每个单元格,您只需要针对同一单元格或紧邻单元格中的点测试每个点(并且您不需要比较之前比较过的单元格,因此在单元格内进行比较,并与单元格进行比较右侧,以及下方的单元格)。在最坏的情况下,您什么都不会节省(并且进行分区会花费一点点),但如果点合理均匀分布,这将平均减少比较次数。