/// <inheritdoc /> protected override void InternalCompute() { // Adding vertices to the new graph // and pushing filtered vertices in queue var filteredVertices = new Queue <TVertex>(); foreach (TVertex vertex in VisitedGraph.Vertices) { CondensedGraph.AddVertex(vertex); if (!VertexPredicate(vertex)) { filteredVertices.Enqueue(vertex); } } // Adding all edges foreach (TEdge edge in VisitedGraph.Edges) { var mergedEdge = new MergedEdge <TVertex, TEdge>(edge.Source, edge.Target); mergedEdge.Edges.Add(edge); CondensedGraph.AddEdge(mergedEdge); } // Remove vertices while (filteredVertices.Count > 0) { TVertex filteredVertex = filteredVertices.Dequeue(); // Do the cross product between in-edges and out-edges MergeVertex(filteredVertex); } }
private void MergeVertex([NotNull] TVertex vertex) { Debug.Assert(vertex != null); // Get in-edges and out-edges var inEdges = new List <MergedEdge <TVertex, TEdge> >(CondensedGraph.InEdges(vertex)); var outEdges = new List <MergedEdge <TVertex, TEdge> >(CondensedGraph.OutEdges(vertex)); // Remove vertex CondensedGraph.RemoveVertex(vertex); // Add condensed edges foreach (MergedEdge <TVertex, TEdge> inEdge in inEdges) { if (EqualityComparer <TVertex> .Default.Equals(inEdge.Source, vertex)) { continue; } foreach (MergedEdge <TVertex, TEdge> outEdge in outEdges) { if (EqualityComparer <TVertex> .Default.Equals(outEdge.Target, vertex)) { continue; } var newEdge = MergedEdge <TVertex, TEdge> .Merge(inEdge, outEdge); CondensedGraph.AddEdge(newEdge); } } }
/// <summary> /// Merges the given two edges. /// </summary> /// <param name="inEdge">First edge.</param> /// <param name="outEdge">Second edge.</param> /// <returns>The merged edge.</returns> public static MergedEdge <TVertex, TEdge> Merge( MergedEdge <TVertex, TEdge> inEdge, MergedEdge <TVertex, TEdge> outEdge) { if (inEdge is null) { throw new ArgumentNullException(nameof(inEdge)); } if (outEdge is null) { throw new ArgumentNullException(nameof(outEdge)); } var newEdge = new MergedEdge <TVertex, TEdge>(inEdge.Source, outEdge.Target) { _edges = new List <TEdge>(inEdge.Edges.Count + outEdge.Edges.Count) }; newEdge._edges.AddRange(inEdge._edges); newEdge._edges.AddRange(outEdge._edges); return(newEdge); }