【问题标题】:Optimization of Rectangle-based Point Search基于矩形的点搜索优化
【发布时间】:2015-01-21 00:19:36
【问题描述】:

我有一组房间和通道,我可以将它们转换为矩形 (x,y,width,height) 或点列表 (x,y)。 RoomPassage 都扩展了 Pointable 接口。为 Room 类实现 getPoints() 方法

public Set<Point> getPoints() {
    Set<Point> array = new HashSet<Point>();
    for (int i = 0; i < width; i++) {
        for (int j = 0; j < height; j++) {
            array.add(new Point(x + i, y + j));
        }
    }
    return array;
}


问题:
我必须识别给定Point 所属的Pointable。没有房间相交。我最初使用HashMap&lt;Point,Pointable&gt; 将每个Point 关联到Pointable,它能够在O(n) 时间内快速访问答案。但是,现在需要在一个关卡的生成中多次重新计算HashMap

此时使用HashMap是不是更高效(考虑到生成和访问) 还是应该使用其他方法,例如一组二维区间树?

【问题讨论】:

  • 您也许可以为此实现R-Tree
  • R-Tree 的唯一问题可能是通道过长,这会增加矩形的大小并降低效率。

标签: java search optimization hashmap interval-tree


【解决方案1】:

此时,是使用 HashMap 更高效(考虑到生成和访问)还是应该使用其他方法,例如一组 2-D 区间树?

除了进行测量的人之外,没有人能说出来。这完全取决于您需要多久更新一次数据、多久更改一次以及多久查询一次。

还有Room 的大小。 HashMap 在一个典型的场景中赢得了几个点,在有数千个点的情况下,更新点的开销占主导地位。


你不能为所有Points 使用一个数组吗?如果是这样,那么它肯定会比HashMap 快​​得多,尤其是在更新方面(除非它变得非常大)。


这可能有用也可能没用。

实际上,不仅每个Room 都有一些Points,而且每个Point 也可能有一个Room (n:1)。它是如何实现的,这是一个不同的问题。

鉴于此,我们有一个标准问题:如果您双向链接,那么您必须保持两个链接同步。最简单的解决方案是使设置器(“adders”/“removers”)尽可能私有,并且只从方法中调用它们

void link(Room room, Point point) {
    Room oldRoom = point.getRoom();
    if (oldRoom!=null) oldRoom.removePoint(point);
    room.addPoint(point);
    point.setRoom(room);
}

您从PointRoom 的链接是外部的,但这几乎不会改变任何事情(除了保持Point 更小,可能更干净,并为每次访问添加 HashMap 的微小开销)。

它通常也是最快的,因为通常查询比更新多得多。您的问题是更新成本按Room 大小增加。 如果您不告诉我们一些数字,则无法进行估算。


如果点太多,房间大小变化不大,您可以将点坐标四舍五入为n 的倍数,并保留一个数组,其中包含与网格相交的所有房间的集合。您可以像以前一样继续操作,但更新开销会降低几乎一个由房间面积 (*) 给出的因子,而搜索开销会更高,因为您必须从集合中选择真正匹配的房间(如果有的话)。

(*) 对于不对齐网格的房间,相交的矩形数量明显更多。

【讨论】:

    猜你喜欢
    • 2012-05-22
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 2021-10-21
    • 2019-11-07
    相关资源
    最近更新 更多