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

com.salesforce.jgrapht.traverse.TopologicalOrderIterator Maven / Gradle / Ivy

Go to download

This project contains the apt processor that implements all the checks enumerated in @Verify. It is a self contained, and shaded jar.

There is a newer version: 2.0.7
Show newest version
/*
 * (C) Copyright 2004-2017, by Marden Neubert and Contributors.
 *
 * JGraphT : a free Java graph-theory library
 *
 * This program and the accompanying materials are dual-licensed under
 * either
 *
 * (a) the terms of the GNU Lesser General Public License version 2.1
 * as published by the Free Software Foundation, or (at your option) any
 * later version.
 *
 * or (per the licensee's choosing)
 *
 * (b) the terms of the Eclipse Public License v1.0 as published by
 * the Eclipse Foundation.
 */
package com.salesforce.jgrapht.traverse;

import java.util.*;

import com.salesforce.jgrapht.*;
import com.salesforce.jgrapht.alg.*;
import com.salesforce.jgrapht.util.*;

/**
 * Implements topological order traversal for a directed acyclic graph. A topological sort is a
 * permutation p of the vertices of a graph such that an edge (i,j) implies that
 * i appears before j in p (Skiena 1990, p. 208). See also
 * 
 * http://mathworld.wolfram.com/TopologicalSort.html.
 *
 * 

* See "Algorithms in Java, Third Edition, Part 5: Graph Algorithms" by Robert Sedgewick and "Data * Structures and Algorithms with Object-Oriented Design Patterns in Java" by Bruno R. Preiss for * implementation alternatives. The latter can be found online at * http://www.brpreiss.com/books/opus5/ *

* *

* For this iterator to work correctly the graph must be acyclic, and must not be modified during * iteration. Currently there are no means to ensure that, nor to fail-fast; the results with cyclic * input (including self-loops) or concurrent modifications are undefined. To precheck a graph for * cycles, consider using {@link com.salesforce.jgrapht.alg.CycleDetector} or * {@link KosarajuStrongConnectivityInspector}. *

* * @param the graph vertex type * @param the graph edge type * * @author Marden Neubert * @since Dec 18, 2004 */ public class TopologicalOrderIterator extends CrossComponentIterator { private Queue queue; private Map inDegreeMap; /** * Creates a new topological order iterator over the directed graph specified, with arbitrary * tie-breaking in case of partial order. Traversal will start at one of the graph's * sources. See the definition of source at * * http://mathworld.wolfram.com/Source.html. * * @param dg the directed graph to be iterated. */ public TopologicalOrderIterator(DirectedGraph dg) { this(dg, new LinkedListQueue<>()); } /** * Creates a new topological order iterator over the directed graph specified, with a * user-supplied queue implementation to allow customized control over tie-breaking in case of * partial order. Traversal will start at one of the graph's sources. See the definition * of source at * http://mathworld.wolfram.com/Source.html. * * @param dg the directed graph to be iterated. * @param queue queue to use for tie-break in case of partial order (e.g. a PriorityQueue can be * used to break ties according to vertex priority); must be initially empty */ public TopologicalOrderIterator(DirectedGraph dg, Queue queue) { this(dg, queue, new HashMap<>()); } // NOTE: This is a hack to deal with the fact that CrossComponentIterator // needs to know the start vertex in its constructor private TopologicalOrderIterator( DirectedGraph dg, Queue queue, Map inDegreeMap) { this(dg, initialize(dg, queue, inDegreeMap)); this.queue = queue; this.inDegreeMap = inDegreeMap; // empty queue for non-empty graph would indicate presence of // cycles (no roots found) assert dg.vertexSet().isEmpty() || !queue.isEmpty(); } // NOTE: This is intentionally private, because starting the sort "in the // middle" doesn't make sense. private TopologicalOrderIterator(DirectedGraph dg, V start) { super(dg, start); } /** * @see CrossComponentIterator#isConnectedComponentExhausted() */ @Override protected boolean isConnectedComponentExhausted() { // FIXME jvs 25-Apr-2005: This isn't correct for a graph with more than // one component. We will actually exhaust a connected component // before the queue is empty, because initialize adds roots from all // components to the queue. return queue.isEmpty(); } /** * @see CrossComponentIterator#encounterVertex(Object, Object) */ @Override protected void encounterVertex(V vertex, E edge) { putSeenData(vertex, null); decrementInDegree(vertex); } /** * @see CrossComponentIterator#encounterVertexAgain(Object, Object) */ @Override protected void encounterVertexAgain(V vertex, E edge) { decrementInDegree(vertex); } /** * @see CrossComponentIterator#provideNextVertex() */ @Override protected V provideNextVertex() { return queue.remove(); } /** * Decrements the in-degree of a vertex. * * @param vertex the vertex whose in-degree will be decremented. */ private void decrementInDegree(V vertex) { ModifiableInteger inDegree = inDegreeMap.get(vertex); if (inDegree.value > 0) { inDegree.value--; if (inDegree.value == 0) { queue.offer(vertex); } } } /** * Initializes the internal traversal object structure. Sets up the internal queue with the * directed graph vertices and creates the control structure for the in-degrees. * * @param dg the directed graph to be iterated. * @param queue initializer for queue * @param inDegreeMap initializer for inDegreeMap * * @return start vertex */ private static V initialize( DirectedGraph dg, Queue queue, Map inDegreeMap) { for (V vertex : dg.vertexSet()) { int inDegree = dg.inDegreeOf(vertex); inDegreeMap.put(vertex, new ModifiableInteger(inDegree)); if (inDegree == 0) { queue.offer(vertex); } } if (queue.isEmpty()) { return null; } else { return queue.peek(); } } // NOTE jvs 22-Dec-2006: For JDK1.4-compatibility, we can't assume // that LinkedList implements Queue, since that wasn't introduced // until JDK1.5, so use an adapter here. Move this to // top-level in com.salesforce.jgrapht.util if anyone else needs it. private static class LinkedListQueue extends LinkedList implements Queue { private static final long serialVersionUID = 4217659843476891334L; @Override public T element() { return getFirst(); } @Override public boolean offer(T o) { return add(o); } @Override public T peek() { if (isEmpty()) { return null; } return getFirst(); } @Override public T poll() { if (isEmpty()) { return null; } return removeFirst(); } @Override public T remove() { return removeFirst(); } } } // End TopologicalOrderIterator.java




© 2015 - 2025 Weber Informatics LLC | Privacy Policy