
de.uni.freiburg.iig.telematik.jagal.traverse.Traverser Maven / Gradle / Ivy
package de.uni.freiburg.iig.telematik.jagal.traverse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.concurrent.ArrayBlockingQueue;
import de.invation.code.toval.types.HashList;
import de.invation.code.toval.validate.ParameterException;
import de.uni.freiburg.iig.telematik.jagal.graph.Graph;
import de.uni.freiburg.iig.telematik.jagal.graph.Vertex;
import de.uni.freiburg.iig.telematik.jagal.graph.exception.VertexNotFoundException;
public class Traverser implements Iterator{
private Traversable structure = null;
private TraversalMode mode = null;
private final List visited = new HashList<>();
private final ArrayBlockingQueue queue = new ArrayBlockingQueue<>(10);
private final Stack stack = new Stack<>();
protected List path = new ArrayList<>();
private final Map indexMap = new HashMap<>();
private boolean lastNodeAddedChildren;
public Traverser(Traversable traversableStructure, V startNode, TraversalMode mode){
structure = traversableStructure;
this.mode = mode;
setFirstNode(startNode);
}
private void setFirstNode(V startNode){
switch(mode){
case DEPTHFIRST: stack.push(startNode);
break;
case BREADTHFIRST: queue.offer(startNode);
break;
}
}
public Map getIndexMap(){
return Collections.unmodifiableMap(indexMap);
}
public void iterate(){
while(hasNext()){
next();
}
}
protected Traversable getStructure() {
return structure;
}
@Override
public boolean hasNext() {
switch(mode){
case DEPTHFIRST: return !stack.isEmpty();
case BREADTHFIRST: return !queue.isEmpty();
}
return false;
}
public List getPath(){
return Collections.unmodifiableList(path);
}
public List getVisitedNodes(){
return visited;
}
@Override
public V next() {
if(hasNext()){
Collection children = null;
try {
switch(mode){
case DEPTHFIRST:
visited.add(stack.peek());
indexMap.put(stack.peek(), visited.size()+1);
addToPath(stack.peek());
children = structure.getChildren(stack.pop());
for(V child: children){
childFoundDF(child);
}
break;
case BREADTHFIRST:
visited.add(queue.peek());
indexMap.put(queue.peek(), visited.size()+1);
addToPath(queue.peek());
children = structure.getChildren(queue.poll());
for(V child: children){
childFoundBF(child);
}
break;
default: return null;
}
checkPath();
lastNodeAddedChildren = children != null && !children.isEmpty();
}catch(VertexNotFoundException | ParameterException e){
e.printStackTrace();
}
return visited.get(visited.size()-1);
}
return null;
}
protected void childFoundDF(V child){
if(!visited.contains(child))
pushToStack(child);
}
protected void pushToStack(V node){
stack.push(node);
}
protected void childFoundBF(V child){
if(!visited.contains(child))
queue.offer(child);
}
protected void addToPath(V vertex){
path.add(vertex);
}
public V lastVisited(){
return visited.get(visited.size()-1);
}
protected void checkPath(){
// System.out.print(path + " -> ");
if(!lastNodeAddedChildren && !visited.isEmpty()){
Collection parentsOfLastAddedElement = null;
try {
parentsOfLastAddedElement = structure.getParents(lastVisited());
} catch (VertexNotFoundException | ParameterException e) {
e.printStackTrace();
}
Set pathElementsToRemove = new HashSet<>();
if (path.size() > 1 && parentsOfLastAddedElement != null) {
for (int i = path.size() - 2; i >= 0; i--) {
if (!parentsOfLastAddedElement.contains(path.get(i))) {
pathElementsToRemove.add(path.get(i));
} else {
break;
}
}
}
path.removeAll(pathElementsToRemove);
}
// System.out.println(path);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
public enum TraversalMode {DEPTHFIRST, BREADTHFIRST}
public static void main(String[] args) throws Exception {
Graph g = new Graph<>();
g.addVertex("1");
g.addVertex("2");
g.addVertex("3");
g.addVertex("4");
g.addVertex("5");
g.addEdge("1", "2");
g.addEdge("1", "3");
g.addEdge("2", "4");
g.addEdge("3", "4");
g.addEdge("3", "5");
Traverser> t = new Traverser<>(g, g.getVertex("1"), TraversalMode.DEPTHFIRST);
while(t.hasNext()){
System.out.println(t.next());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy