find m nearest neighbors in KD tree use java - java

I want to implement KD tree in java for a data structure project but I have problem with special method that this project wants. In below you can see the format of method that I want.
float[][] findMNearest(float[] point, int m) {}
I implement find nearest neighbor method but for m nearest neighbor I have problem and I can't understand algorithm for solution.
In this picture you can see my implementation for nearest neighbor.
java
private void nearest(KDNode root, KDNode target, int index) {
if (root == null)
return;
visited++;
float d = root.distance(target);
if (best == null || d < bestDistance) {
bestDistance = d;
best = root;
}
if (bestDistance == 0)
return;
float dx = root.getCoordinates()[index] - target.getCoordinates()[index];
index = (index + 1) % k;
nearest(dx > 0 ? root.getLeft() : root.getRight(), target, index);
if (dx * dx >= bestDistance)
return;
nearest(dx > 0 ? root.getRight() : root.getLeft(), target, index);
}
I don't want to use ready library, too.

At the end my friend help me!
Full source of project for answer this question and other questions about kdtree and its methods at https://github.com/Iman9mo/KDTree

Related

Balanced binary tree returning true

I am trying to solve a question of the balanced binary tree.
Given a binary tree : [1,2,2,3,3,null,null,4,4]. Determine if it's a balanced tree or not.
And I had the solution:
public boolean isBalanced(TreeNode root) {
int height = heightCalculation(root);
if(height > 1) return false;
else
return true;
}
public int heightCalculation(TreeNode root){
if(root == null)
return 0;
int left_height = Integer.MIN_VALUE;
int right_height = Integer.MIN_VALUE;
left_height = heightCalculation(root.left);
right_height =heightCalculation(root.right);
return Math.abs(left_height - right_height);
}
The tree structure looks like:
1
/ \
2 2
/ \
3 3
/ \
4 4
It's returning true but the actual answer is false.
Can someone help me in fixing the issue ? I have kept the tree structure for your reference
The problem is that the heightCalculation function which is supposed to calculate the heights of right and left sub-trees and find the difference always returns 0. Following is the correct implementation for calculating the height of a binary tree:
int height(TreeNode node) {
if(node == null) {
return 0;
} else {
return 1 + Math.max(height(node.left), height(node.right));
}
}
Use the above function to find the heights of the sub trees and then calculate the difference.

Find the shortest path with maximum gain

Problem link How can i modify my code so it give me shortest path with maximum weight.
Problem overview: I am giving a matrix and i have to go from one index to other with minimum index each index is having some gain , so i have to find the shortest path(if more than one shortest path are possible so path with maximum gain)
My code:
public static int min(int x , int y ,int endx,int endy,int n ,int m,int[][] p){
int[] dirx ={1,-1,0,0 };
int[] diry={0,0,1,-1};
LinkedList<Point> som = new LinkedList<Point>();
som.add(new Point(x,y));
//dp[x][y]=p[x][y];
while(!som.isEmpty()){
Point xx = som.pop();
for(int i=0;i<4;i++){
int x1 = xx.x + dirx[i];
int y1 = xx.y + diry[i];
if(x1>=0 && x1<n && y1>=0 && y1<m && p[x1][y1]!=-1 && dp[x1][y1]==-1){
dp[x1][y1] = dp[xx.x][xx.y]+ 1;
som.add(new Point(x1,y1));
}
}
}
return dp[endx][endy];
}
from your code add
((dp[x1][y1]==-1) || ((dp[x1][y1] == dp[xx.x][xx.y] + 1) && (w[xx.x][xx.y]+p[x1][y1] > w[x1][y1])))
instead of
(dp[x1][y1]==-1)
and inside the condition
w[x1][y1] = w[xx.x][xx.y] + p[x1][y1];
which means you will update the path result if you found better way of the same length
also you may optimize not to add same point several times, but i think this is not necessary in this particular problem
This problem can be solved using Dijkstra's algorithm. But we need to compare both distance and gain amount instead of just distance in the original algorithm.
These are some code hints from me, so you only need to change some part of your code.
class Entry implements Comparable<Entry>{
int x,y, dist, gain;
//Constructor is omitted.
public int compareTo(Entry o){
if(dist != o.dist)//Compare distance first
return dist - o.dist;
return o.gain - gain;//Compare gain value
}
}
//Method signature is omitted
PriorityQueue<Entry> q = new PriorityQueue();
q.add(new Entry(0,0,0,gain[0][0]);
int[][][]dist = new int[n][m][2];//Assume size of matrix is n x m
//Init dist array omitted
dist[0][0][0] = 0;//Init distance
dist[0][0][1] = gain[0][0];//Init gain amount, assume we have a gain matrix
while(!q.isEmpty()){
Entry e = q.poll();
if(dist[e.x][e.y][0] == e.dist && dist[e.x][e.y][1] == e.gain){
for(all valid next positions (a,b))
if(dist[a][b][0] > e.dist + 1 || (dist[a][b][0] == e.dist + 1 && dist[a][b][1] < e.gain + gain[a][b]){
//Notice the condition to update the dist array
dist[a][b][0] = e.dist + 1;
dist[a][b][1] = e.gain + gain[a][b];
q.add(new Entry(a,b,e.dist + 1, e.gain + gain[a][b]);
}
}
}
return dist[n-1][m-1][1];

Find sum of nodes height in a binary tree recursively

How to find sum of node's height in a binary tree recursively?
Example:
public int totalHeight() {
return totalHeight(root);
}
private int totalHeight(BinaryNode<AnyType> n) {
int totalHeight = 0;
if (n.left == null && n.right == null)
return totalHeight;
if (n.left != null && n.right != null)
return totalHeight + 1
+ Math.max(totalHeight(n.left), totalHeight(n.right));
if (n.left != null)
return totalHeight + 1 + Math.max(totalHeight(n.left), -1);
if (n.right != null)
return totalHeight + 1 + Math.max(-1, totalHeight(n.right));
return totalHeight;
}
I have tried this, but it only get the height of the tree instead of sum of all node's height.
I feel difficult to track the counter in recursion, it seems that the totalHeight set to 0 every recursive call. This is not good.
A simple version would be to do a two-pass process where you first record for each node the height it is at, and then iterate through the nodes to sum them up. This method can be made recursive, but it is easy to do it in just one pass by summing as you calculate the height.
public static int totalHeightSum = 0;
private int calculateHeightAndAdd ( Node n )
{
if ( n == null )
return 0;
int leftHeight = calculateHeightAndAdd ( n.left );
int rightHeight= calculateHeightAndAdd ( n.right);
int myHeight = 1 + Math.max ( leftHeight, rightHeight );
totalHeightSum += myHeight;
return myHeight;
}
Recurcively find height of each node and keep adding to a static variable. Alternately, you could memorize the height and store in each node and then do another recursion to add them up.
The recursion should return the height of the node n and not the total heights of each of the nodes in the subtree.
Given your implementation of the height of a node, let's simply call it height(BinaryNode<?>), you can:
if you have access to all the nodes in a collection:
int sumHeight(List<BinaryNode<?>> nodes) {
int sum = 0;
for (BinaryNode<?> node: nodes) {
sum += height(node);
}
return sum;
}
if you only have access to the nodes in a tree structure:
int sumHeight(BinaryNode<?> node) {
if (node == null) return 0;
return height(node) + sumHeight(node.left) + sumHeight(node.right);
}
It would be interesting to see if there're algo's that can do the calculation in one recursion (maybe some backtracking algo?).
Ok. I have come out a solution.
a) if n == null return 0
b) if n.left == null && n.right == null return 0
c) the total height is total height of left + total height of right + the height of it self
the height of itself is:
1) if left side is larger, then total height of left minus total height of left's left
2) if right side is larger, then total height of right minus total height of right's right
public int totalHeight() {
return totalHeight(root);
}
private int totalHeight(BinaryNode<AnyType> n) {
if (n == null)
return 0;
else if (n.left == null && n.right == null)
return 0;
else
return totalHeight(n.left)
+ totalHeight(n.right)
+ (totalHeight(n.left) > totalHeight(n.right) ? totalHeight(n.left)
- (n.left == null ? 0 : totalHeight(n.left.left))
: totalHeight(n.right)
- (n.right == null ? 0
: totalHeight(n.right.right))) + 1;
}
I am assuming you are not updating heights during insertion.
Solution:
I would traverse through the tree in a inorder way. So I first declare root.height=0.
And then say
BinaryNode right;
BinaryNode left;
BinaryNode parent;
static int level;
int height;
if(left!=null)
{
left.height=left.parent.height+1;
level=level+left.height;
left.yourMethod();
}
if(right!=null)
{
right.height= right.parent.height+1;
level=level+right.height;
right.yourMethod();
}
So you will now have level that stores all the heights.
Alternative method can be Breadth first search traversal using a queue, but the answer would be the same.
Hope this helps.
void addHeights(class tree* root, int depth, int& sum)
{
if(root)
{
addHeights(root->left, depth+1, sum);
addHeights(root->right, depth+1, sum);
sum += depth;
}
}
public int sum(){
return sum(root);
}
private int sum(BinaryNode <?> n){
if(n == null)
return 0;
else
return n.data + sum(n.left) + sum(n.right);
}
I need more data to assess your code though I am assuming that you called the data inside the node "data".
So if the node is null it means you have reached the end of the tree and returns 0. Otherwise it takes the data and traverses towards the left then to the right. With each recursion they are being added until they are no more nodes left to be added.
private int maxHeight(BinaryNode<AnyType> n) {
if (n ! = null) return 0;
int leftheight = maxHeight(n.left);
int rightheight = maxHeight(n.right);
return (leftheight > rightheight) ? leftheight + 1 : rightheight + 1;
}
So far you have known the 4 cases to count the height
The essence is to continue to go left or right node if the left child or the right child exist.
if exist, return 1.
The counting function goes in the last statement. That is to get the largest height counted.
The main course is to get familiar with recursion and the programming stack when the method is working.

Calculating direction based on point offsets

For my tile-based game, I need to calculate direction based on a given point offset (difference between two points). For example, let's say I'm standing at point (10, 4) and I want to move to point (8, 6). The direction I move at is north-west. What would be the best way to calculate this?
Here's me basic implementation in Java.
public int direction(int x, int y) {
if (x > 0) {
if (y > 0) {
return 0; // NE
} else if (y < 0) {
return 1; // SE
} else {
return 2; // E
}
} else if (x < 0) {
if (y > 0) {
return 3; // NW
} else if (y < 0) {
return 4; // SW
} else {
return 5; // W
}
} else {
if (y > 0) {
return 6; // N
} else if (y < 0) {
return 7; // S
} else {
return -1;
}
}
}
Surely it can be optimised or shortened. Any help? Thanks.
I think the easiest to understand way would be making a static array that contains the values for all cases.
// Won't say anything about how much these values make sense
static final int[][] directions = {
{3, 6, 0},
{5, -1, 2}, // -1 for "no direction", feel free to replace
{4, 7, 1}
};
public int direction(int x, int y) {
x = (x < 0) ? 0 : ((x > 0) ? 2 : 1);
y = (y < 0) ? 0 : ((y > 0) ? 2 : 1);
return directions[y][x];
}
Edit: Now it's correct (why are so many languages missing a proper sgn function?)
My answers with if conditions :).
public int direction(int x, int y) {
//0 NE, 1 SE, 2 E, 3 NW, 4 SW, 5 W, 6 N, 7 S, 8 (Same place / Not a direction)
int direction = 0;
if(x < 0){
direction = 3;
}else if(x == 0){
direction = 6;
}
if(y < 0){
direction = direction + 1;
}else if(y == 0){
direction = direction + 2;
}
return direction;
}
define a 2D array to hold all states.
convert x and y to 0, 1 or 2 based on their value (x>0 or x<0 or x ==0)
return the specific index of array.
This is about as short and clean as you can get, if you represent the eight cardinal directions this way, as separate enumerated values. You're choosing between eight distinct return values, so a decision tree with eight leaves is the best you can do.
You might get something a little tidier if you split direction into two components (N-S and E-W), but without knowing more about what you do with direction, we can't know whether that's worth the trouble.
You can receive and return your direction as a Point or something similar (anyway, an (x,y) tuple). So if you're standing in p0 = (10, 4) and want to move to p1 = (8, 6), the result would be (in pseudocode):
norm(p1 - p0) = norm((-2,2)) = (-1,1)
You can calculate the norm of an integer if you divide it by its absolute value. So for a point you calculate the norm of both members. Just bear in mind that (-1,1) is more expressive than 3 and you can operate in an easier fashion with it.
If you need specific operations, you can create your own Java Point class or extend the existing ones in the library.

Binary tree search algorithm errors

I have a binary tree that I need to search through. I'm not searching for one specific node of the tree, but rather over every node of the tree to gain information about them. I have a simple recursive search right now, but every time it runs I get a stack overflow error. It's a full binary tree of depth 7...
if (curDepth < 6 && !searchedNodes[curID * 2])
depthSearch(curNode.getRight());
if (curDepth < 6 && !searchedNodes[curID * 2 + 1])
depthSearch(curNode.getLeft());
if (curID != 1 && !searchedNodes[(int) (curID / 2)])
depthSearch(curNode.getParent());
The curID == 1 corresponds to the root node, so I need to check that it's
not the parent. The searchedNodes thing is to make sure i don't search
the same node twice. Any ideas on how to do this?
edit: here's the entire search method
public void depthSearch(AntTree curNode) {
boolean[] searchedNodes = new boolean[128];
if (curNode == null)
return;
int curID = curNode.getID();
searchedNodes[curID] = true;
if (curNode.getFood() > 0) {
AntScript.foodLocs[curID] = 1;
} else {
Ant6Script.foodLocs[curID] = 0;
}
Ant[] ants = curNode.getAnts();
boolean containsWorker = false, containsSoldier = false;
if (ants != null) {
for (int i = 0; i < ants.length; i++) {
if (ants[i].type().equals("Worker")
&& ants[i].teamID() != AntScript.myTeamID) {
containsWorker = true;
} else if (ants[i].type().equals("Soldier")
&& ants[i].teamID() != AntScript.myTeamID) {
containsSoldier = true;
} else if (ants[i].type().equals("Queen")
&& ants[i].teamID() != AntScript.myTeamID) {
AntScript.enemyQueenLoc = curID;
}
}
}
if (containsWorker)
AntScript.enemyWorkerLocs[curID] = 1;
else
AntScript.enemyWorkerLocs[curID] = 0;
if (containsSoldier)
AntScript.enemySoldierLocs[curID] = 1;
else
AntScript.enemySoldierLocs[curID] = 0;
AntScript.viewedNodeLocs[curID] = 1;
int curDepth = (int) (Math.log(curID) / Math.log(2));
if (AntScript.viewedNodeLocs[(int) (curID / 2)] == 0
|| (curDepth < 6 && AntScript.viewedNodeLocs[curID * 2 + 1] == 0)
|| (curDepth < 6 && AntScript.viewedNodeLocs[curID * 2] == 0)) {
if (curDepth < 6
&& AntScript.viewedNodeLocs[curID * 2] == 0
&& !searchedNodes[curID * 2]) {
depthSearch(curNode.getLeft());
}
if (curDepth < 6
&& AntScript.viewedNodeLocs[curID * 2 + 1] == 0
&& !searchedNodes[curID * 2 + 1]) {
depthSearch(curNode.getRight());
}
if (curID != 1
&& AntScript.viewedNodeLocs[(int) (curID / 2)] == 0
&& !searchedNodes[(int) (curID / 2)]) {
depthSearch(curNode.getParent());
}
} else {
if (curDepth < 6 && !searchedNodes[curID * 2]) {
depthSearch(curNode.getRight());
}
if (curDepth < 6 && !searchedNodes[curID * 2 + 1]) {
depthSearch(curNode.getLeft());
}
if (curID != 1 && !searchedNodes[(int) (curID / 2)]) {
depthSearch(curNode.getParent());
}
}
}
The purpose of the viewedNodeLocs array is because i have many ants on a board performing a search from different nodes, and it is better to search through a node that hasn't been searched before than one that has been. I can't just do one big search and then be done because my requests for next nodes are supposed to return null after 13 requests from one ant (this whole thing is from an ant AI thing I'm programming for a game)
Your data structure is most peculiar. It looks like you have flattened the tree into an array of nodes. It makes your algorithm really difficult to understand, and is almost certainly a bad idea.
Having said that, I suspect that the problem is related to the fact that each recursive call to depthSearch allocates a new searchedNodes array. Like I said, your algorithm is ... hard to understand.
I suggest that you represent your binary tree in the conventional way, with each node having a 'left' and 'right' pointer. Then implement the traversal in the way described in the wikipedia article. Better still, take a look at the Java Collections framework and see if one of the existing List/Set/Map implementations does what you are trying to do.
You can use the tree traversal technique to get get the information about all node. Check here
http://en.wikipedia.org/wiki/Pre-order_traversal.
You need traversal, not search.
for example, some psuedo code
void PrintTree( TreeNode node ){
if( node == null ) return;
if( node.Left != null ) PrintTree( node.Left );
if( node.Right != null ) PrintTree( node.Right );
Console.Printline( node.Value );
}
If you want to fire off multiple copies of this code for multiple ants and let only one ant touch any single node, you will need multiple threads and a shared data structure with locking etc.
Better for now to just share a "Map" data structure that each gets a reference to that you build by executing a traversal once. After all a tree of depth 7 is only going to have 128 nodes anyways, so it's not much memory or time to traverse. You can always improve it later if you need to, but at least get it working first.

Categories