All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.uni.freiburg.iig.telematik.jagal.traverse.Traverser Maven / Gradle / Ivy

Go to download

JAGAL provides implementations for directed graphs (weighted and unweighted) and various types of transition systems as well as utils for graph traversal and modification.

The newest version!
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){
				throw new RuntimeException(e);
			}
			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) {
				throw new RuntimeException(e);
			}
			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