How Can You Clear a Quad Tree Without Recursion ( using queue maybe? ) - c++

Ok given a class along the lines of
class quadTree {
short level;
Vec2f midpoint;
quadTree * nodes[4] = { NULL, NULL, NULL, NULL};
public:
void newPartition() {
float j = fWIDTH / 2 ^ level;
float k = fHEIGHT / 2 ^ level;
nodes[0] = new quadTree(level+1, midpoint[0] - j, midpoint[0] + k);
nodes[1] = new quadTree(level+1, midpoint[0] + j, midpoint[0] + k);
nodes[2] = new quadTree(level+1, midpoint[0] - j, midpoint[0] - k);
nodes[3] = new qaudTree(level+1, midpoint[0] + j, midpoint[0] - k);
}
}
How could I implement a function that deletes all the nodes under the current node of the quad tree without recursion probably using a queue? As in a Clear() function.
I'm sorry for asking, I feel like I should know this and just can't quite figure it out. I looked online but couldn't find anything. Any Ideas?
For any example code using a queue just use std::queue.
EDIT ::
Ok I think this is what I am going to use for reference. I think this should work, correct me if I am wrong.
#include <queue>
void helpClear( bool notPassing, queue<quadTree> &q ) {
int count;
for ( int i; i < 4; i++ ) {
if ( node[i] != NULL){
q.push ( node[i] );
count++;
}
}
quadTree * Point;
if ( notPassing ){
for ( int i; i < count; i++ ){
Point = q.front();
q.pop();
Point -> helpClear(0, q);
}
for ( int i; i < 4; i ++ )
delete nodes[i];
}
}
void clear () {
queue <quadTree> q;
quadTree * Point;
helpClear(1,q);
while (!queue.empty() ) {
quadTree * Point;
Point = q.front();
q.pop();
Point -> helpClear(1,q);
delete Point;
}
for ( int i; i < 4; i++ )
nodes[i] = NULL;
}
helpClear() is a private function of quadTree and clear() is the public function you call to delete all nodes below the current node.

There are two ideas (approaches):
1) If you can control all newPartition()-actions at the one point (for instance, at the top level), you can implement special buffer of quadTree pointers and collect in it all nodes (any of std list, vector, queue, ...).
In this case, when you need to clean up all nodes, you can just clean up all child-nodes by pointers in this buffer without using a stack.
2) If your QuadTree uses strict order of nodes (in spatial sense), you can organize all of your pointers in one container. For example:
Level 0 (1 pointer):
1111
1111
1111
1111
Level 1 (4 pointers)
2233
2233
4455
4455
Level 2 (16 pointers)
ABEF
CDGH
IJMN
KLOP
In container order will be like this:
12345ABCDEFGHIJKLOP
Relationships between levels can be resolved by math calculations, due to every level needs precisely 2^N elements.
This solution doesn't need extra pointers (and 0 pointers at all), and solve your stack problem. However, it needs more time to move from parent to child and from child to parent, and can consume more memory if your levels in QuadTree are different (by number of elements in one of, for instance less than 2^N).
Note: it's a very rare type of solution and in the most cases recursive is better.

Some applications can use a quadtree that is transformed to an array with key "morton Index". Such a quad tree is an huge array, without any child pointers.
You can delete this as simple as deleting an array.
However not all applications can use that MortonIndexed Quadtree.
But recursion should be no problem, because the quadtree should not have a depth of more than 16. If much deeper then you are using the wrong type of quad tree.

I use my custom tree implementation to avoid recursion. In my realization Node contains pointer to Parent Node, Child Node and Next Plain(one level depth) node. Using this data it's easy to implement non recursive tree iteration.

Related

Kd-Tree flawed K nearest neighbor

Disclaimer: There are some bad practices in this following code
Hello, I just had a few questions on how to correctly format my KD tree K nearest neighbor search. Here is an example of my function.
void nearest_neighbor(Node *T, int K) {
if (T == NULL) return;
nearest_neighbor(T->left, K);
//do stuff find dist etc
if(?)nearest_neighbor(T->right, K);
}
This code is confusing so I will try to explain it. My function only takes the k value and a Node T. What I am trying to do is find the distance between the current node and every other value in the structure. These all work, the issue I'm having is understanding when and how to call the recursive calls nearest_neighbor(T->left/T->right,K) I know I am meant to prune the calls to the right side but I'm not sure how to do this. This is an multidimensional KD Tree by the way. Any guidance to better examples would be very appreciated.
I would advise you to implement like Wikipedia says, where for your specific question, this:
Starting with the root node, the algorithm moves down the tree
recursively, in the same way that it would if the search point were
being inserted (i.e. it goes left or right depending on whether the
point is lesser than or greater than the current node in the split
dimension).
answers the question. Of course you can have this image in mind:
where if you have more two dimensions like in the example, you simply split in the first dimension, then in the second, then in the third, then in the forth and so on, and then you follow a cyclic policy, so that when you reach the final dimension, you start from the first dimension again.
The general idea is to keep a global point closest to the target, updating with newly discovered points and never descending into an n-gon that can't possibly contain a point closer than the nearest to the target already found. I'll show it in C rather than C++. You can easily translate to object-oriented form.
#define N_DIM <k for the k-D tree>
typedef float COORD;
typedef struct point_s {
COORD x[N_DIM];
} POINT;
typedef struct node_s {
struct node_s *lft, *rgt;
POINT p[1];
} NODE;
POINT target[1]; // target for nearest search
POINT nearest[1]; // nearest found so far
POINT b0[1], b1[1]; // search bounding box
bool prune_search() {
// Return true if no point in the bounding box [b0..b1] is closer
// to the target than than the current value of nearest.
}
void search(NODE *node, int dim);
void search_lft(NODE *node, int dim) {
if (!node->lft) return;
COORD save = b1->p->x[dim];
b1->p->x[dim] = node->p->x[dim];
if (!prune_search()) search(node->lft, (dim + 1) % N_DIM);
b1->p->x[dim] = save;
}
void search_rgt(NODE *node, int dim) {
if (!node->rgt) return;
COORD save = b0->p->x[dim];
b0->p->x[dim] = node->p->x[dim];
if (!prune_search()) search(node->rgt, (dim + 1) % N_DIM);
b0->p->x[dim] = save;
}
void search(NODE *node, int dim) {
if (dist(node->p, target) < dist(nearest, target)) *nearest = *node->p;
if (target->p->x[dim] < node->p->x[dim]) {
search_lft(node, dim);
search_rgt(node, dim);
} else {
search_rgt(node, dim);
search_lft(node, dim);
}
}
/** Set *nst to the point in the given kd-tree nearest to tgt. */
void get_nearest(POINT *nst, POINT *tgt, NODE *root) {
*b0 = POINT_AT_NEGATIVE_INFINITY;
*b1 = POINT_AT_POSITIVE_INFINITY;
*target = *tgt;
*nearest = *root->p;
search(root, 0);
*nst = *nearest;
}
Note this is not the most economical implementation. It does some unnecessary nearest updates and pruning comparisons for simplicity. But its asymptotic performance is as expected for kd-tree NN. After you get this one working, you can use it as a base implementation to squeeze out the extra comparisons.

Depth First Search: Formatting output?

If I have the following graph:
Marisa Mariah
\ /
Mary---Maria---Marian---Maryanne
|
Marley--Marla
How should be Depth First Search function be implemented such that I get the output if "Mary" is my start point ?
Mary
Maria
Marisa
Mariah
Marian
Maryanne
Marla
Merley
I do realize that the number of spaces equal to depth of the vertex( name ) but I don't how to code that. Following is my function:
void DFS(Graph g, Vertex origin)
{
stack<Vertex> vertexStack;
vertexStack.push(origin);
Vertex currentVertex;
int currentDepth = 0;
while( ! vertexStack.empty() )
{
currentVertex = vertexStack.top();
vertexStack.pop();
if(currentVertex.visited == false)
{
cout << currentVertex.name << endl;
currentVertex.visited = true;
for(int i = 0; i < currentVertex.adjacencyList.size(); i++)
vertexStack.push(currentVertex.adjacencyList[i]);
}
}
}
Thanks for any help !
Just store the node and its depth your stack:
std::stack<std::pair<Vertex, int>> vertexStack;
vertexStack.push(std::make_pair(origin, 0));
// ...
std::pair<Vertex, int> current = vertexStack.top();
Vertex currentVertex = current.first;
int depth = current.second;
If you want to get fancy, you can extra the two values using std::tie():
Vertex currentVertex;
int depth;
std::tie(currentVertex, depth) = vertexStack.top();
With knowing the depth you'd just indent the output appropriately.
The current size of your stack is, BTW, unnecessarily deep! I think for a complete graph it may contain O(N * N) elements (more precisely, (N-1) * (N-2)). The problem is that you push many nodes which may get visited.
Assuming using an implicit stack (i.e., recursion) is out of question (it won't work for large graphs as you may get a stack overflow), the proper way to implement a depth first search would be:
push the current node and edge on the stack
mark the top node visited and print it, using the stack depth as indentation
if there is no node
if the top nodes contains an unvisited node (increment the edge iterator until such a node is found) go to 1.
otherwise (the edge iterator reached the end) remove the top node and go to 3.
In code this would look something like this:
std::stack<std::pair<Node, int> > stack;
stack.push(std::make_pair(origin, 0));
while (!stack.empty()) {
std::pair<Node, int>& top = stack.top();
for (; top.second < top.first.adjacencyList.size(); ++top.second) {
Node& adjacent = top.first.adjacencyList[top.second];
if (!adjacent.visited) {
adjacent.visted = true;
stack.push(std::make_pair(adjacent, 0));
print(adjacent, stack.size());
break;
}
}
if (stack.top().first.adjacencyList.size() == stack.top().second) {
stack.pop();
}
}
Let Rep(Tree) be the representation of the tree Tree. Then, Rep(Tree) looks like this:
Root
<Rep(Subtree rooted at node 1)>
<Rep(Subtree rooted at node 2)>
.
.
.
So, have your dfs function simply return the representation of the subtree rooted at that node and modify this value accordingly. Alternately, just tell every dfs call to print the representation of the tree rooted at that node but pass it the current depth. Here's an example implementation of the latter approach.
void PrintRep(const Graph& g, Vertex current, int depth)
{
cout << std::string(' ', 2*depth) << current.name << endl;
current.visited = true;
for(int i = 0; i < current.adjacencyList.size(); i++)
if(current.adjacencyList[i].visited == false)
PrintRep(g, current.adjacencyList[i], depth+1);
}
You would call this function with with your origin and depth 0 like this:
PrintRep(g, origin, 0);

Finding nearest neighbor(s) in a KD Tree

Warning: Fairly long question, perhaps too long. If so, I apologize.
I'm working on a program involving a nearest neighbor(s) search of a kd tree (in this example, it is an 11 dimensional tree with 3961 individual points). We've only just learned about them, and while I have a good grasp of what the tree does, I get very confused when it comes to the nearest neighbor search.
I've set up a 2D array of points, each containing a quality and a location, which looks like this.
struct point{
double quality;
double location;
}
// in main
point **parray;
// later points to an array of [3961][11] points
I then translated the data so it has zero mean, and rescaled it for unit variance. I won't post the code as it's not important to my questions. Afterwards, I built the points into the tree in random order like this:
struct Node {
point *key;
Node *left;
Node *right;
Node (point *k) { key = k; left = right = NULL; }
};
Node *kd = NULL;
// Build the data into a kd-tree
random_shuffle(parray, &parray[n]);
for(int val=0; val<n; val++) {
for(int dim=1; dim<D+1; dim++) {
kd = insert(kd, &parray[val][dim], dim);
}
}
Pretty standard stuff. If I've used random_shuffle() incorrectly, or if anything is inherently wrong about the structure of my tree, please let me know. It should shuffle the first dimension of the parray, while leaving the 11 dimensions of each in order and untouched.
Now I'm on to the neighbor() function, and here's where I've gotten confused.
The neighbor() function (last half is pseudocode, where I frankly have no idea where to start):
Node *neighbor (Node *root, point *pn, int d,
Node *best, double bestdist) {
double dist = 0;
// Recursively move down tree, ignore the node we are comparing to
if(!root || root->key == pn) return NULL;
// Dist = SQRT of the SUMS of SQUARED DIFFERENCES of qualities
for(int dim=1; dim<D+1; dim++)
dist += pow(pn[d].quality - root->key->quality, 2);
dist = sqrt(dist);
// If T is better than current best, current best = T
if(!best || dist<bestdist) {
bestdist = dist;
best = root;
}
// If the dist doesn't reach a plane, prune search, walk back up tree
// Else traverse down that tree
// Process root node, return
}
Here's the call to neighbor in main(), mostly uncompleted. I'm not sure what should be in main() and what should be in the neighbor() function:
// Nearest neighbor(s) search
double avgdist = 0.0;
// For each neighbor
for(int i=0; i<n; i++) {
// Should this be an array/tree of x best neighbors to keep track of them?
Node *best;
double bestdist = 1000000000;
// Find nearest neighbor(s)?
for(int i=0; i<nbrs; i++) {
neighbor(kd, parray[n], 1, best, &bestdist);
}
// Determine "distance" between the two?
// Add to total dist?
avgdist += bestdist;
}
// Average the total dist
// avgdist /= n;
As you can see, I'm stuck on these last two sections of code. I've been wracking my brain over this for a few days now, and I'm still stuck. It's due very soon, so of course any and all help is appreciated. Thanks in advance.
The kd-tree does not involve shuffling.
In fact, you will want to use sorting (or better, quickselect) to build the tree.
First solve it for the nearest neighbor (1NN). It should be fairly clear how to find the kNN once you have this part working, by keeping a heap of the top candidates, and using the kth point for pruning.

BST in array traversal

I have the following implementation of a binary tree in an array;
32
/ \
2 -5
/ \
-331 399
The data is grouped 3 indexes at a time. index%3==0 is the value of the node, index%3==1 is the index of the value of the left node and index%3==2 is the index of the value of the right node. If the left or right index reference is 0, there is no node that direction.
I'm trying to find the depth (height) of this tree. I've written it recursively
height(node):
if node == null:
return 0
else:
return max(height(node.L), height(node.R)) + 1
I want to find a non-recursive solution, however.
Here is some pseudocode i have, assuming the tree is not empty
int i = 0; int left = 0; int right = 0;
while (i != n ){
if ( a[i+1] != 0 ){
left++;
}
else if ( a[i+2] != 0 ){
right++;
}
i = i + 3;
}
return max ( left, right ) + 1;
I don't think this is right and I'd like some help figuring out how to do this correctly.
You haven't said what your problem is with recursion for us to understand what behavior you want to improve.
There are many solutions to this, but almost all of them have the same or worse performance than your recursive solution. Really, the best solutions are going to be things you'd have to do when you're creating the tree. For example, you could store the height of each node in a fourth array index per node. Then it's a trivial scan of every fourth index to find the max height. It would also make it easier if nodes had parent references stored with them so that didn't have to be computed during the height check.
One solution is to simulate recursion with a stack, but that's really no different than recursion.
Another solution is to go through each node and determine its height based on it's parent, but not in a specific traversal's order. However, because of how you have this configured, without a secondary datastructure to store the hierarchy, it's going to be less efficient O(n^2). The problem is you can't get from the child to its parent without a full array scan. Then you can do it in linear time (but recursion is also linear time, so I'm not sure we're doing better. It's also not going to be much better from a memory perspective).
Can you define what type of efficiency you want to improve?
Here's the pseudocode for each, but I'm depending on a few datastructures that aren't easily present:
"recursion without recursion" solution:
int get_height(int * tree, int length) {
Stack stack;
int max_height = 0;
if (length == 0) {
return 0;
}
// push an "array" of the node index to process and the height of its parent.
// make this a struct and use that for real c code
stack.push(0,0);
while(!stack.empty()) {
int node_index, parent_height = stack.pop();
int height = parent_height + 1;
if (height > max_height) {
max_height=height;
}
if (tree[node_index+1] != 0 )
stack.push(tree[node_index+1], height);
if (tree[node_index+2] != 0 )
stack.push(tree[node_index+2], height);
}
return max_height;
}
Now working on really slow solution that uses no additional memory, but it's REALLY bad. It's like writing fibonacci recursively bad. The original algorithm went through each node and performed O(n) checks worst case for a runtime of O(n^2) (actually not quite as bad as I had originally thought)
edit: much later I'm adding an optimization that skips all nodes with children. This is REALLY important, as it cuts out a lot of calls. Best case is if the tree is actually a linked list, in which case it runs in O(n) time. Worst case is a fully balanced tree - with logn leaf nodes each doing logn checks back to the root for O((log(n)^2). Which isn't nearly so bad. Lines below to be marked as such
"really slow but no extra memory" solution (but now updated to not be nearly so slow):
int get_height(int * tree, int length) {
int max_height = 0;
for (int i = 0; i < length; i+=3) {
// Optimization I added later
// if the node has children, it can't be the tallest node, so don't
// bother checking from here, as the child will be checked
if (tree[i+1] != 0 || tree[i+2] != 0)
continue;
int height = 0;
int index_pointing_at_me;
// while we haven't gotten back to the head of the tree, keep working up
while (index_pointing_at_me != 0) {
height += 1;
for (int j = 0; j < length; j+=3) {
if (tree[j+1] == tree[i] ||
tree[j+2] == tree[i]) {
index_pointing_at_me = j;
break;
}
}
}
if (height > max_height) {
max_height = height;
}
}
return max_height;
}
Improved on previous solution, but uses O(n) memory - this assumes parents are always before children in array (which I suppose isn't technically required)
int get_height(int * tree, int length) {
if (length == 0)
return 0;
// two more nodes per node - one for which node is its parent, the other for its height
int * reverse_mapping = malloc((sizeof(int) * length / 3) * 2)
reverse_mapping[1] = 1; // set height to 1 for first node
// make a mapping from each node to the node that points TO it.
// for example, for the first node
// a[0] = 32
// a[1] = 3
// a[2] = 6
// store that the node at 3 and 6 are both pointed to by node 0 (divide by 3 just saves space since only one value is needed) and that each child node is one taller than its parent
int max_height = 0;
for (int i = 0; i < length; i+=3) {
int current_height = reverse_mapping[(i/3)*2+1];
if (current_height > max_height)
max_height = current_height;
reverse_mapping[(tree[i+1]/3)*2] = i;
reverse_mapping[(tree[i+1]/3)*2 + 1] = current_height + 1;
reverse_mapping[(tree[i+2]/3)*2] = i;
reverse_mapping[(tree[i+2]/3)*2 + 1] = current_height + 1;
}
return max_height
}

Mapping a branching tile path

I'm working on a game (and have asked a couple questions on it already), and now I have another question to ask of you guys.
The level format in this game is set up as a tilemap of Uint16's (I'm using SDL) which are indices into an array of tilemapData structs. One of the bits of the tilemapData struct is the isConductive bit/boolean.
The use of this bit is basically to create paths that connect various objects together into a single "powerNet." I've got some code below on the current method (which works, but I'll cover why I really hate it after)
void findSetPoweredObjects(unsigned long x, unsigned long y, powerNetInfo * powerNet) {
//Look for poweredObjs on this tile and set their powerNet to the given powernet
for (int i = 0; i < level->numChunks[CHUNKTYPE_POWEREDDEF]; i++)
if (level->poweredObjects[i]->position[0] == x && level->poweredObjects[i]->position[1] == y)
level->poweredObjects[i]->powerNet = powerNet, powerNet->objectsInNet++;
}
void recursiveCheckTile(bool * isWalked, powerNetInfo * powerNet, unsigned long x, unsigned long y, tilemapData * levelMap) {
//If out of bounds, return
if (x < 0 || y < 0 || x >= level->mapDimensions[0] || y >= level->mapDimensions[1]) return;
//If tile already walked, return
if (isWalked[x + (y * level->mapDimensions[0])]) return;
//If tile is nonconductive, return
if (!(level->tiles[levelMap->map[x + (y * level->mapDimensions[0])]]->flags & TILETYPE_CONDUCTIVE)) return;
//Valid tile to check, see if there's a poweredobj on the tile (link it to the net if it is) and check the adjacent tiles.
isWalked[x + (y * level->mapDimensions[0])] = true;
findSetPoweredObjects(x,y,powerNet);
recursiveCheckTile(isWalked, powerNet, x - 1, y, levelMap);
recursiveCheckTile(isWalked, powerNet, x + 1, y, levelMap);
recursiveCheckTile(isWalked, powerNet, x, y - 1, levelMap);
recursiveCheckTile(isWalked, powerNet, x, y + 1, levelMap);
}
bool buildPowerNets(void) {
//Build the powernets used by the powered objects
//TODO: Rewrite buildPowerNets() & recursiveCheckTile() to avoid stack overflows and make it easier to backtrace powernets in-game
bool * isWalked;
isWalked = new bool[(level->mapDimensions[0] * level->mapDimensions[1])];
unsigned long x, y;
tilemapData * levelMap = level->layers[level->activeMap];
for (y = 0; y < level->mapDimensions[1]; y++) {
for (x = 0; x < level->mapDimensions[0]; x++) {
if (isWalked[x + (y * level->mapDimensions[0])]) continue;
isWalked[x + (y * level->mapDimensions[0])] = true;
if (level->tiles[levelMap->map[x + (y * level->mapDimensions[0])]]->flags & TILETYPE_CONDUCTIVE) {
//it's conductive, find out what it's connected to.
//But first, create a new powernet
powerNetInfo * powerNet = new powerNetInfo;
powerNet->objectsInNet = 0;
powerNet->producerId = -1;
powerNet->supplyType = POWER_OFF;
powerNet->prevSupplyType = POWER_OFF;
powerNet->powerFor = 0;
//Find adjacent tiles to this one, add them to it's powernet, and then mark them walked. Then repeat until the net is done.
recursiveCheckTile(isWalked, powerNet, x, y, levelMap);
}
}
}
delete isWalked;
for (int i = 0; i < level->numChunks[CHUNKTYPE_POWEREDDEF]; i++)
if (level->poweredObjects[i]->powerNet == NULL) return false;
return true;
}
Note that returning false means that the function failed (in this case, it didn't properly link all of the objects).
My worry is that the function to walk the conductive tiles will flat-out fail on more complex maps because of a stack overflow. What are some ideas for how to mitigate this risk with these functions? I can provide more info on the structs used if it's needed.
I've thought of modifying the code so that recursiveCheckTile only makes a recursive call when it reaches a junction and just interatively follows the conductive path it's on otherwise, but that still seems to be only a partial solution since I can't know ahead of time how twisted or branching the path might be.
If it makes a difference, speed is entirely unimportant here, since this function only runs once when the map is being processed before being used, and so using a little extra time won't hurt.
Flood fill
It looks like you're basically doing a flood fill of your grid. You can eliminate the recursion by employing a queue or a stack of squares that need to be checked. See the "alternate implementations" section of the Wikipedia article for pseudo-code.
The advantage of maintaining the queue/stack yourself is that you will remove squares from the list as you visit them, whereas in the recursive solution the squares remain on the stack even after you have visited them.
Here's the "simple" alternative implementation from the Wikipedia article adapted to your problem:
1. Set Q to the empty queue.
2. Add node to the end of Q.
3. While Q is not empty:
4. Set n equal to the first element of Q
5. Remove first element from Q
6. If n has already been visited:
7. Go back to step 3.
8. Mark n as visited.
9. Add the node to the west to the end of Q.
10. Add the node to the east to the end of Q.
11. Add the node to the north to the end of Q.
12. Add the node to the south to the end of Q.
13. Return.
Note that you can use a stack or a queue for this, either will work. Here are some cool—and mesmerizing—animations showing the difference visually:
Queue-based flood fill
Stack-based flood fill
Connected-component labeling
You may also find the connected component labeling page interesting if you ever end up having multiple power nets on the same grid. It basically helps you figure out if you have multiple disconnected power nets, and when you do it tells you which one each square belongs to.
You can rewrite this function iteratively.
Think of it this way: You're implicitly using the call stack as your path stack for your search algorithm. Each time you call recursiveCheckTile you're pushing a node onto that stack. The call stack is relatively small, however, so you're blowing it out quickly.
You need to manage your path stack explicitly. Instead of making a call to a recursive function for the four adjoining nodes, push a node onto this explicit stack. Your algorithm will look like this (pseudo):
add starting node to stack
while( nodes on stack )
{
pop node
if( node is conductive )
{
add node to powerSet
push 4 adjoining nodes onto stack
}
}
This will yield the same traversal (depth-first), but your stack will be explicit so you can allocate gobsmacks of memory for it.