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
Related
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.
When solving the Chinese postman problem (route inspection problem), how can we find the pairings (between odd vertices) such that the sum of the weights is minimized?
This is the most crucial step in the algorithm that successfully solves the Chinese Postman Problem for a non-Eulerian Graph. Though it is easy to implement on paper, but I am facing difficulty in implementing in Java.
I was thinking about ways to find all possible pairs but if one runs the first loop over all the odd vertices and the next loop for all the other possible pairs. This will only give one pair, to find all other pairs you would need another two loops and so on. This is rather strange as one will be 'looping over loops' in a crude sense. Is there a better way to resolve this problem.
I have read about the Edmonds-Jonhson algorithm, but I don't understand the motivation behind constructing a bipartite graph. And I have also read Chinese Postman Problem: finding best connections between odd-degree nodes, but the author does not explain how to implement a brute-force algorithm.
Also the following question: How should I generate the partitions / pairs for the Chinese Postman problem? has been asked previously by a user of Stack overflow., but a reply to the post gives a python implementation of the code. I am not familiar with python and I would request any community member to rewrite the code in Java or if possible explain the algorithm.
Thank You.
Economical recursion
These tuples normally are called edges, aren't they?
You need a recursion.
0. Create main stack of edge lists.
1. take all edges into a current edge list. Null the found edge stack.
2. take a next current edge for the current edge list and add it in the found edge stack.
3. Create the next edge list from the current edge list. push the current edge list into the main stack. Make next edge list current.
4. Clean current edge list from all adjacent to current edge and from current edge.
5. If the current edge list is not empty, loop to 2.
6. Remember the current state of found edge stack - it is the next result set of edges that you need.
7. Pop the the found edge stack into current edge. Pop the main stack into current edge list. If stacks are empty, return. Repeat until current edge has a next edge after it.
8. loop to 2.
As a result, you have all possible sets of edges and you never need to check "if I had seen the same set in the different order?"
It's actually fairly simple when you wrap your head around it. I'm just sharing some code here in the hope it will help the next person!
The function below returns all the valid odd vertex combinations that one then needs to check for the shortest one.
private static ObjectArrayList<ObjectArrayList<IntArrayList>> getOddVertexCombinations(IntArrayList oddVertices,
ObjectArrayList<IntArrayList> buffer){
ObjectArrayList<ObjectArrayList<IntArrayList>> toReturn = new ObjectArrayList<>();
if (oddVertices.isEmpty()) {
toReturn.add(buffer.clone());
} else {
int first = oddVertices.removeInt(0);
for (int c = 0; c < oddVertices.size(); c++) {
int second = oddVertices.removeInt(c);
buffer.add(new IntArrayList(new int[]{first, second}));
toReturn.addAll(getOddVertexCombinations(oddVertices, buffer));
buffer.pop();
oddVertices.add(c, second);
}
oddVertices.add(0, first);
}
return toReturn;
}
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
I read this question on career cup but didn't find any good answer other than 'SkipList'. The description of SkipList that I found on wikipedia was interesting, however, I didn't understand some terms like 'geometric/binomial distrubution'... I read what it is and goes deep into probabilistic theory. I simply wanted to implement a way to make some searching quicker. So here's what I did:
1. Created indexes.
- I wrote a function to create say 1000 nodes. Then, I created an array of type linked list and looped through the 1000 nodes and picked every 23rd element (random number that came in my mind) and added to the array which I call 'index'.
SLL index = new SLL[50]
Now the function to to create the index:
private static void createIndex(SLL[] index, SLL head){
int count=0;
SLL temp = head;
while(temp!=null)
{
count++;
temp = temp.next;
if((count==23){
index[i] = temp;
i++;
count=0;
}
}
}
Now finally the 'find' function. In that function, I first take the input element say 769 for example. I go through the 'index' array and find index[i]>769. Thus, now I pass head = index[i-1] and tail = index[i] to the 'find' function. It will then search between a short range of 23 elements for 769. Thus, I calculated that it takes a total of 43 jumps (including the array jumps and the node=node.next jumps) to find the element I wanted which otherwise would have taken 769 jumps.
Please Note: I consider the code to create index array NOT a part of searching, thus I do not add its time complexitiy(which is terrible) with the 'find' function's time complexity. I assume that this creation of index should be done as a separate function after a list has been created, OR, do it timely. Just like it takes time for a webpage to show up on google searches.
Also, this question was asked in a Microsoft interview and I wonder if the solution I provided would be any good or would I look like a fool for providing such kind of a solution. The solution has been written in Java.
Waiting for your feedback.
It is difficult to make out what problem it is that you are trying to solve here, or how your solution is supposed to work. (Hint: complete working code would help with both!)
However there are a couple of general things we can say:
You can't search a list data structure (e.g. find i in the list) in better that O(N) unless some kind of ordering has been placed on it. For example, sorting the elements.
If the elements of the list are sorted and your list is indexable (i.e. getting the element at position i is O(1)), then you can use binary search and find an element in O(logN).
You can't get the element at position i of a linked list in better that O(N).
If you add secondary data (indexes, whatever), you can potentially get better performance for certain operations ... at the expense of more storage space, and making certain other operations more expensive. However, you no longer have a list / linked list. The entire data structure is "something else".
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.