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

de.uni.freiburg.iig.telematik.jagal.traverse.TraversalUtils 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.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;

import de.invation.code.toval.validate.ParameterException;
import de.invation.code.toval.validate.Validate;
import de.uni.freiburg.iig.telematik.jagal.graph.exception.VertexNotFoundException;
import de.uni.freiburg.iig.telematik.jagal.traverse.Traverser.TraversalMode;
import de.uni.freiburg.iig.telematik.jagal.traverse.algorithms.SCCTarjan;

public class TraversalUtils {

        private static final ArrayBlockingQueue queue = new ArrayBlockingQueue<>(10);
        private static final Set visited = new HashSet<>();

        /**
         * Returns true, if the given traversable structure is
         * weakly connected.
         *
         * @param 
         * @param traversableStructure
         * @return
         */
        public static  boolean isWeaklyConnected(Traversable traversableStructure) {
                Validate.notNull(traversableStructure);
                for (V node : traversableStructure.getNodes()) {
                        Set nodes = new HashSet<>();
                        try {
                                weakConnectivityRec(traversableStructure, node, nodes);
                        } catch (ParameterException | VertexNotFoundException e) {
                                // shouldn't be happening
                                throw new RuntimeException(e);
                        }
                        if (nodes.size() < traversableStructure.getNodes().size()) {
                                return false;
                        }
                        break;
                }
                return true;
        }

        /**
         * Returns true, if the given traversable structure is
         * strongly connected.
         *
         * @param 
         * @param traversableStructure
         * @param node
         * @return
         */
        public static  boolean isStronglyConnected(Traversable traversableStructure, V node) {
                int visitedNodes = 0;
                Iterator iter = new Traverser<>(traversableStructure, node, TraversalMode.DEPTHFIRST);
                while (iter.hasNext()) {
                        iter.next();
                        visitedNodes++;
                }
                return visitedNodes == traversableStructure.nodeCount();
        }

        public static  Set> getStronglyConnectedComponents(Traversable traversableStructure) throws ParameterException {
                SCCTarjan tarjan = new SCCTarjan<>();
                return tarjan.execute(traversableStructure);
        }

        public static  Set getSiblings(Traversable traversableStructure, V node) throws VertexNotFoundException, ParameterException {
                Validate.notNull(traversableStructure);
                Set result = new HashSet<>();
                for (V parent : traversableStructure.getParents(node)) {
                        result.addAll(traversableStructure.getChildren(parent));
                }
                result.remove(node);
                return result;
        }

        /**
         * Checks, if queryNode is a predecessor of
         * baseNode.
         *
         * @param 
         * @param traversableStructure
         * @param baseNode Basic Node for predecessor search
         * @param queryNode Query Node for predecessor search
         * @return true if queryNode is a predecessor
         * of baseNode; false otherwise.
         * @throws VertexNotFoundException
         * @throws ParameterException
         */
        public static  boolean isPredecessor(Traversable traversableStructure, V queryNode, V baseNode) throws VertexNotFoundException, ParameterException {
                Validate.notNull(traversableStructure);
                visited.clear();
                visited.add(baseNode);
                queue.clear();
                for (V parent : traversableStructure.getParents(baseNode)) {
                        queue.offer(parent);
                }
                while (!queue.isEmpty()) {
                        if (queryNode.equals(queue.peek())) {
                                return true;
                        }
                        //Cast is safe since only objects of type V were added to the queue before.
                        for (V parent : traversableStructure.getParents((V) queue.peek())) {
                                if (!visited.contains(parent) && !queue.contains(parent)) {
                                        queue.add(parent);
                                }
                        }
                        visited.add(queue.poll());
                }
                return false;
        }

        /**
         * Checks, if queryNode<T> is a successor of
         * baseNode<T>.
         *
         * @param 
         * @param traversableStructure
         * @param baseNode Basic Node<T> for successor search
         * @param queryNode Query Node<T> for successor search
         * @return true if queryNode<T> is a
         * successor of baseNode<T>; false
         * otherwise.
         * @throws VertexNotFoundException
         * @throws ParameterException
         */
        public static  boolean isSuccessor(Traversable traversableStructure, V queryNode, V baseNode) throws VertexNotFoundException, ParameterException {
                Validate.notNull(traversableStructure);
                visited.clear();
                visited.add(baseNode);
                queue.clear();
                for (V child : traversableStructure.getChildren(baseNode)) {
                        queue.offer(child);
                }
                while (!queue.isEmpty()) {
                        if (queryNode.equals(queue.peek())) {
                                return true;
                        }
                        //Cast is safe since only objects of type V were added to the queue before.
                        for (V child : traversableStructure.getChildren((V) queue.peek())) {
                                if (!visited.contains(child) && !queue.contains(child)) {
                                        queue.add(child);
                                }
                        }
                        visited.add(queue.poll());
                }
                return false;
        }

//	public static , U> Set getPredecessorsFor(AbstractGraph graph, V vertex) throws VertexNotFoundException
        public static  Set getPredecessorsFor(Traversable traversableStructure, V startNode) throws VertexNotFoundException, ParameterException {
                Validate.notNull(traversableStructure);
                Set visitedNodes = new HashSet<>();
                visitedNodes.add(startNode);
                queue.clear();
                for (V parent : traversableStructure.getParents(startNode)) {
                        queue.offer(parent);
                }
                while (!queue.isEmpty()) {
                        //Cast is safe since only objects of type V were added to the queue before.
                        for (V parent : traversableStructure.getParents((V) queue.peek())) {
                                if (!visitedNodes.contains(parent) && !queue.contains(parent)) {
                                        queue.add(parent);
                                }
                        }
                        visitedNodes.add((V) queue.poll());
                }
                visitedNodes.remove(startNode);
                return visitedNodes;
        }

//	public static , U> Set getSuccessorsFor(AbstractGraph graph, V vertex) throws GraphException
        public static  Set getSuccessorsFor(Traversable traversableStructure, V startNode) throws VertexNotFoundException, ParameterException {
                Validate.notNull(traversableStructure);
                Set visitedNodes = new HashSet<>();
                visitedNodes.add(startNode);
                queue.clear();
                for (V child : traversableStructure.getChildren(startNode)) {
                        queue.offer(child);
                }
                while (!queue.isEmpty()) {
                        //Cast is safe since only objects of type V were added to the queue before.
                        for (V child : traversableStructure.getChildren((V) queue.peek())) {
                                if (!visitedNodes.contains(child) && !queue.contains(child)) {
                                        queue.add(child);
                                }
                        }
                        visitedNodes.add((V) queue.poll());
                }
                visitedNodes.remove(startNode);
                return visitedNodes;
        }

//	public static , U> boolean isVertexInCycle(AbstractGraph graph, V vertex) throws VertexNotFoundException{
        /**
         * Checks if a vertex is contained in a cycle.
* In case the given vertex is in a cycle, it is a predecessor of * itself. * * @param * @param traversableStructure The graph that contains the vertex. * @param node The vertex for which the property is checked. * @return true if the given vertex is contained in a * cycle;
* false. * @throws VertexNotFoundException If the graph does not contain the * vertex. * @throws ParameterException */ public static boolean isNodeInCycle(Traversable traversableStructure, V node) throws VertexNotFoundException, ParameterException { Validate.notNull(traversableStructure); return isPredecessor(traversableStructure, node, node); } /** * Checks if a traversable structure contains a cycle. * * @param * @param traversableStructure The graph to check for cycles. * @return true if the given structure contains at least * one cycle, false otherwise. * @throws ParameterException */ public static boolean hasCycle(Traversable traversableStructure) throws ParameterException { Validate.notNull(traversableStructure); for (V node : traversableStructure.getNodes()) { try { if (isNodeInCycle(traversableStructure, node)) { return true; } } catch (VertexNotFoundException e) { throw new RuntimeException(e); } } return false; } // public static , U> ArrayBlockingQueue> getDirectedPathsFor(AbstractGraph graph, V sourceVertex, V targetVertex) throws VertexNotFoundException{ /** * Returns a list of paths that lead from sourceVertex to targetVertex. * * @param * @param traversableStructure * @param sourceNode The source vertex for the desired paths. * @param targetNode The target vertex for the desired paths. * @return A list of all paths leading from sourceVertex to * targetVertex. * @throws VertexNotFoundException If the graph does not contain the * given vertexes. * @throws ParameterException */ public static ArrayBlockingQueue> getDirectedPathsFor(Traversable traversableStructure, V sourceNode, V targetNode) throws VertexNotFoundException, ParameterException { Validate.notNull(traversableStructure); return getDirectedPathsFor(traversableStructure, Arrays.asList(sourceNode), targetNode); } // public static , U> ArrayBlockingQueue> getDirectedPathsFor(AbstractGraph graph, List sourceVertexes, V targetVertex) throws VertexNotFoundException{ /** * Returns a list of paths leading from one source vertex to * targetVertex. * * @param * @param traversableStructure The graph that contains the vertexes. * @param sourceNodes The source vertexes for the desired paths. * @param targetNode The target vertex for the desired paths. * @return A list of all paths leading from sourceVertex to * targetVertex. * @throws VertexNotFoundException If the graph does not contain the * given vertexes. * @throws ParameterException */ public static ArrayBlockingQueue> getDirectedPathsFor(Traversable traversableStructure, List sourceNodes, V targetNode) throws VertexNotFoundException, ParameterException { Validate.notNull(traversableStructure); ArrayBlockingQueue> finalPaths = new ArrayBlockingQueue<>(10); if (sourceNodes.contains(targetNode)) { return finalPaths; } ArrayBlockingQueue> tempPaths = new ArrayBlockingQueue<>(10); List firstPath = new ArrayList<>(); firstPath.add(targetNode); tempPaths.offer(firstPath); while (!tempPaths.isEmpty()) { Collection parents = traversableStructure.getParents(tempPaths.peek().get(tempPaths.peek().size() - 1)); for (V v : parents) { List newPath = new ArrayList<>(tempPaths.peek()); if (!tempPaths.peek().contains(v)) { newPath.add(v); if (sourceNodes.contains(v)) { finalPaths.add(newPath); } else { tempPaths.offer(newPath); } } } tempPaths.poll(); } for (List l : finalPaths) { Collections.reverse(l); } return finalPaths; } private static void weakConnectivityRec(Traversable graph, V v, Set nodes) throws ParameterException, VertexNotFoundException { Set neighbours = new HashSet<>(); neighbours.addAll(graph.getChildren(v)); neighbours.addAll(graph.getParents(v)); for (V n : neighbours) { if (false == nodes.contains(n)) { nodes.add(n); weakConnectivityRec(graph, n, nodes); } } } }