uniform cost search making some trouble - java

i am making program for uniform cost search but in my code when i put nodes in priority queue the node overrides... i don't know what's the problem.
for example if node A is already present in a queue with value 10, and if i put node A again with value 20 then the previous node A value also changes.
can any one help?
while(!queue.isEmpty())
{
Node temp=queue.remove();
System.out.println(temp.city_name+" "+temp.getPath_cost());
path.add(temp);
if(temp==destination)
{
break;
}
System.out.println(temp.link.length);
for(int i=0; i<temp.link.length; i++){
a=temp.link[i].cost;
b=temp.link[i].getParent().getPath_cost();
temp.link[i].getNode().setPath_cost(a+b);
System.out.print(temp.link[i].getNode().city_name+": ");
System.out.println(temp.link[i].getNode().getPath_cost());
queue.add(temp.link[i].getNode());
}
}

It looks like your node holds the path cost directly, so there is only ever one reference to a node. Vertexes in a graph (nodes) don't need to know about their path cost for search; instead the search typically implements a wrapper for each node evaluated at the time it is evaluated that stores search specific information, like path cost. Basically you query the node for it's neighbors (link property in your impl) and create a new instance of the wrapper for each neighbor.
All that being said, if you are only looking for the shortest path then you can safely just set the path cost to the min of it's existing path cost and the currently evaluated path cost. You would start by setting the path cost of each node positive infinity.

Related

Do not understand the solution for the Binary Tree Maximum Path Sum problem

The website GeeksforGeeks has presented a solution for the problem of Maximum path sum for a binary tree. The question is as follows:
Given a binary tree, find the maximum path sum. The path may start and
end at any node in the tree.
The core of the solution is as follows:
int findMaxUtil(Node node, Res res)
{
if (node == null)
return 0;
// l and r store maximum path sum going through left and
// right child of root respectively
int l = findMaxUtil(node.left, res);
int r = findMaxUtil(node.right, res);
// Max path for parent call of root. This path must
// include at-most one child of root
int max_single = Math.max(Math.max(l, r) + node.data,
node.data);
// Max Top represents the sum when the Node under
// consideration is the root of the maxsum path and no
// ancestors of root are there in max sum path
int max_top = Math.max(max_single, l + r + node.data);
// Store the Maximum Result.
res.val = Math.max(res.val, max_top);
return max_single;
}
int findMaxSum() {
return findMaxSum(root);
}
// Returns maximum path sum in tree with given root
int findMaxSum(Node node) {
// Initialize result
// int res2 = Integer.MIN_VALUE;
Res res = new Res();
res.val = Integer.MIN_VALUE;
// Compute and return result
findMaxUtil(node, res);
return res.val;
}
Res has the following definition:
class Res {
public int val;
}
I am confused about the reasoning behind these lines of code:
int max_single = Math.max(Math.max(l, r) + node.data, node.data);
int max_top = Math.max(max_single, l + r + node.data);
res.val = Math.max(res.val, max_top);
return max_single;
I believe the code above follows this logic but I do not understand WHY this logic is correct or valid:
For each node there can be four ways that the max path goes through
the node:
Node only
Max path through Left Child + Node
Max path through Right Child + Node
Max path through Left Child + Node + Max path through Right Child
In particular, I do not understand why max_single is being returned in the function findMaxUtil when we the variable res.val contains the answer we are interested in. The following reason is given on the website but I do not understand it:
An important thing to note is, root of every subtree need to return
maximum path sum such that at most one child of root is involved.
Could someone provide an explanation for this step of the solution?
In particular, I do not understand why max_single is being returned in the function findMaxUtil when we the variable res.val contains the answer we are interested in.
The problem is that findMaxUtil() really does two things: it returns largest sum of the tree that it's applied to, and it updates a variable that keeps track of the largest sum yet encountered. There's a comment to that effect in the original code, but you edited it out in your question, perhaps for brevity:
// This function returns overall maximum path sum in 'res'
// And returns max path sum going through root.
int findMaxUtil(Node node, Res res)
Because Java passes parameters by value, but every object variable in Java implicitly references the actual object, it's easy to miss the fact that the Res that's passed in the res parameter may be changed by this function. And that's exactly what happens in the lines you asked about:
int max_single = Math.max(Math.max(l, r) + node.data, node.data);
int max_top = Math.max(max_single, l + r + node.data);
res.val = Math.max(res.val, max_top);
return max_single;
That first line finds the maximum of the node itself or the node plus the greatest subtree, and that result is the max path sum going through root. Returning that value on the last line is one thing that this function does. The second and third lines look at that value and consider whether either it or the path that includes both children is larger than any previously seen path, and if so, it updates res, which is the other thing this function does. Keep in mind that res is some object that exists outside the method, so changes to it persist until the recursion stops and findMaxSum(Node), which started the whole thing, returns the res.val.
So, getting back to the question at the top, the reason that the findMaxUtil returns max_single is that it uses that value to recursively determine the max path through each subtree. The value in res is also updated so that findMaxSum(Node) can use it.
You're missing the value of res.val. The algorithm is trying to explore the whole tree, using res.val equal to the maximum path length explored up till then. In each step it iterates recursively across the children and updates res.val with the maximum path length, if higher than the one already present.
Proof:
Assume your algorithm works with trees with height n. For trees with height n+1 there's a root and 2 sub trees of height n. Also consider that findMaxUtil works fine for i<=n and will return the maximum path, starting with the partial root of the sub trees.
So the maximum path in your tree with height n+1 is calculated as follows
findMaxUtil(subtree1)
findMaxUtil(subtree2)
findmaxUtil(subtree1)+root.data
findmaxUtil(subtree2)+root.data
findmaxUtil(subtree1)+findmaxUtil(subtree2)+root.data
res.val
And finally the result is: findmaxUtil(newTree)=max(items 1:6).
Honestly I think the description on that website is very unclear. I'll try to convince you of the reasoning behind the algorithm as best I can.
We have a binary tree, with values at the nodes:
And we are looking for a path in that tree, a chain of connected nodes.
As it's a directed tree, any nonempty path consists of a lowest-depth node (i.e. the node in the path that is closest to the root of the tree), a path of zero or more nodes descending to the left of the lowest-depth node, and a path of zero or more nodes descending to the right of the lowest-depth node. In particular, somewhere in the tree there is a node that is the lowest-depth node in the maximum path. (Indeed, there might be more than one such path tied for equal value, and they might each have their own distinct lowest-depth node. That's fine. As long as there's at least one, that's what matters.)
(I've used "highest" in the diagram but I mean "lowest-depth". To be clear, any time I use "depth" or "descending" I'm talking about position in the tree. Any time I use "maximum" I'm talking about the value of a node or the sum of values of nodes in a path.)
So if we can find its lowest-depth node, we know the maximum value path is composed of the node itself, a sub-path of zero or more nodes descending from (and including) its left child, and a sub-path of zero or more nodes descending from (and including) its right child. It's a small step to conclude that the left and right descending paths must be the maximum value such descending path on each side. (If this isn't obvious, consider that whatever other path you picked, you could increase the total value by instead picking the maximum value descending path on that side.) If either or both of those paths would have a negative value then we just don't include any nodes at all on the negative side(s).
So we have a separate subproblem - given a subtree, what is the value of the maximum value path descending through its root? Well, it might just be the root itself, if all the paths rooted at its children have negative sum, or if it has no children. Otherwise it is the root plus the maximum value descending path of either of those rooted at its children. This subproblem could easily be answered on its own, but to avoid repeated traversals and redoing work we'll combine them both into one traversal of the tree.
Going back to the main problem, we know that some node is the lowest-depth node in the maximum value path. We're not even particularly concerned with knowing when we visit it - we're just going to recursively visit every node and find the maximum value path that has that path as its lowest-depth node, assured that at some point we will visit the one we want. At each node we calculate both the maximum value path starting at that point and descending within the subtree (max_single) and the maximum value path for which this node is the lowest-depth node in the path (max_top). The latter is found by taking the node and "gluing on" zero, one or both of the maximum descending-only paths through its children. (Since max_single is already the maximum value path descending from zero or one of the children, the only extra thing we need to consider is the path that goes through both children.) By calculating max_top at every node and keeping the largest value found in res.val, we guarantee that we will have found the largest of all values by the time we have finished traversing the tree. At every node we return max_single to use in the parent's calculations. And at the end of the algorithm we just pull out the answer from res.val.

Count number of nodes within given range in AVL tree

Suppose I have an AVL tree of distinct integers. I need to determine the number of nodes which lie in the interval [a, b) where a < b. Note that [a, b) is supplied by the user and hence I do not know beforehand what the value of a and b are. Also, a and b may not be present in the tree at all. For example, if I have a tree containing the integers {1, 2, 4, 5, 6, 7} then the user should expect an answer of 3 if he supplies the interval [3, 7).
A naive implementation would be to traverse every node and increment the count by 1 every time a node is found in the given interval. But this would have a worst case time complexity of O(n), as it is possible for every single integer in the tree to be within the given range. I need a faster algorithm, and after doing some research I found that it requires storing a size statistic in every node so that the rank of any given node can be easily computed.
I would like to do something like rank(b) - rank(a), but the problem is that a and b may not exist in the tree. In the above example, rank(7) would return 6 but rank(3) will not return any meaningful value.
Can anyone offer suggestions as to how I can address this issue? Also, I know that there is another similar question on this website, but that one involves C++ while this one involves Java. Also, I could not find a satisfactory answer there.
I've implemented a stack based tree iterator for an AVL tree some (long) time ago. It should work for your case like this:
create an array "treestack" which holds structs for traversal info. The struct just needs a bool "visited", and a pointer to your node type. The array can be of static size e.g. hold 64 info elements (one for each level of your tree, so this 64 will mean your tree contains max 4G nodes)
change the search method of your AVL tree to put the root node at treestack[0] when you begin with the search, and put all other nodes on top of the treestack as you follow the left and right child nodes during your search. Edit: Note that an unsuccessful search will result in your treestack having a node with the next smaller or next higher value, which is exactly what you want (just skip counting in case it's smaller, we still have abvalid iterator start oath).
You've now a path un your treestack which you can use for subsequent in-order traversal to find the next higher values. In-order traversal using the stack works like this:
start at the last element in treestack, keep a treeindex which is initially = arrayindex of the last item.
When there is a right node, and it is not marked visited: try follow ONE right of the current node, then ENDLESS to the left of any following nodes. Wherever you stop (so also if there are no left nodes but a single right one) is the next higher value. Put all nodes at the end of your tree stack as you follow them and inc your treeindex as you follow paths. And Mark the choosen final node with the next higher value as visited. Increase your node counter+1.
now to find subsequent higher values, ascend in the tree by taking treeindex-1 in your treestack as current node, an repeat the above step to find the next node with higher value.
if there is no right child node the current node, and the node is not marked visited: mark as visited, and inc node counter by 1
you're done when you either reach the root node with treeindex 0 or your node containing max value.
I hope it helps.
Instead of
rank(b) - rank(a)
what I would do is
rank(X) - rank(Y)
X is the very first node having value > b.
Y is the very first node having value >= a.

Height of binary search tree in constant time

I need to fine the height of a binary search tree with a time of O(1) the only way i could think to do this is to put a check in the add and remove methods incrementing a global counter is there any other way?
O(1) time suggests that you should already have the height when it is requested.
The best way is it to keep/update the correct value whenever a new node is added/deleted . You are doing it in a right way , however it increases the complexity on addition and deletion.
You can do it number of ways , like keep the depth value along with the node in tree etc.
class Node{
int depth;
Object value;
}
Node lowestNode;
I can think of storing the max depth node reference in an object and keep that as depth . So whenever you add a new element , you can check the depth of element based on its parent and replace the max depth node if the new element has more depth .
If you are deleting the max depth node then replace it with the parent otherwise correct the depth of all elments recursively along the tree.
The height of tree is , lowestNode.depth
Storing an attribute for the height and update it when you are doing add/remove should be the most reasonable solution.
If the tree is guaranteed to be balanced (e.g. AVL), you can calculate the height by number of element in the tree (you have to keep the number of elements though :P )

Traverse a graph, but only n levels deep

I have a graph which is essentially an ArrayList of Nodes, each of which stores their neighbors.
public class Node {
ArrayList<Node> neighbors;
String data;
public Node() {
data = null;
neighbors = new ArrayList<Node>();
}
}
I print out every path in this graph, but only do it n-levels deep. How should I go about coding this?
Or, if I should store this differently, feel free to let me know. But more importantly I want to know how to print out every path n-levels deep.
Just do a depth-limited traversal of the graph. This is just like depth-first search, except in the recursive step, you also add a variable called depth which is incremented every time you go down a depth. Then simply stop recursing once you've hit the desired depth.
Add an extra variable called visited in every node.
Do a breadth first search using a Queue and use the visited to prevent from forming a loop.
Do it for length n.

Graph Tour with Uniform Cost Search in Java

I'm new to this site, so hopefully you guys don't mind helping a nub.
Anyway, I've been asked to write code to find the shortest cost of a graph tour on a particular graph, whose details are read in from file. The graph is shown below:
http://img339.imageshack.us/img339/8907/graphr.jpg
This is for an Artificial Intelligence class, so I'm expected to use a decent enough search method (brute force has been allowed, but not for full marks).
I've been reading, and I think that what I'm looking for is an A* search with constant heuristic value, which I believe is a uniform cost search. I'm having trouble wrapping my head around how to apply this in Java.
Basically, here's what I have:
Vertex class -
ArrayList<Edge> adjacencies;
String name;
int costToThis;
Edge class -
final Vertex target;
public final int weight;
Now at the moment, I'm struggling to work out how to apply the uniform cost notion to my desired goal path. Basically I have to start on a particular node, visit all other nodes, and end on that same node, with the lowest cost.
As I understand it, I could use a PriorityQueue to store all of my travelled paths, but I can't wrap my head around how I show the goal state as the starting node with all other nodes visited.
Here's what I have so far, which is pretty far off the mark:
public static void visitNode(Vertex vertex) {
ArrayList<Edge> firstEdges = vertex.getAdjacencies();
for(Edge e : firstEdges) {
e.target.costToThis = e.weight + vertex.costToThis;
queue.add(e.target);
}
Vertex next = queue.remove();
visitNode(next);
}
Initially this takes the starting node, then recursively visits the first node in the PriorityQueue (the path with the next lowest cost).
My problem is basically, how do I stop my program from following a path specified in the queue if that path is at the goal state? The queue currently stores Vertex objects, but in my mind this isn't going to work as I can't store whether other vertices have been visited inside a Vertex object.
Help is much appreciated!
Josh
EDIT: I should mention that paths previously visited may be visited again. In the case I provided this isn't beneficial, but there may be a case where visiting a node previously visited to get to another node would lead to a shorter path (I think). So I can't just do it based on nodes already visited (this was my first thought too)
Two comments:
1) When you set costToThis of a vertex, you override the existing value, and this affects all paths in the queue, since the vertex is shared by many paths. I would not store the costToThis as a part of Vertex. Instead, I would have defined a Path class that contains the total cost of the path plus a list of nodes composing it.
2) I am not sure if I understood correctly your problem with the goal state. However, the way I would add partial paths to the queue is as follows: if the path has a length<N-1, a return to any visited node is illegal. When length=N-1, the only option is returning to the starting node. You can add visitedSet to your Path class (as a HashSet), so that you can check efficiently whether a given node has been visited or not.
I hope this helps...

Categories

Resources