public void ToString2() { ToStringTest(1, 2, 3, 4); ToStringTest( new TestVertex("1"), new TestVertex("2"), new TestVertex("3"), new TestVertex("4")); ToStringTest( new EquatableTestVertex("1"), new EquatableTestVertex("2"), new EquatableTestVertex("3"), new EquatableTestVertex("4")); #region Local function void ToStringTest <TVertex>( TVertex vertex1, TVertex vertex2, TVertex vertex3, TVertex vertex4) { var queue = new BinaryQueue <TVertex, double>(_ => 1.0); // Empty heap => consistent StringAssert.StartsWith(Consistent, queue.ToString2()); queue.Enqueue(vertex1); queue.Enqueue(vertex2); queue.Enqueue(vertex2); queue.Enqueue(vertex3); queue.Enqueue(vertex1); StringAssert.StartsWith(Consistent, queue.ToString2()); queue.Dequeue(); queue.Dequeue(); StringAssert.StartsWith(Consistent, queue.ToString2()); queue.Dequeue(); queue.Dequeue(); queue.Dequeue(); StringAssert.StartsWith(Consistent, queue.ToString2()); queue.Enqueue(vertex4); StringAssert.StartsWith(Consistent, queue.ToString2()); } #endregion }
/// <inheritdoc /> protected override void InternalCompute() { ThrowIfCancellationRequested(); while (_edges.Count > 0 && _visitedVertices.Count < VisitedGraph.VertexCount) { TEdge minEdge = _queue.Dequeue(); OnExamineEdge(minEdge); if (!_sets.AreInSameSet(minEdge.Source, minEdge.Target)) { OnTreeEdge(minEdge); _sets.Union(minEdge.Source, minEdge.Target); TVertex lastVertex; if (_visitedVertices.Contains(minEdge.Source)) { lastVertex = minEdge.Target; _visitedVertices.Add(minEdge.Target); } else { lastVertex = minEdge.Source; _visitedVertices.Add(minEdge.Source); } EnqueueEdgesFrom(lastVertex); } } }
/// <inheritdoc /> protected override void InternalCompute() { while (_heap.Count != 0) { ThrowIfCancellationRequested(); TVertex vertex = _heap.Dequeue(); if (InDegrees[vertex] != 0) { throw new NonAcyclicGraphException(); } _sortedVertices.Add(vertex); OnVertexAdded(vertex); // Update the count of its adjacent vertices foreach (TEdge edge in VisitedGraph.OutEdges(vertex)) { --InDegrees[edge.Target]; Debug.Assert(InDegrees[edge.Target] >= 0); _heap.Update(edge.Target); } } SortedVertices = _sortedVertices.ToArray(); }
protected override void InternalCompute() { var cancelManager = this.Services.CancelManager; var ds = new ForestDisjointSet<TVertex>(this.VisitedGraph.VertexCount); foreach (var v in this.VisitedGraph.Vertices) ds.MakeSet(v); if (cancelManager.IsCancelling) return; var queue = new BinaryQueue<TEdge, double>(this.edgeWeights); foreach (var e in this.VisitedGraph.Edges) queue.Enqueue(e); if (cancelManager.IsCancelling) return; while (queue.Count > 0) { var e = queue.Dequeue(); this.OnExamineEdge(e); if (!ds.AreInSameSet(e.Source, e.Target)) { this.OnTreeEdge(e); ds.Union(e.Source, e.Target); } } }
/// <inheritdoc /> protected override void InternalCompute() { var sets = new ForestDisjointSet <TVertex>(VisitedGraph.VertexCount); foreach (TVertex vertex in VisitedGraph.Vertices) { sets.MakeSet(vertex); } ThrowIfCancellationRequested(); var queue = new BinaryQueue <TEdge, double>(_edgeWeights); foreach (TEdge edge in VisitedGraph.Edges) { queue.Enqueue(edge); } ThrowIfCancellationRequested(); while (queue.Count > 0) { TEdge edge = queue.Dequeue(); OnExamineEdge(edge); if (!sets.AreInSameSet(edge.Source, edge.Target)) { OnTreeEdge(edge); sets.Union(edge.Source, edge.Target); } } }
/// <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 }
/// <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 }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; InitializeInDegrees(); while (_heap.Count != 0) { if (cancelManager.IsCancelling) { break; } TVertex vertex = _heap.Dequeue(); if (InDegrees[vertex] != 0) { throw new NonAcyclicGraphException(); } SortedVertices.Add(vertex); OnVertexAdded(vertex); // Update the count of its successor vertices IEnumerable <TEdge> successorEdges = _direction == TopologicalSortDirection.Forward ? VisitedGraph.OutEdges(vertex) : VisitedGraph.InEdges(vertex); foreach (TEdge edge in successorEdges) { if (edge.IsSelfEdge()) { continue; } TVertex successor = _direction == TopologicalSortDirection.Forward ? edge.Target : edge.Source; --InDegrees[successor]; Debug.Assert(InDegrees[successor] >= 0); _heap.Update(successor); } } }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; var sets = new ForestDisjointSet <TVertex>(VisitedGraph.VertexCount); foreach (TVertex vertex in VisitedGraph.Vertices) { sets.MakeSet(vertex); } if (cancelManager.IsCancelling) { return; } var queue = new BinaryQueue <TEdge, double>(_edgeWeights); foreach (TEdge edge in VisitedGraph.Edges) { queue.Enqueue(edge); } if (cancelManager.IsCancelling) { return; } while (queue.Count > 0) { TEdge edge = queue.Dequeue(); OnExamineEdge(edge); if (!sets.AreInSameSet(edge.Source, edge.Target)) { OnTreeEdge(edge); sets.Union(edge.Source, edge.Target); } } }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; InitializeInDegrees(); while (_heap.Count != 0) { if (cancelManager.IsCancelling) { break; } TVertex vertex = _heap.Dequeue(); if (InDegrees[vertex] != 0) { throw new NonAcyclicGraphException(); } SortedVertices.Add(vertex); OnVertexAdded(vertex); // Update the count of its adjacent vertices foreach (TEdge edge in VisitedGraph.OutEdges(vertex)) { if (edge.IsSelfEdge()) { continue; } --InDegrees[edge.Target]; Debug.Assert(InDegrees[edge.Target] >= 0); _heap.Update(edge.Target); } } }
/// <inheritdoc /> protected override void InternalCompute() { while (_heap.Count != 0) { ThrowIfCancellationRequested(); TVertex vertex = _heap.Dequeue(); if (InDegrees[vertex] != 0) { throw new NonAcyclicGraphException(); } _sortedVertices.Add(vertex); OnVertexAdded(vertex); // Update the count of its successor vertices IEnumerable <TEdge> successorEdges = _direction == TopologicalSortDirection.Forward ? VisitedGraph.OutEdges(vertex) : VisitedGraph.InEdges(vertex); foreach (TEdge edge in successorEdges) { TVertex successor = _direction == TopologicalSortDirection.Forward ? edge.Target : edge.Source; --InDegrees[successor]; Debug.Assert(InDegrees[successor] >= 0); _heap.Update(successor); } } SortedVertices = _sortedVertices.ToArray(); }
protected override void InternalCompute() { var cancelManager = this.Services.CancelManager; var visetedVert = new List <TVertex>(); var visetedEdges = new List <TEdge>(); var ds = new ForestDisjointSet <TVertex>(this.VisitedGraph.VertexCount); foreach (var v in this.VisitedGraph.Vertices) { if (visetedVert.Count == 0) { visetedVert.Add(v); } ds.MakeSet(v); } if (cancelManager.IsCancelling) { return; } var queue = new BinaryQueue <TEdge, double>(this.edgeWeights); foreach (var edge in this.VisitedGraph.Edges) { if (!visetedEdges.Contains(edge) && (visetedVert.Contains(edge.Source) || visetedVert.Contains(edge.Target))) { queue.Enqueue(edge); visetedEdges.Add(edge); } } if (cancelManager.IsCancelling) { return; } while (queue.Count > 0) { foreach (var edge in this.VisitedGraph.Edges) { if (!visetedEdges.Contains(edge) && (visetedVert.Contains(edge.Source) || visetedVert.Contains(edge.Target))) { queue.Enqueue(edge); visetedEdges.Add(edge); } } var e = queue.Dequeue(); this.OnExamineEdge(e); if (!ds.AreInSameSet(e.Source, e.Target)) { this.OnTreeEdge(e); ds.Union(e.Source, e.Target); if (visetedVert.Contains(e.Source)) { visetedVert.Add(e.Target); } else { visetedVert.Add(e.Source); } } } }
protected override void InternalCompute() { var dic = new Dictionary <TVertex, HashSet <TEdge> >(); var cancelManager = this.Services.CancelManager; var visetedVert = new HashSet <TVertex>(); var edges = new HashSet <TEdge>(); var queue = new BinaryQueue <TEdge, double>(this.edgeWeights); var ds = new ForestDisjointSet <TVertex>(this.VisitedGraph.VertexCount); foreach (var v in this.VisitedGraph.Vertices) { if (visetedVert.Count == 0) { visetedVert.Add(v); } ds.MakeSet(v); dic.Add(v, new HashSet <TEdge>()); } foreach (var e in this.VisitedGraph.Edges) { dic[e.Source].Add(e); dic[e.Target].Add(e); } if (cancelManager.IsCancelling) { return; } var enumerator = visetedVert.GetEnumerator(); enumerator.MoveNext(); var lastVert = enumerator.Current; foreach (var edge in dic[lastVert]) { if (!edges.Contains(edge)) { edges.Add(edge); queue.Enqueue(edge); } } if (cancelManager.IsCancelling) { return; } while (edges.Count > 0 && visetedVert.Count < VisitedGraph.VertexCount) { var mined = queue.Dequeue(); this.OnExamineEdge(mined); if (!ds.AreInSameSet(mined.Source, mined.Target)) { this.OnTreeEdge(mined); ds.Union(mined.Source, mined.Target); if (visetedVert.Contains(mined.Source)) { lastVert = mined.Target; visetedVert.Add(mined.Target); } else { lastVert = mined.Source; visetedVert.Add(mined.Source); } foreach (var edge in dic[lastVert]) { if (!edges.Contains(edge)) { edges.Add(edge); queue.Enqueue(edge); } } } } }
public void ToPairsArray() { ToPairsArrayTest(1, 2, 3, 4); ToPairsArrayTest( new TestVertex("1"), new TestVertex("2"), new TestVertex("3"), new TestVertex("4")); ToPairsArrayTest( new EquatableTestVertex("1"), new EquatableTestVertex("2"), new EquatableTestVertex("3"), new EquatableTestVertex("4")); #region Local function void ToPairsArrayTest <TVertex>( TVertex vertex1, TVertex vertex2, TVertex vertex3, TVertex vertex4) { var distances = new Stack <double>(new[] { 123.0, 3.0, 2.0, 4.0, 5.0, 1.0 }); var queue = new BinaryQueue <TVertex, double>(_ => distances.Pop()); // Empty heap CollectionAssert.IsEmpty(queue.ToPairsArray()); queue.Enqueue(vertex1); queue.Enqueue(vertex2); queue.Enqueue(vertex2); queue.Enqueue(vertex3); queue.Enqueue(vertex1); // Array not sorted with distance CollectionAssert.AreEquivalent( new[] { new KeyValuePair <double, TVertex>(1.0, vertex1), new KeyValuePair <double, TVertex>(5.0, vertex2), new KeyValuePair <double, TVertex>(4.0, vertex2), new KeyValuePair <double, TVertex>(2.0, vertex3), new KeyValuePair <double, TVertex>(3.0, vertex1) }, queue.ToPairsArray()); queue.Dequeue(); queue.Dequeue(); // Array not sorted with distance CollectionAssert.AreEquivalent( new[] { new KeyValuePair <double, TVertex>(3.0, vertex1), new KeyValuePair <double, TVertex>(5.0, vertex2), new KeyValuePair <double, TVertex>(4.0, vertex2) }, queue.ToPairsArray()); queue.Dequeue(); queue.Dequeue(); queue.Dequeue(); CollectionAssert.IsEmpty(queue.ToPairsArray()); queue.Enqueue(vertex4); CollectionAssert.AreEqual( new[] { new KeyValuePair <double, TVertex>(123.0, vertex4) }, queue.ToPairsArray()); } #endregion }