Data structure for irregular grid - data-structures

Im wondering what is the best data structure for grid containing different sized rectangles/squares as game map sectors. I need to acces object within that grid by simple xyz coordinates.
searched for KdTrees, but they seem to find nearest object, I found also segment trees/interval trees but there is little info about them
Cheers.

You can use an octree. That is, you can start with a rectangular parallelepiped that contains the entire region ((0, 0, 0), (x, y, z))(it is a root of the tree). At the next step, split it into 8 rectangular parallelepipeds(((0, 0, 0), (x / 2, y / 2, z / 2)), ((0, 0, z / 2), (x / 2, y / 2, z)) and so on). These 8 rectangular parallelepipeds are children of the root. Keep building the tree recursively for each of them. When a rectangular parallelepiped is completely inside one region, the recursion should stop(so it becomes a leaf of the tree).
To answer a query, start from the root of the octree and go to a proper child until you reach a leaf.
It is also possible to adapt a k-d tree to solve this problem. The idea is similar to the one described above: split a space into two half-spaces, build a tree for each of them recursively. The base case for recursion is the same too: once the current subspace is inside only one region, the recursion should stop.

Related

Tree that contains points - improvement needed

Currently, I'm making my own structure that holds points in 2D space. I know that there are many ready-made algorithms and kind of trees but I want to have something lightweight. So I have (x, y) point that is inside of each node, each node contains 4 children: topLeft, topRight, botLeft, botRight next node.
Inserting:
Every new node is inserted depends on its position.
If the tree is empty, insert the new node / If the tree is not empty, go to the first node and do:
1. Decide what is the position of the current node in regard of the new node.
2. If it is e. g. topLeft and it is not occupied then insert the new node.
3. If position topLeft is occupied go to this node and repeat.
Removing:
The structure I need does not need to have "removing particular node" function, so if the job is done the destructor deletes the whole tree recursively.
Check if the node is inside of particular area:
If the tree is not empty go the first node and then:
1. Check if given area's x is less than node's x and area's y is less than node's y if it is then go to the topLeft children node (if it exists).
2. The same for the topRight (check area's x + width position and y).
3. The same for botRight (check area's x + width and y + height).
4. The same for botLeft (check area's x and y + height).
5. Check if current node is inside of area if it is do stuff you want to do with a point. Recursively go back and repeat.
That's how my structure looks like, the image shows which bonds would be checked for particular area (orange color):
link
My question is, is there is a better algorithm? What Can I improve? I saw quadtree but it seems to be different and it contains more data. I need something that can easily hold moving objects in 2D. I appreciate your help.
What you have is basically a quadtree, but you use your data for doing splits instead of the typical middle.
You can improve the system a bit by switching to a KD tree. It's similar except at each point you split along a single dimension. The main difference is that you only have two pointers per node (instead of 4) so you save about half the memory.
Another thing is that you split your space until you get to 1 point. Because modern CPUs do really fancy things, for small values, linear search will be faster than traversing the tree. So I would only split a space when you have 50-100 points already in there. This will also save a bunch of pointers that don't need to stored at all.
If you know something about the distribution of your points you might be able to do something better. If the distribution is kinda uniform you can simply chunk your space into uniform cells and store the points in the associated cells. A rule of thumb says if you have N points you should have sqrt(N) cells, but you should try and see what works best.

Greedy Best First Search Algorithm, how to compute the length of its traverse?

I have this problem that I am working on that has to do with the greedy best first search algorithm. However I am bit stuck on computing the length of the traverse when it comes to points (x, y). For example lets say I have these points:
(0, 1), (0, 2), (1, 2), (1, 3). So what I did is draw out a diagram on the x, y plane:
Now knowing the GBF algorithm, it goes to check the closet node and so in this case the transverse would look like so: (0, 1)->(0, 2)->(1, 2)->(1, 3). So now in order to compute the length of the points connections done by the GBF, do I need to basically add up the path, which in this case would be three? Any clarifications would be helpful.
The first part is to find the best way to store the graph using appropriate data structure.
Say the graph looks like this now.
(1,3)P4
|
P2(0,2)--(1,2)P3
|
(0,1)P1
|
(0,0)P0
One way to represent this graph would using Adjacency List. Like this
P0 => P1
P1 => P2
P2 => P3
P3 => P4
Now using Breath first Search the distance between two points can be calculated in linear time. The distance between two nodes(points) with the path length being the number edges.
Explanation for BFS can be found here

Algorithm for >2D skyline query/efficient frontier

The problem at hand:
given a set of N points in an D dimensional space, with all their coordinates >= 0 (in 2D the points would all be in the 1st quadrant, in 3D in the 1st octant, and so on...), remove all the points that have another point that has value bigger or equal in every coordinate.
In 2D, the result is this:
(image from Vincent Zoonekynd's answer here) and there is a simple algorithm, detailed in that answer, that runs in N*log(N).
With chunking I should have brought it to N*log(H), but optimizations on that are for another question.
I was interested in extending the solution to 3 dimensions (and possibly 4, if it's still reasonable), but my current 3D algorithm is pretty slow, cumbersome and doesn't generalize to 4D nicely:
Sort points on the x axis, annotate the position of each point
Initialize a sort of segment tree with N leaves, where leaves will hold the points' y values and a node will hold max(child1, child2)
Sort points on the z axis
For every point from the largest z:
Check what position it was in the x order, try to put it in the segment tree in that position
Check first if there is a point already down (so it has > z), at an higher place (so it has > x) with a bigger y (this costs log(N), thanks tree)
If said point is found, the current point is discarded, otherwise it's inserted and the tree is updated
This still runs in N*log(N), but requires 2 different sorts and a 2*N-big structure.
Extending this would require another sort and a prohibitive 2*N^2-big quad tree.
Are there more efficient (especially CPU-wise) approaches?
I don't think it's relevant, but I'm writing in C, the code is here.

data structure for storing angle intervals

I want to create a data structure that can store angle intervals, for example (a,b) where both a and b represent the polar angle of the the end points of a segment A,B against a point Q
This data structure must support two operations. Insert new intervals and also tell me if the entire view point of point Q has been covered, in other words if the union of all viewpoints created by the segments is 360 degrees.
I tried implementing a very simple interval tree where the insertion procedure is as follows.
Let (a,b) the interval that you want to insert.
Start from the root node, see if (a,b) is covered entirely by the interval stored in the root node, if that is the case, return and do nothing.
Otherwise, there maybe some part covered by the root node and some part not completely covered. At most two parts can not be covered and depending on each case, recurse to the left or/and to the right subtree.
I am not using augmented data structures so in the worst case to insert an interval you will have to do O(n) operations, giving you a complexity of O(n^2) for inserting n intervals.
Here is the problem though. When you are working with angles, you have to deal with cycles, which polar angle is a and which polar angle is b. So given a segment AB you find the polar angles of the end points against Q, but then how do you find out the interval that you will store in your tree?
One might say, okay, your interval can be (min(angleAQ, angleBQ), max(angleAQ, angleBQ)).
This however will not work in the following case:
The interval would be defined by the blue angle and the green angle, which is much larger than the actual view point which is defined by the red angle.
Due to this cycle property, it's much more difficult to manage such angle intervals.
My question is whether such an interval tree can exist and if so can someone give me some hints to overcome these difficulties?
thank you in advance
The circularity of angles is not a major obstacle: to instead an interval like [270, 45) that wraps around, instead insert two intervals [270, 360), [0, 45).
To implement insertion without wraparound, we can use a binary search tree. This tree tracks the uncovered intervals by mapping each endpoint of an uncovered interval to whether it's a left or right endpoint. For example, if we have covered intervals [0, 45), [0, 60), [90, 120), [150, 180), [180, 270), then the mapping is
60: left
90: right
120: left
150: right
270: left
360: right .
Initialize the mapping with
0: left
360: right
To insert an interval [a, b) with a < b, we do the following. Find the predecessor x of a in the mapping (greatest key not greater than a). If x exists and is a left endpoint, then insert a as a right endpoint (after x). Find the successor y of b in the mapping (least key not less than b). If y exists and is a right endpoint, then insert b as a left endpoint (before y). Delete all keys not just inserted between a and b inclusive. The initial interval is covered completely if and only if the mapping is empty.

Algorithm to search and sort cubic area

I'm trying to figure out an algorithm that would sort cubic area (ex the area defined by (0, 0, 0) to (1, 1, 1) and would be as fast as possible to return the area when given coordinates.
ex: data structure contains area: (0, 0, 0) to (100, 100, 100), (1000, 1000, 1000) to (1010, 1010, 1010) and (-50, -50, -50) to (60, -60, 60)
thus searching for 10, 10, 10 would return area 1, (1001, 1001, 1001) would return area 2 etc
Sort, add, remove time can be long. I need a fast search time
we can assume its only integers that will be searched and the solution of making a 3d grid and filling every cell contained within the area with a reference to the area is NOT an acceptable solution, i don't have 3TB of ram to dedicate to this :P.
We can also assume that areas will NOT be overlapping, if that helps anyone
If anybody has an idea I'd be glad to hear it
Thanks guys
-Olivier-
Edit: using a structure that holds minX, minY, minZ, maxX, maxY, maxZ to represent an area and place all those area in a list where you search one by one (by checking if the coordinates is bigger then minX but smaller then maxX, and same for every coordinates ) is still too slow O(N)
at the moment I'm exploring the idea to sort then using a n-ary tree, sort by x, then by y, then by z but i do not know if it will be a good one
You don't want to "sort" the cubic area, you want a spatial indexing structure such as a k-d tree, octree, or otherwise. K-d trees are an especially good choice because you're already talking about shapes (sub-cuboids) with axis-aligned surfaces which do not overlap. It may be worth looking up methods for broad phases in computer games as they often use data structures for which detecting arbitrary intersections of aligned boxes with existing aligned boxes is very fast. (e.g. The Bullet physics engine.)
Most of the spatial indexing techniques mentioned above are O(log n) for performing point queries. There's many implementations of K-d trees already in existence.
This is a simple bounding box problem.
Linear search:
Each of your regions is defined by a minimum corner (x_min, y_min, z_min) and a maximum corner (x_max, y_max, z_max). If you are searching for a particular target point (target_x, target_y, target_z), you can just loop through all the regions. If you find a region where:
x_min <= target_x <= x_max
y_min <= target_y <= y_max
z_min <= target_z <= z_max
then the region that you're searching for is the one defined by {(x_min, y_min, z_min), (x_max, y_max, z_max)}.
If N is your number of bounding regions, this algorithm will run in O(N). If you collect a list of regions that match your target, you can also handle overlapping regions as well.
Octree spatial subdivision:
If you have a very large number of regions, you can create a pre-computed hierarchy also known as an octree:
An octree is a tree data structure in which each internal node has
exactly eight children. Octrees are most often used to partition a
three dimensional space by recursively subdividing it into eight
octants. Octrees are the three-dimensional analog of quadtrees. The
name is formed from oct + tree, but note that it is normally written
"octree" with only one "t". Octrees are often used in 3D graphics and
3D game engines.
So, at every level of this hierarchy, you subdivide the space into eight sub-cubes.
If one of those sub-cubes does not have any search regions inside it, it becomes an empty leaf node (i.e., you can say "nope, nothing in here, move along").
If a sub-cube has a sufficiently small number of search regions within it (i.e., some number M where M << N) you can apply the above linear search algorithm to that target number.
If a sub-cube still has a relatively large number of search regions within it, continue the subdivision process on that sub-cube.
If you're willing to spend the time to compute the octree, this will produce a search algorithm that has performance on the order of O(logN) + O(M).
I would start by implementing a simple Box collision method. Then you'd just run this against each of your areas.
My question would be what if the search spans multiple areas
You should choose from one of algorithms, listed here. If your data allows it, you may try integer sorting algorithms, which have lower theoretical iteration count, then comparison-based ones.

Resources