I'm trying to implement Ford-Fulkerson/Edmonds-Karp only using adjacency matrix'. The only thing I'm not able to program is the function to calculate the shortest path, using BFS. The function to see if a shortest path actually exists is fine, but is it possible to also get the shortest path? Or is the only way to get the shortest path with BFS to use some kind of parent pointers, and traverse backwards to get the path?
Here is my code for see if path exists:
public static boolean existsPathFromSourceToSinkInGf(int Gf[][])
{
LinkedList<Integer> queue = new LinkedList<Integer>();
queue.add(0);
while (!queue.isEmpty())
{
int v = queue.remove();
if (v == sink) return true;
for (int i = 0; i < 5; i++)
{
if (Gf[v][i] != 0)
{
if (!queue.contains((Integer)i))
{
queue.add((Integer)i);
}
}
}
}
return false;
}
The common way to do it would indeed be to maintain parent pointers each time you settle a node and to go backwards once you found your path.
You could also keep track of paths explicitly in your queue. Instead of using just an integer for your linkedlist, you could create your own class consisting of the integer and a string with something like "node 1-> node 3->...". It's less commonly used because of the overhead of the class and the paths, but it avoids having to keep the parent pointers on their own and having to traverse them in the end.
On a side note 2 remarks on your code:
Why does it run for i=0..5?
You check if (!queue.contains((Integer)i)) so you don't put a vertex on your queue that's already on it. You should also avoid putting vertices on that have already been removed from the list (try maintaining a set of visited nodes).
Related
My method should add the associated key/value pair to the trie and if the key is already in the trie, the value should be updated. However I am not quite sure what Im doing wrong, its my first time using tries.
So I am currently working on my put method and I have the following:
public void put(TrieMapNode current, String curKey, String value){
if(current.getChildren().containsKey(curKey))
value = current.get(key);
curKey =value;
put(current.getChildren().get(curKey), curKey, value);
}
Any help would be greatly appreciated thanks!
In your current implementation, you will not benefit from the advantages of a trie. That is because at the root node, you have one child for each string you encounter.
That is not the way a trie is built. Each node of your trie can have at most one child per character (the elements that form strings).
So your method should look more like the following:
public void put(TrieMapNode current, String key, String value, int depth){
if (depth == key.length()){
current.value = value;
} else {
char curChar = key.charAt(depth);
if(!current.getChildren().containsKey(curChar)){
TrieMapNode newNode = new TrieMapNode();
current.getChildren().put(curChar, newNode);
}
put(current.getChildren().get(curChar), curKey, value, depth + 1);
}
The main mistake you did was to consider the key as a whole when inserting/updating in your trie. This would have resulted in a root node having one child node for each key in your map (so a ton of children), but with a very limited depth (the root node, its children and that's it).
In the implementation I proposed you, a node has one child per possible character (a bounded number, 26, 52, anyway a small and bounded number).
And its depth is not limited to one, because as you can see in the else block, we create a node if the one we look for did not exist (when you start you only have a root node, so you need to plan for the case where new node are created), and we also call recursively put on a child of the current node. So the value will be stored at a depth equal toi the length of its key.
I am tasked with creating a method that adds to the front (left) of an ArrayDeque without using the Deque library. I have come up with a method though its not adding to the que, it is coming out with an empty que.
Here is my addLeft method:
public T[] addLeft(T item){
T[] copyarr = (T[]) new Object[arr.length+1];
if(isEmpty()){
copyarr[frontPos] = item;
}else{
copyarr[frontPos] = item;
frontPos--;
for(int i = 1; i<copyarr.length; i++){
copyarr[i] = arr[i];
}
}
arr = copyarr;
return arr;
}
Here is the test code iv been using:
public class DequeueTest {
public static void main(String[] args) {
Dequeue test = new Dequeue();
test.addLeft(3);
test.addLeft(4);
System.out.println(test.toString());
}
}
Any idea where i have gone wrong ?
Can you clarify "ArrayDeque without using the Deque library"? Does it mean you do not want to use the ArrayDeque from the JDK?
You've gone wrong at the array copy statement, which should be
copyarr[i] = arr[i-1]
(note how the index is shifted)
Your implementation has serious runtime costs for adding elements in front, as you are copying the array every time.
(From the computer science class: ArrayLists gain their runtime behaviour from doubling the array size, when needed, thus balancing the re-sizing costs over all append operations.)
Also, as already mentioned in the comments, have a look at the ArrayDeque implementation for inspiration. Maybe offerFirst is really just what you need.
Addition based on the comment by Ferrybig:
You may want to track the array size in an extra variable, so that the storage array can be larger than the actual deque. This way you can double the storage array size when it is too small, sparing you from creating a copy every time.
Still, you have to move the elements (from higher to lower indexes) and finally put in the new element on the first place.
Second optimization step: save the first position and, if you expect multiple inserts at front, reserve some space, so that you don't have to move the elements on every insertion.
(Again, you are trading spacial for runtime compexity.)
I need to implement a Trie (in Java) for a college project. The Trie should be able to add and remove Strings (for phase 1).
I have spent several hours each day (for the last few days) trying to figure out how to do this and FAILED miserably each time.
I require some help, the examples on the internet and my textbook (Data Structures and Algorithms in Java By Adam Drozdek) are not helping.
Information
Node classes I am working with:
class Node {
public boolean isLeaf;
}
class internalNode extends Node {
public String letters; //letter[0] = '$' always.
//See image -> if letter[1] = 'A' then children[1] refers to child node "AMMO"
//See image -> if letter[2] = 'B' then children[2] refers to internal node "#EU"
public TrieNode[] children = new TrieNode[2];
public TrieInternalNode(char ch)
{
letters = "#" + String.valueOf(ch);//letter[0] = '$' always.
isLeaf = false;
}
}
class leafNode extends Node
{
public String word;
public TrieLeafNode(String word)
{
this.word = new String(word);
isLeaf = true;
}
}
And here is the pseudo code for insert that I need to follow: (warning it is very vague)
trieInsert(String K)
{
i = 0;
p = the root;
while (not inserted)
{
if the end of word k is reached
set the end-of-word marker in p to true;
else if (p.ptrs[K[i]] == 0)
create a leaf containing K and put its address in p.ptrs[K[i]];
else if reference p.ptrs[K[i]] refers to a leaf
{
K_L = key in leaf p.ptrs[K[i]]
do
{
create a nonleaf and put its address in p.ptrs[K[i]];
p = the new nonleaf;
} while (K[i] == K_L[i++]);
}
create a leaf containing K and put its address in p.ptrs[K[--i]];
if the end of word k is reached
set the end-of-word marker in p to true;
else
create a leaf containing K_L and put its address in p.ptrs[K_L[i]];
else
p = p.ptrs[K[i++]];
}
}
I need to implement the following methods.
public boolean add(String word){...}//adds word to trie structure should return true if successful and false otherwise
public boolean remove(String word){...}//removes word from trie structure should return true if successful and false otherwise
I cant find pseudo code for remove, but if insert does not work delete wont help me.
Here is a image of how the Trie that I need to implement should look like.
I am aware that the Trie will still be inefficient if implemented like this, but at the moment I need not worry about this.
The book provides an implementation that is similar to what I need to do but doesn't use the end of word char ('$') and only stores the words without their prefixes in the child nodes http://mathcs.duq.edu/drozdek/DSinJava/SpellCheck.java
Constraints
I need to implement the trie in JAVA.
I may not import or use any of Java's built-in data structures. (ie. no Map, HashMap, ArrayList etc)
I may use Arrays, Java primitive Types and Java Strings.
The Trie must use a $ (dollar) symbol to indicate a end-of-word. (see the image below )
I may asume that now word containing the $symbol will be inserted.
I need to implement the Trie it in the same style as the book does.
Case of words doesn't matter ie. all words will be considered to be lowercase
The Trie should only store the end-of-word character and the characters applicable to a word and not the entire alphabet(like some implementations).
I do not expect anyone to do the implementation for me(unless they have one lying around :P) I just really need help.
First of all, I don't think you should make leaf nodes and internal nodes separate classes. I recommend making a universal node class with an isLeaf() method. This method would return true if a node has no children.
Here is some higher-level pseudocode for the functions you need to implement. For simplicity, I assume the existence of a method called getIndex() which returns the index corresponding to a character.
Insert(String str)
Node current = null
for each character in str
int index = getIndex(character)
if current.children[index] has not been initialized
initialize current.children[index] to be a new Node
current = current.children[index]
You can easily augment this pseudocode to fit your needs. For example, if you want to return false whenever insertion isn't successful:
Return false if the input string is null
Return false if the input string contains invalid characters
Now, here is some higher-level pseudocode for remove.
Remove(String str)
Node current = null
for each character in str
int index = getIndex(character)
current = current.children[index]
// At this point, we found the node we want to remove. However, we want to
// delete as many ancestor nodes as possible. We can delete an ancestor node
// if it is not need it any more. That is, we can delete an ancestor node
// if it has exactly one child.
Node ancestor = current
while ancestor is not null
if ancestor has 2 or more children
break out of loop
else if ancestor has less than 2 children
Node grandAncestor = ancestor.parent
if grandAncestor is not null
reinitialize grandAncestor.children // this has the effect of removing ancestor
ancestor = ancestor.parent
At a very high level, we follow the input string to the node we want to remove. After this, we traverse up the tree following parent pointers and delete every node with 1 child (since it is no longer needed). Once we reach a node with 2 children, we stop.
Like Insert, we can easily augment this pseudocode to return false whenever deletion isn't successful:
Return false if the input string is null
Return false if the input string contains invalid characters
Return false if the input string leads to a Node which doesn't exist
It is easiest to implement delete if your Node class has a parent field. However, it is possible to implement the method without parent points, but it is more difficult. You can see an example of the trickier implementation here.
I'm implementing text predictions using a very simple Trie implementation, which is a slightly modified version of this code
It performs better than I initially expected, but I'm receiving an OutOfMemoryError frequently. Any ideas how can solve this problem by either:
increasing the memory designated to my app
optimizing the implementation to use less memory
or any other suggestions?
I've seen recommendations that the memory limitation problems could be avoided by using a native implementation of a part of the code, but I would prefer to stay in Java, if possible.
You could try turning on largeHeap in your manifest to see if it helps:
http://developer.android.com/guide/topics/manifest/application-element.html#largeHeap
By doing this.next = new Node[R]; the implementation allocates an array with 26 pointers to nodes on level 1, then 26^26 pointers to nodes on level 2, then 26^26^26 on level 3 and so on. That could be one reason you run out of memory.
You can try and change the implementation so that every Node has a HashMap of nodes with a small initial capacity, say 5. The HashMap will grow only when there's a real need - which will save some memory.
Another problem in that code is with the delete:
// delete a node
public void delete(Node node) {
for(int i = 0; i < R; i++) {
if(node.next != null) {
delete(node.next[i]);
}
}
node = null; // <-- this is not doing anything!
}
The reason it's not doing anything is that the reference to the node is passed by value in Java - so the real reference remains intact. What you should do instead is:
// delete a node
public void delete(Node node) {
for(int i = 0; i < R; i++) {
if(node.next != null) {
delete(node.next[i]);
node.next[i] = null; // <-- here you nullify the actual array item
} // which makes the object a good candidate for
// the next time GC will run
}
}
So it could also be a memory leak - in case you counted on delete to free space.
My dipslay function of linked list is as follows:-
public void display()
{
cur = first;
if(isEmpty())
{
System.out.println("no elements in the list");
}
else
{
System.out.println("elements in the list are:");
do {
System.out.println(first.data);
first = first.link;
} while(first.link!=null);
first=cur;
}
where curr and first are references of class node
public class node
{
int data;
Node link=null;
}
why is this function only printing the last element?
The function looks more or less correct. However why are you setting cur to first and then using first to do the iteration? Just use cur in the iteration so you don't have to reset first.
Check to make sure you're adding nodes into the list correctly. So if you think there are 3 elements in the list, run this in display():
System.out.println(first.data);
System.out.println(first.link.data);
System.out.println(first.link.link.data);
This is to check if your links are correct.
It is not possible to say for sure, but it is probable that your list actually contains only one element; i.e. that the code that creates the list is broken.
I should also point out that the display method should use a local variable to step through the elements. If you use an instance variable (e.g. first) you are liable to get different methods interfering with each other.
Finally, your test for the end of the list is incorrect. Think carefully about what first and first.link point at when the while test is executed.