Traverse a graph, but only n levels deep - java

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.

Related

StackOverFlow Error when converting 1,000,000 Nodes in a Splay Tree to a SinglyLinkedList

I have implemented a Splay Tree class that uses nodes to store data. In this class I have tried to convert the data of nodes into a Singly Linked List. 1,000,000 nodes can be inserted into the splay tree and it works perfectly. Using recursion I get a StackOverFlow error when the tree contains 1,000,000 nodes. However when the tree contains around 15000 nodes it is able to be converted to a linked list without a problem.
Here is the code for my toList Method that is inside the splay tree class
public LinkedList<Node> toList() {
LinkedList<Node> list = new LinkedList<Node>();
Node node = root;
addToList(node, list);
return list;
}
private void addToList(Node node, LinkedList<Node> list) {
if(node != null) {
addToList(node.left, list);
list.add(node);
addToList(node.right, list);
}
}
I used this test class below to test the function of this method
#Test
public void testConversionToLinkedList {
SplayTree<Integer,String> st = new SplayTree<Integer,String>();
for(int i = 0; i < 1000000; i++) {
st.insert(i, Integer.toString(i));
}
assertEquals(1000000, st.size());
LinkedList<Node> list = st.toList();
assertEquals(1000000, list.size());
}
The test passes when the size entered is around 15000, however any number greater than that will show a StackOverFlowError
The error occurs at the line addToList(node.left, list);
This is really weird because when i used the same recursion technique to print the data of the nodes into a txt file, there is no StackOverFlow error and the data prints perfectly.
I have tried to use In Order Traversal, PreOrder and PostOrder but I still receive the same error at 1,000,000 nodes. I do know that it could be doing recursion too deeply and the stack runs out of memory. If that is the case is there any way I can convert a splay tree of nodes into a linked list?
Any idea what could be going wrong? cheers
Your poblem is the recursive algorithm. As you figured out there is a limit in the stack size, which is build when you have recursion.
You can always transform recursion to a loop.
here are some examples for DFS and BFS algorithms using loops: Non recursive Depth first search algorithm
You can increase the stack’s size. To do it you have to pass parameter to the jvm.
The format is -Xss[g|G|m|M|k|K].
For example: java -Xss4m YourTreeProgram
The root issue is that splay trees can have a height equal to their node count, so the recursive algorithms you often see applied to binary trees are risky when applied to splay trees.
The easiest approach is to splay the tree as you go.
Find the tree's minimum node. Simply follow the "left" links from the root all the way until they are null. Splay this node to the root, then add it to your list.
Find its successor. I.e. follow the root's "right" link once, then follow "left" repeatedly until null. Splay that node to the root, then add it to your list.
Repeat step 2 until there is no successor (i.e. the root's "right" link is null).
Finding the minimum and successor nodes are no different from other kinds of trees.

Change (same) variables of multiple objects quickly

I have an implementation of depth-first search for a directed graph with same size edges. This search changes the state of the nodes in my graph. So if I want to do a new search all nodes have to be reset to default.
My implementation:
public void resetGraph() {
ListItem temp = nodes.getHead();
while(temp != null){
DiGraphNode node = temp.key;
node.visitorState = VISITORS.NONE; //Set all nodes their initial state
node.sumOfDistances = 0;
temp = temp.next;
}
}
=> This takes some time for a large graph
Is there a way to do this more time efficient ?
Maybe someting like:
DiGraphNode.someStaticMethod(0);
As your structure stands at the moment there is little you can do - you must visit every node to reset it so you are stuck with an O(n) algorithm.
One possible solution that may improve performance a little would be to keep track of all of your visitorState and sumOfDistances fields in an array. You could then use a int nodeID (generated at node construction time perhaps) to access the state and sum. The benefit of this tweak would be to allow you to use Arrays.fill which may make use of cpu-specific block-set instructions.
You will not be able to change the order of the algorithm but you might find some speed-up this way.

Linked List Manual Sort

I'm having a really difficult time solving this problem. I have spent hours on it and can't figure it out.
I have a linked list that I am trying to manually sort. My nodes are called CNodes. There is a start CNode, a tail CNode and a newNext CNode.
Each Node contains a contact. The contact has a firstname that I am trying to sort the list by.
I know there are more automatic ways to do this, but I need to demonstrate that I understand how to sort (which clearly I do not at this point).
I am trying to do this by iterating over each node and comparing it to start, then changing the start entity if it qualifies.
This code is not working...I've been working on it for two days and am really stuck.
Any specific suggestions would be really appreciated.
CNode nextNode=start;
while(nextNode.getNext()!=null) {
CNode newNext;
tail=nextNode;
while(tail!=null) {
if(start.getContact().getStrFirstName().compareTo(tail.getContact().getStrFirstName()) > 0) {
//We put the starting node in a temp node
newNext=start;
newNext.setNext(tail.getNext());
//We set our current node to the start
start=tail;
start.setNext(newNext);
//Set the next node of start to the original next one of the one we
//just removed from the chain
//Set current marker to the new first nodes' next entity
tail=start.getNext();
//Set the next node for the marker to the one we just removed
} else {
tail=tail.getNext();
}
}
nextNode=nextNode.getNext();
}
The best thing you can do is start with an array, and get the sorting concept down. You also need to figure out what type of sort you are going to do, you're currently trying to do a bubble sort. There is also a merge sort, quick sort, and others. Once you pick the type of sort you want, you can then do it on an array, then move to node.
Here are some sorts:
https://github.com/BlaineOmega/MergeSort Bubble sort:
http://en.wikipedia.org/wiki/Bubble_sort Quick sort:
http://en.wikipedia.org/wiki/Quicksort
So what you're doing is a bubble sort. For a visual representation of what the is, look at this (from Wikipedia): http://upload.wikimedia.org/wikipedia/commons/c/c8/Bubble-sort-example-300px.gif
So in the while loop, when two nodes need to be switched, we're going to store the 'next' (current) node into a temp, put the tail in the next node, and put the temp into the tail, like a triangle.
temp
/ ^
/ \
V \
tail -- next
I attempted to rewrite your code, but was confused as to if start is you're root node, and if not, what is you're root node. If it is, it should be only used once, and that is declaring you're tail node.
Good luck, hope I helped,
Stefano

Converting a Breadth First Search to Depth first Search in Java

its been a long time since I touched Java so this may seem like an odd question. Currently have this Breadth First Search code I found here on StackOverflow, I have it modified on my end but I'll post the original code here.
public List<Node> getDirections(Node start, Node finish){
List<Node> directions = new LinkedList<Node>();
Queue<Node> q = new LinkedList<Node>();
Node current = start;
q.add(current);
while(!q.isEmpty()){
current = q.remove();
directions.add(current);
if (current.equals(finish)){
break;
}else{
for(Node node : current.getOutNodes()){
if(!q.contains(node)){
q.add(node);
}
}
}
}
if (!current.equals(finish)){
System.out.println("can't reach destination");
}
return directions;
}
I'm aware of other depth first search algorithms out there, but I was also told its possible to convert breadth first search to depth first search easily, and I would understand it better if it was done to this code instead of 2 totally different codes.
How can I change this to be a Depth First Search?
The main difference between Depth first and Breadth fist is the order in which you explore the nodes in your "frontier" (the list of nodes you're yet to explore).
If you add the outgoing nodes from your current node to the end of that list, you'll be testing every possibility in a "level" (for simplification purposes, imagine this as a tree), before going to the next level, so you have a Breadth first search.
If, on the other hand, you explore the newly added nodes (the outgoing nodes from your current position), before the nodes you've added earlier (that belong in the "upper" levels of the tree), then you'll be exploring the depth of the tree first.
In terms of data structures, you want a Stack instead of a Queue, but I think the explanation may come in handy.
You'd have to replace q.add(node) (which adds at the end of a list) with q.add(0, node) (to add at the beginning). Basically, use a stack instead of a queue.
Obviously you'd have to use the List interface instead of the Queue one to access the LinkedList.
Deque<Node> q = new LinkedList<Node>();
and use pop and push instead of remove and add
basically remove from the same side you added (normal remove and add are LIFO queue base ops) depth first uses a FIFO stack
and the other search algorithms are essentially the same but use different types of queues (eager search uses a easiest next step for example)
Replace Queue and LinkedList with Stack, add with push, and remove with pop

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