I have been trying to make simple DFS using object oriented design and by implementing the Iterator class. But DFS does not work as it should.
I have almost tried everything that I could but I was not able to make this work.
Also I couldn't find much relevant info on internet about the type of code I am trying.
I have two interfaces Vertex and Graph.
Following is the code I am trying:
public class GraphIterator implements Iterator<Vertex> {
private Graph g;
private Vertex v;
private Stack<Vertex> stack;
private Set<Vertex> colored;
public GraphIterator(Graph g, Vertex v) {
this.g = g;
this.v = v;
stack = new Stack<>();
colored = new TreeSet<>();
stack.push(v);
colored.add(v);
}
#Override
public boolean hasNext() {
return stack.isEmpty();
}
#Override
public Vertex next() {
Vertex u = stack.pop();
for(Vertex vertex : g.getNeighbours(u)) {
if(vertex != null && !colored.contains(vertex))
stack.add(vertex);
}
return stack.pop();
}
}
This is the code in main() I am trying to test with:
GraphClass g = new GraphClass();
Vertex v = new VertexClass(0);
Vertex w = new VertexClass(1);
g.addVertex(v);
g.addVertex(w);
g.addEdge(v, w);
Iterator<Vertex> it = new GraphIterator(g, v);
System.out.println(v+" vs "+it.next());
System.out.println(it.hasNext());
System.out.println(w+" vs "+it.next());
I know I am doing something wrong with the DFS algorithm but I am not able to quite understand what and where am I going wrong?
I am mostly sure that I am doing something wrong with DFS algorithm, which needs to be implemented using overriden methods from Iterator class. I would also appreciate some tips of how to do so.
I would appreciate if someone could help me in this algorithm.
Possible improvements to the code in question:
In next(), maybe just return u;, instead of return stack.pop();.
Because that would pop 2 elements in a single call to next(), and with the second's neighbor vertices unchecked.
LinkedList might be a better choice than Stack here.
Since there seems has no need for concurrent control.
BTW:
LinkedList is also a stack, it's not thread-safe; while Stack is thread-safe.
(If could post the code in a block, that others can copy & run directly, and see the output, then probably a better answer could be provided.)
Related
I am using JGraphT for holding about 150,000 (or thereabouts) vertices in an in-memory graph. This a directed graph and each vertex is going to have { 0 | 1 } outgoing edges.
I want to find retrieve the set of vertices which have no outgoing edges. Here's what I have attempted:
import io.vavr.Tuple;
import io.vavr.Tuple2;
import io.vavr.Tuple3;
import io.vavr.control.Option;
import org.jgrapht.Graphs;
import org.jgrapht.graph.SimpleDirectedGraph;
import org.jgrapht.graph.concurrent.AsSynchronizedGraph;
public Option<io.vavr.collection.Set<Employee>>
pickEmployeesWithNoSupervisor(Integer companyID) {
// holdingCompany is of type: SimpleDirectedGraph<Employee,String>
// edge is a simple string: "reportingTo"
// Retrieve from a Map, initialized earlier, elsewhere
var holdingCompany = this.allCompanies.get(companyID);
if (holdingCompany == null)
return (Option.none());
else {
var vertices = holdingCompany.vertexSet();
io.vavr.collection.Set<Employee> accumulator = io.vavr.collection.HashSet.empty();
var allNoReportingToEmployees =
io.vavr.collection.HashSet.ofAll(vertices)
.foldLeft(accumulator,(accu,nextEmp) -> {
var hasPredecessors =
Graphs.vertexHasPredecessors(mayBeAKnownCompany,nextEmp);
return (!hasPredecessors ? accu.add(nextEmp) : accu) ;
});
return Option.some(allNoReportingToEmployees);
}
}
public class Employee {
private final Integer empID;
public Employee(Integer empID) {
this.empID = empID;
}
#Override
public boolean equals(Object o) {
// ..
}
#Override
public int hashCode() {
// ..
}
}
This perhaps, is a naive attempt. I am keen to know if there is any better, more idiomatic and more efficient way of doing this.
I'm not quite sure what's going on in the code, but the following would work fine:
Set<Employee> verticesWithoutSucc = myGraph.vertexSet().stream().filter(v -> !Graphs.vertexHasSuccessors(myGraph,v)).collect(Collectors.toSet());
Note that, to get all vertices without outgoing arcs, you must use vertexHasSuccessors(.) as opposed to vertexHasPredecessors(.).
Note that the vertexHasSuccessors method simply invokes !graph.outgoingEdgesOf(vertex).isEmpty();
This approach should be efficient since it runs in O(n) time, where n is the number of customers. If you want even better performance, you could keep track of all the vertices without an outgoing arc during the construction of the graph. That is, keep a set of all the vertices in your graph, and each time you add an arc (i,j), remove vertex i from your set. As such you can always query the set of vertices without outgoing arcs in constant time.
Finally, for large graphs, you could have a look at the optimized graph implementations in the jgrapht-opt package.
Briefing:
I have implemented three search algorithms to break a lock. A lock can be broken by the actions shaking, pulling, pulling, or poking. These are 4 methods can be applied to the given lock. This lock has a length anywhere from 1 to 16, meaning that if the length was 16, 16 back to back actions in the correct order will need to be done. For example, a length two lock that can be unlocked by pulling and then poking will need to be pulled and then poked. The data structure devised to solve this is a tree where each parent has 4 children that correspond to actions. These search algorithms climb the tree in many ways to find the correct solution to break a given lock.
Set-up of Solution & Problem:
I have one class called Tree that has 3 Search algorithms: Breadth-First, Depth-Limited, and Iterative-Deepening Search. In this same class, I have 2 helper methods to help each algorithm break a lock combination (check, which checks if the sequence of actions up to the child being viewed is a solution, and depth, which determines the depth of a given child). I also have a Node class that is used by Tree to create the root and subsequent children. Now, I want to store each algorithm in an array, so that I can iterate over each algorithm, and collect data for each algorithm from a main function. I have looked a little into the Command Pattern regarding Polymorphism. It seems that it might work, but I am confused on how I would have to organize my current solution to adapt. Would I need to turn each algorithm methodintoPerhaps there is a better solution than the Command Pattern. I can create a main in the Tree and simply call each algorithm there, but that seems a bit "sloppy" to me. Any suggestions?
The code below is just to get a gist of my current format. I have would rather simplify the code to show organization to best get at how I can adapt to utilize something like the Command Pattern to store each algorithm in an array to iterate over each and collect certain data.
public class Tree {
Node root = new Node(0, null);
TheLock lock = new TheLock("Michael");
Tree()
{this.root = root;}
public int runBST(TheLock lock){
}
public int it2runIDS(TheLock lock){
}
public int runDLS(int depthlim, TheLock lock){
}
public boolean check(Node child,TheLock lock) {
}
public int depth(Node child, int currd) {
}
}
public class Node {
int action;
Node parent;
public Node(int action, Node parent) {
this.action = action;
this.parent = parent;
}
}
I would suggest the Visitor pattern, if you had to pick a specific one. Each algorithm will visit one lock and try to break it.
The following approach is not exactly an implementation of said pattern, but it shows one way you can store a list of objects with a similar method
Start with an Interface, and some model object to hold state of a Lock
public interface LockAlgorithm {
// returns true if lock is broken
boolean break(Lock lock);
}
Some implementation, repeat for other types
public class BFSLockAlgorithm implements LockAlgorithm {
#Override
public boolean break(Lock lock) {
return false; // TODO: implement
}
}
Then, you store a list of interface implementations to loop over and apply on some Lock object
// in main
List<LockAlgorithm> algos = Arrays.asList(new BFSLockAlgorithm());
Lock l = new Lock("data");
for (LockAlgorithm a : algos) {
if (l.isLocked()) {
if (a.break(l)) System.out.print("success");
}
}
if (l.isLocked()) {
System.out.print("failed");
}
The inverted way to implement the link above would be to allow for boolean Lock.unlockWith(LockAlgorithm a)
Don't forget to do adequate unit testing for each LockAlgorithm first
So, basically this is what I have so far.
public List<String> cycleSearch(Graph<String,String> g) throws Exception{
List<String> list = null;
Graph<String,String> auxG = g;
for(String aux : g.getVertices()){
String aux2 = aux;
if(g.degree(aux)>1){
if(auxG.removeVertex(aux2)){
for(String d : g.getSuccessors(aux2)){
for(String a : g.getSuccessors(aux)){
if(a!=d){
list = findPath(auxG,d,a);
if(list!=null){
list.add(0,aux);
list.add(aux);
return list;
}
}
}
}
}
}
auxG = g;
}
return null;
}
What the method does is basically to search for a cycle in a hypergraph based on JUNG.
The idea it's to recieve a graph on the parameters and then create a variable (as the same type) to later remove a vertex from it without making any changes on the original graph, just in case a cycle isn't found. That way I can use a method called findPath(,,), once the vertex is removed. The method will 'create' another path without walking through the removed vertex.
My compiler says there is problem right here:
for(String d : g.getSuccessors(aux2))
I've been programming graphs in Java(JUNG) for only 1 month.
HELP
There is a bug in JUNG that this code has turned--getSuccessors() should be returning an empty collection if the graph does not have the vertex, rather than returning null, which is what SetHypergraph's implementation does. Sorry about that. (In general, you can avoid this by wrapping the getSuccessors(x) inside a containsVertex(x) if statement.)
However, the reason why you're encountering this bug is that you're doing at least a couple of things that do not make sense:
(1) you're assigning auxG to g (so they're referencing the same object); this is misleading and not helpful.
Similarly, you're assigning aux2 to aux, which is also misleading.
(2) you're removing aux[2] from auxG and then asking for aux2's successors in auxG. aux2 will not have any successors in auxG once it's removed.
(3) Since aux2 and aux are the same vertex, your innermost loop will also not do anything useful for the same reason; there will be no successors.
You need to rethink your entire algorithm, because this simply is not correct as designed.
Instead of using null to represnt no successors, you could just use an empty list, and thus avoid the NullPointerException. Replace return null; with return new LinkedList<>();.
I have written a code for deleting all elements of tree.
Need suggestions for following:
In reverseTreeStack method, Can I design without using stack method parameter?
Can I design the entire code in 1 method with better design?
UPDATE : Changed return type of reverseTreeStack to void.Removed additional variable for stack.
public class DeleteTree {
public static void deleteTree(BinaryTreeNode root)
{
Stack stack = new Stack();
reverseTreeStack(stack, root);
while (!stack.isEmpty())
{
BinaryTreeNode node = (BinaryTreeNode)stack.pop();
System.out.println("---------Deleting----------->" + node.getData());
node = null;
}
}
public static void reverseTreeStack(Stack stack,BinaryTreeNode root)
{
if (root != null)
{
stack.push(root);
reverseTreeStack(stack,root.getLeft());
reverseTreeStack(stack, root.getRight());
}
}
}
Why do you need to do this? If I recall correctly, the JVM can free resources once there are no available references to the resource, so just setting your root node to be null should free the whole tree.
I think, James is right, but if you want to practice the tree traversal, or if you want to implement this in a language where you need to free memory manually, then use recursion:
void deleteTree(TreeNode node)
{
if(node==null)return;
deleteTree(node.getLeft());
deleteTree(node.getRight());
System.out.printline("Deleting: "+node.getData())
node = null;
}
Also take a look at Postorder Traversal (thats the only one, that works for deleting)
1) I think you can kill the return value and make it a void method as you are directly manipulating the stack. So just do
Stack stack = new Stack();
reverseTreeStack(stack, root);
// Now just use stack
2) Don't condense things into one method. Breaking things out into more methods will make your code easier to navigate and understand. The less each function is responsible for, the more sense it will make to someone reading it.
Well your reverseTreeStack method can potentially give you a StackOverflowError if your tree is too large, so using a loop instead of recursion there might be a better choice (unless you know for a fact that your trees will never be that large).
Also, why are you "deleting" every node? (node = null actually just removes the reference you have just in that method...) Generally just forgetting the root (root = null) will delete your whole tree if you're structuring it in the classic way of Node(parent, leftChild, rightChild) and not storing pointers to nodes anywhere else.
Am trying to solve a labyrinth by DFS, using adj List to represent the vertices and edges of the graph. In total there are 12 nodes (3 rows[A,B,C] * 4 cols[0,..,3]). My program starts by saving all the vertex labels (A0,..C3), so far so good, then checks the adjacent nodes, also no problems, if movement is possible, it proceeds to create the edge, here its where al goes wrong.
adjList[i].add(vList[j].label);
I used the debugger and found that vList[j].label is not null it contains a correct string (ie. "B1"). The only variables which show null are in adjList[i], which leads me to believe i have implemented it wrongly. this is how i did it.
public class GraphList {
private ArrayList<String>[] adjList;
...
public GraphList(int vertexcount) {
adjList = (ArrayList<String>[]) new ArrayList[vertexCount];
...
}
...
public void addEdge(int i, int j) {
adjList[i].add(vList[j].label); //NULLPOINTEREXCEPTION HERE
}
...
}
I will really appreaciate if anyone can point me on the right track regrading to what its going wrong... Thanks!
You've created the array, but you still need to go through and create the ArrayList objects. As it's written, adjList[i] returns null because nothing has been assigned to it yet.
I see that you created the container but are you sure you populated the list with elements?
Why don't you add assert((adjList[i] != null) && (adjList[j] != null)) to addEdge just to be sure either of them are not null. Run with java -ea ...