I'm trying to determine a fast way of storing a set of objects, each of which have an x and y coordinate value, such that I can quickly retrieve all objects within a certain rectangle or circle. For small sets of objects (~100) the naive approach of simply storing them in a list, and iterating through it, is relatively quick. However, for much larger groups, that is expectedly slow. I've tried storing them in a pair of TreeMaps as well, one sorted on the x coordinate, and one sorted on the y coordinate, using this code:
我正在尝试确定一种存储一组对象的快速方法,每个对象都有一个x和y坐标值,这样我就可以快速检索某个矩形或圆形内的所有对象。对于小型对象集(~100),简单地将它们存储在列表中并通过它迭代的简单方法相对较快。但是,对于规模更大的群体来说,这预计会很慢。我已经尝试将它们存储在一对TreeMaps中,一个在x坐标上排序,一个在y坐标上排序,使用以下代码:
xSubset = objectsByX.subSet( minX, maxX );
ySubset = objectsByY.subSet( minY, maxY );
result.addAll( xSubset );
result.retainAll( ySubset );
This also works, and is faster for larger sets of objects, but is still slower than I would like. Part of the problem is also that these objects move around, and need to be inserted back into this storage, which means removing them from and re-adding them to the trees/lists. I can't help but think there must be better solutions out there. I'm implementing this in Java, if it makes any difference, though I expect any solution will be more in the form of a useful pattern/algorithm.
这也适用,对于较大的对象集更快,但仍然比我想要的慢。部分问题还在于这些对象移动,需要插回到此存储中,这意味着将它们从树中删除并重新添加到树/列表中。我不禁想到那里必须有更好的解决方案。我在Java中实现这个,如果它有任何区别,尽管我希望任何解决方案都会以有用的模式/算法的形式出现。
6 个解决方案
#1
14
Quadtrees seem to solve the specific problem I asked. Kd-Trees are a more general form, for any number of dimensions, rather than just two.
Quadtrees似乎解决了我问的具体问题。 Kd-Trees是一种更通用的形式,适用于任何数量的维度,而不仅仅是两个维度。
R-Trees may also be useful if the objects being stored have a bounding rectangle, rather than being just a simple point.
如果存储的对象具有边界矩形,而不仅仅是一个简单的点,则R树也可能很有用。
The general term for these type of structures is Spatial Index.
这些类型结构的总称是空间索引。
There is a Java implementation of Quadtree and R-Tree.
有一个Quachiree和R-Tree的Java实现。
#2
4
The general term is a Spatial Index. I guess you should choose according to the existing implementations.
一般术语是空间索引。我想你应该根据现有的实现来选择。
#5
1
Simple QuadTree implementation in C# (easy to translate into java) http://www.codeproject.com/KB/recipes/QuadTree.aspx
C#中简单的QuadTree实现(易于翻译成java)http://www.codeproject.com/KB/recipes/QuadTree.aspx
#6
0
You could put all the x cords in a map, and the y cords in another map, and have the map values point to the object.
您可以将所有x条线放在地图中,将y绳索放在另一个地图中,并使地图值指向该对象。
TreeMap<Integer, TreeMap<Integer, Point>> xMap = new TreeMap<Integer, TreeMap<Integer, Point>>();
for (int x = 1; x < 100; x += 2)
for (int y = 0; y < 100; y += 2)
{
Point p = new Point(x, y);
TreeMap<Integer, Point> tempx = xMap.get(x);
if (tempx == null)
{
tempx = new TreeMap<Integer, Point>();
xMap.put(x, tempx);
}
tempx.put(y, p);
}
SortedMap<Integer, TreeMap<Integer, Point>> tempq = xMap.subMap(5, 8);
Collection<Point> result = new HashSet<Point>();
for (TreeMap<Integer, Point> smaller : tempq.values())
{
SortedMap<Integer, Point> smallerYet = smaller.subMap(6, 12);
result.addAll(smallerYet.values());
}
for (Point q : result)
{
System.out.println(q);
}
}
#1
14
Quadtrees seem to solve the specific problem I asked. Kd-Trees are a more general form, for any number of dimensions, rather than just two.
Quadtrees似乎解决了我问的具体问题。 Kd-Trees是一种更通用的形式,适用于任何数量的维度,而不仅仅是两个维度。
R-Trees may also be useful if the objects being stored have a bounding rectangle, rather than being just a simple point.
如果存储的对象具有边界矩形,而不仅仅是一个简单的点,则R树也可能很有用。
The general term for these type of structures is Spatial Index.
这些类型结构的总称是空间索引。
There is a Java implementation of Quadtree and R-Tree.
有一个Quachiree和R-Tree的Java实现。
#2
4
The general term is a Spatial Index. I guess you should choose according to the existing implementations.
一般术语是空间索引。我想你应该根据现有的实现来选择。
#3
#4
#5
1
Simple QuadTree implementation in C# (easy to translate into java) http://www.codeproject.com/KB/recipes/QuadTree.aspx
C#中简单的QuadTree实现(易于翻译成java)http://www.codeproject.com/KB/recipes/QuadTree.aspx
#6
0
You could put all the x cords in a map, and the y cords in another map, and have the map values point to the object.
您可以将所有x条线放在地图中,将y绳索放在另一个地图中,并使地图值指向该对象。
TreeMap<Integer, TreeMap<Integer, Point>> xMap = new TreeMap<Integer, TreeMap<Integer, Point>>();
for (int x = 1; x < 100; x += 2)
for (int y = 0; y < 100; y += 2)
{
Point p = new Point(x, y);
TreeMap<Integer, Point> tempx = xMap.get(x);
if (tempx == null)
{
tempx = new TreeMap<Integer, Point>();
xMap.put(x, tempx);
}
tempx.put(y, p);
}
SortedMap<Integer, TreeMap<Integer, Point>> tempq = xMap.subMap(5, 8);
Collection<Point> result = new HashSet<Point>();
for (TreeMap<Integer, Point> smaller : tempq.values())
{
SortedMap<Integer, Point> smallerYet = smaller.subMap(6, 12);
result.addAll(smallerYet.values());
}
for (Point q : result)
{
System.out.println(q);
}
}