private void ExploreAdjacentEdges([NotNull] TVertex u) { foreach (TEdge edge in VisitedGraph.AdjacentEdges(u)) { bool reversed = edge.Target.Equals(u); TVertex v = reversed ? edge.Source : edge.Target; OnExamineEdge(edge); GraphColor vColor = VerticesColors[v]; if (vColor == GraphColor.White) { OnTreeEdge(edge, reversed); VerticesColors[v] = GraphColor.Gray; OnDiscoverVertex(v); _vertexQueue.Enqueue(v); } else { OnNonTreeEdge(edge, reversed); if (vColor == GraphColor.Gray) { OnGrayTarget(edge, reversed); } else { OnBlackTarget(edge, reversed); } } } }
public void Visit(TVertex u, int depth) { if (depth > this.maxDepth) { return; } if (u == null) { throw new ArgumentNullException("u"); } var cancelManager = this.Services.CancelManager; if (cancelManager.IsCancelling) { return; } VertexColors[u] = GraphColor.Gray; OnDiscoverVertex(u); TVertex v = default(TVertex); foreach (var e in VisitedGraph.AdjacentEdges(u)) { if (cancelManager.IsCancelling) { return; } OnExamineEdge(e); if (u.Equals(e.Source)) { v = e.Target; } else { v = e.Source; } GraphColor c = VertexColors[v]; if (c == GraphColor.White) { OnTreeEdge(e); Visit(v, depth + 1); } else if (c == GraphColor.Gray) { OnBackEdge(e); } else { OnForwardOrCrossEdge(e); } } VertexColors[u] = GraphColor.Black; OnFinishVertex(u); }
private void MarkAdjacentAsUnavailable(TVertex vertex, bool[] available) { foreach (TEdge adjacentEdges in VisitedGraph.AdjacentEdges(vertex)) { TVertex adjacentVertex = adjacentEdges.GetOtherVertex(vertex); if (Colors[adjacentVertex].HasValue) { available[Colors[adjacentVertex].Value] = true; } } }
private void ResetAdjacentAsAvailable(TVertex vertex, bool[] available) { foreach (TEdge adjacentEdges in VisitedGraph.AdjacentEdges(vertex)) { if (Colors[adjacentEdges.GetOtherVertex(vertex)].HasValue) { // ReSharper disable once PossibleInvalidOperationException, Justification: Was assigned a color just before var usedColor = Colors[adjacentEdges.GetOtherVertex(vertex)].Value; available[usedColor] = false; } } }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; while (_heap.Count != 0) { if (cancelManager.IsCancelling) { return; } TVertex vertex = _heap.Dequeue(); int degree = Degrees[vertex]; // 0 => isolated vertex // 1 => single adjacent edge if (degree != 0 && degree != 1 && !AllowCyclicGraph) { throw new NonAcyclicGraphException(); } _sortedVertices.Add(vertex); OnVertexAdded(vertex); // Update the count of its adjacent vertices UpdateAdjacentDegree(vertex); } SortedVertices = _sortedVertices.ToArray(); #region Local function void UpdateAdjacentDegree(TVertex vertex) { foreach (TEdge edge in VisitedGraph.AdjacentEdges(vertex).Where(e => !e.IsSelfEdge())) { TVertex other = edge.GetOtherVertex(vertex); --Degrees[other]; if (Degrees[other] < 0 && !AllowCyclicGraph) { throw new InvalidOperationException("Degree is negative, and cannot be."); } if (_heap.Contains(other)) { _heap.Update(other); } } } #endregion }
public void Visit(TVertex s) { if (this.IsAborting) { return; } this.VertexColors[s] = GraphColor.Gray; OnDiscoverVertex(s); this.vertexQueue.Push(s); while (this.vertexQueue.Count != 0) { if (this.IsAborting) { return; } TVertex u = this.vertexQueue.Pop(); OnExamineVertex(u); foreach (TEdge e in VisitedGraph.AdjacentEdges(u)) { TVertex v = (e.Source.Equals(u)) ? e.Target : e.Source; OnExamineEdge(e); GraphColor vColor = VertexColors[v]; if (vColor == GraphColor.White) { OnTreeEdge(e); VertexColors[v] = GraphColor.Gray; OnDiscoverVertex(v); this.vertexQueue.Push(v); } else { OnNonTreeEdge(e); if (vColor == GraphColor.Gray) { OnGrayTarget(e); } else { OnBlackTarget(e); } } } VertexColors[u] = GraphColor.Black; OnFinishVertex(u); } }
private bool FindEdge([NotNull] TVertex vertexFromA, [NotNull] TVertex vertexFromB, out TEdge foundEdge) { foreach (TEdge edge in VisitedGraph.AdjacentEdges(vertexFromA)) { if (edge.Target.Equals(vertexFromB) || edge.Source.Equals(vertexFromB)) { foundEdge = edge; return(true); } } foundEdge = default(TEdge); return(false); }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; InitializeInDegrees(); while (_heap.Count != 0) { if (cancelManager.IsCancelling) { return; } TVertex vertex = _heap.Dequeue(); if (Degrees[vertex] != 0 && !AllowCyclicGraph) { throw new NonAcyclicGraphException(); } SortedVertices.Add(vertex); OnVertexAdded(vertex); // Update the count of its adjacent vertices UpdateAdjacentDegree(vertex); } #region Local function void UpdateAdjacentDegree(TVertex vertex) { foreach (TEdge edge in VisitedGraph.AdjacentEdges(vertex).Where(e => !e.IsSelfEdge())) { --Degrees[edge.Target]; if (Degrees[edge.Target] < 0 && !AllowCyclicGraph) { throw new InvalidOperationException("Degree is negative, and cannot be."); } if (_heap.Contains(edge.Target)) { _heap.Update(edge.Target); } } } #endregion }
private void FlushVisitQueue() { var cancelManager = this.Services.CancelManager; while (this.vertexQueue.Count != 0) { if (cancelManager.IsCancelling) { return; } TVertex u = this.vertexQueue.Dequeue(); OnExamineVertex(u); foreach (var e in VisitedGraph.AdjacentEdges(u)) { TVertex v = (e.Source.Equals(u)) ? e.Target : e.Source; OnExamineEdge(e); GraphColor vColor = VertexColors[v]; if (vColor == GraphColor.White) { OnTreeEdge(e); VertexColors[v] = GraphColor.Gray; OnDiscoverVertex(v); this.vertexQueue.Enqueue(v); } else { OnNonTreeEdge(e); if (vColor == GraphColor.Gray) { OnGrayTarget(e); } else { OnBlackTarget(e); } } } VertexColors[u] = GraphColor.Black; OnFinishVertex(u); } }
private void FlushVisitQueue() { var cancelManager = this.Services.CancelManager; while (this.vertexQueue.Count > 0) { if (cancelManager.IsCancelling) { return; } var u = this.vertexQueue.Dequeue(); this.OnExamineVertex(u); foreach (var e in VisitedGraph.AdjacentEdges(u)) { var reversed = e.Target.Equals(u); TVertex v = reversed ? e.Source : e.Target; this.OnExamineEdge(e); var vColor = this.VertexColors[v]; if (vColor == GraphColor.White) { this.OnTreeEdge(e, reversed); this.VertexColors[v] = GraphColor.Gray; this.OnDiscoverVertex(v); this.vertexQueue.Enqueue(v); } else { this.OnNonTreeEdge(e, reversed); if (vColor == GraphColor.Gray) { this.OnGrayTarget(e, reversed); } else { this.OnBlackTarget(e, reversed); } } } this.VertexColors[u] = GraphColor.Black; this.OnFinishVertex(u); } }
private IEnumerable <TVertex> GetNeighbors([NotNull] TVertex vertex) { Debug.Assert(vertex != null); var neighbors = new HashSet <TVertex>(); foreach (TEdge edge in VisitedGraph.AdjacentEdges(vertex)) { neighbors.Add(edge.Source); neighbors.Add(edge.Target); } if (neighbors.Contains(vertex)) { neighbors.Remove(vertex); } return(neighbors); }
/// <summary> /// Searches for an edge that links <paramref name="vertexFromA"/> and <paramref name="vertexFromB"/>. /// </summary> private bool FindEdge( TVertex vertexFromA, TVertex vertexFromB, out TEdge foundEdge ) { foreach (TEdge edge in VisitedGraph.AdjacentEdges(vertexFromA)) { if (EqualityComparer <TVertex> .Default.Equals(edge.Target, vertexFromB) || EqualityComparer <TVertex> .Default.Equals(edge.Source, vertexFromB)) { foundEdge = edge; return(true); } } foundEdge = default(TEdge); return(false); }
/// <summary> /// Gets the set of vertices adjacent to the specified vertex. /// </summary> /// <param name="v"></param> /// <returns></returns> ISet <TVertex> AdjacentVertices(TVertex v) { return(adjacentVerticesCache.GetOrAdd(v, k => { var h = new HashSet <TVertex>(); foreach (var i in VisitedGraph.AdjacentEdges(k)) { if (!Equals(i.Source, k)) { h.Add(i.Source); } else { h.Add(i.Target); } } return h; })); }