/// <summary> /// Computes the offline least common ancestor between pairs of vertices in a rooted tree /// using Tarjan algorithm. /// </summary> /// <remarks> /// Reference: /// Gabow, H. N. and Tarjan, R. E. 1983. A linear-time algorithm for a special case of disjoint set union. In Proceedings of the Fifteenth Annual ACM Symposium on theory of Computing STOC '83. ACM, New York, NY, 246-251. DOI= http://doi.acm.org/10.1145/800061.808753 /// </remarks> /// <typeparam name="TVertex">type of the vertices</typeparam> /// <typeparam name="TEdge">type of the edges</typeparam> /// <param name="visitedGraph"></param> /// <param name="root"></param> /// <param name="pairs"></param> /// <returns></returns> public static TryFunc <SEquatableEdge <TVertex>, TVertex> OfflineLeastCommonAncestorTarjan <TVertex, TEdge>( #if !NET20 this #endif IVertexListGraph <TVertex, TEdge> visitedGraph, TVertex root, IEnumerable <SEquatableEdge <TVertex> > pairs ) where TEdge : IEdge <TVertex> { Contract.Requires(visitedGraph != null); Contract.Requires(root != null); Contract.Requires(pairs != null); Contract.Requires(visitedGraph.ContainsVertex(root)); Contract.Requires(Enumerable.All(pairs, p => visitedGraph.ContainsVertex(p.Source))); Contract.Requires(Enumerable.All(pairs, p => visitedGraph.ContainsVertex(p.Target))); var algo = new TarjanOfflineLeastCommonAncestorAlgorithm <TVertex, TEdge>(visitedGraph); algo.Compute(root, pairs); var ancestors = algo.Ancestors; return(delegate(SEquatableEdge <TVertex> pair, out TVertex value) { return ancestors.TryGetValue(pair, out value); }); }
public static TryFunc <TVertex, IEnumerable <TEdge> > TreeCyclePoppingRandom <TVertex, TEdge>( #if !NET20 this #endif IVertexListGraph <TVertex, TEdge> visitedGraph, TVertex root, IMarkovEdgeChain <TVertex, TEdge> edgeChain) where TEdge : IEdge <TVertex> { Contract.Requires(visitedGraph != null); Contract.Requires(root != null); Contract.Requires(visitedGraph.ContainsVertex(root)); Contract.Ensures(Contract.Result <TryFunc <TVertex, IEnumerable <TEdge> > >() != null); var algo = new CyclePoppingRandomTreeAlgorithm <TVertex, TEdge>(visitedGraph, edgeChain); var predecessorRecorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessorRecorder.Attach(algo)) algo.Compute(root); var predecessors = predecessorRecorder.VertexPredecessors; return(delegate(TVertex v, out IEnumerable <TEdge> edges) { return EdgeExtensions.TryGetPath(predecessors, v, out edges); }); }
public static TryFunc <TVertex, IEnumerable <TEdge> > TreeCyclePoppingRandom <TVertex, TEdge> (this IVertexListGraph <TVertex, TEdge> visitedGraph, TVertex root) where TEdge : IEdge <TVertex> { Contract.Requires(visitedGraph != null); Contract.Requires(root != null); Contract.Requires(visitedGraph.ContainsVertex(root)); Contract.Ensures(Contract.Result <TryFunc <TVertex, IEnumerable <TEdge> > >() != null); return(TreeCyclePoppingRandom(visitedGraph, root, new NormalizedMarkovEdgeChain <TVertex, TEdge>())); }
/// <summary> /// Computes a depth first tree. /// </summary> /// <typeparam name="TVertex">The type of the vertex.</typeparam> /// <typeparam name="TEdge">The type of the edge.</typeparam> /// <param name="visitedGraph">The visited graph.</param> /// <param name="root">The root.</param> /// <returns></returns> public static TryFunc <TVertex, IEnumerable <TEdge> > TreeDepthFirstSearch <TVertex, TEdge> (this IVertexListGraph <TVertex, TEdge> visitedGraph, TVertex root) where TEdge : IEdge <TVertex> { Contract.Requires(visitedGraph != null); Contract.Requires(root != null); Contract.Requires(visitedGraph.ContainsVertex(root)); Contract.Ensures(Contract.Result <TryFunc <TVertex, IEnumerable <TEdge> > >() != null); var algo = new DepthFirstSearchAlgorithm <TVertex, TEdge>(visitedGraph); var predecessorRecorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessorRecorder.Attach(algo)) algo.Compute(root); var predecessors = predecessorRecorder.VertexPredecessors; return(delegate(TVertex v, out IEnumerable <TEdge> edges) { return EdgeExtensions.TryGetPath(predecessors, v, out edges); }); }