public void SetRootVertex_Throws() { var graph = new UndirectedGraph <TestVertex, Edge <TestVertex> >(); var algorithm = new UndirectedBreadthFirstSearchAlgorithm <TestVertex, Edge <TestVertex> >(graph); SetRootVertex_Throws_Test(algorithm); }
public void ClearRootVertex() { var graph = new UndirectedGraph <int, Edge <int> >(); var algorithm = new UndirectedBreadthFirstSearchAlgorithm <int, Edge <int> >(graph); ClearRootVertex_Test(algorithm); }
public TravelPath ShortestPath(int sourcePlace, int targetPlace) { var algo = new UndirectedBreadthFirstSearchAlgorithm <int, TravelEdge>(this); algo.SetRootVertex(sourcePlace); var predecessors = new UndirectedVertexPredecessorRecorderObserver <int, TravelEdge>(); predecessors.Attach(algo); algo.Compute(); List <TravelEdge> path = new List <TravelEdge>(); var place = targetPlace; //there is no way to get to the target if (!predecessors.VertexPredecessors.ContainsKey(place)) { return(null); } while (place != sourcePlace) { var edge = predecessors.VertexPredecessors[place]; path.Insert(0, edge); place = edge.getAnotherPlace(place); } return(ConvertToPath(path, sourcePlace)); }
public void ComputeWithRoot() { var graph = new UndirectedGraph <int, Edge <int> >(); graph.AddVertex(0); var algorithm = new UndirectedBreadthFirstSearchAlgorithm <int, Edge <int> >(graph); ComputeWithRoot_Test(algorithm); }
public static UndirectedBreadthFirstSearchAlgorithm <T, Edge <T> > CreateAlgorithmAndMaybeDoComputation <T>( [NotNull] ContractScenario <T> scenario) { var graph = new UndirectedGraph <T, Edge <T> >(); graph.AddVerticesAndEdgeRange(scenario.EdgesInGraph.Select(e => new Edge <T>(e.Source, e.Target))); graph.AddVertexRange(scenario.SingleVerticesInGraph); var algorithm = new UndirectedBreadthFirstSearchAlgorithm <T, Edge <T> >(graph); if (scenario.DoComputation) { algorithm.Compute(scenario.Root); } return(algorithm); }
public void ComputeNoInit(TVertex s) { Contract.Requires(s != null); Contract.Requires(this.VisitedGraph.ContainsVertex(s)); UndirectedBreadthFirstSearchAlgorithm <TVertex, TEdge> bfs = null; try { bfs = new UndirectedBreadthFirstSearchAlgorithm <TVertex, TEdge>( this, this.VisitedGraph, this.vertexQueue, VertexColors ); bfs.InitializeVertex += this.InitializeVertex; bfs.DiscoverVertex += this.DiscoverVertex; bfs.StartVertex += this.StartVertex; bfs.ExamineEdge += this.ExamineEdge; #if DEBUG bfs.ExamineEdge += e => this.AssertHeap(); #endif bfs.ExamineVertex += this.ExamineVertex; bfs.FinishVertex += this.FinishVertex; bfs.TreeEdge += new UndirectedEdgeAction <TVertex, TEdge>(this.InternalTreeEdge); bfs.GrayTarget += new UndirectedEdgeAction <TVertex, TEdge>(this.InternalGrayTarget); bfs.Visit(s); } finally { if (bfs != null) { bfs.InitializeVertex -= this.InitializeVertex; bfs.DiscoverVertex -= this.DiscoverVertex; bfs.StartVertex -= this.StartVertex; bfs.ExamineEdge -= this.ExamineEdge; bfs.ExamineVertex -= this.ExamineVertex; bfs.FinishVertex -= this.FinishVertex; bfs.TreeEdge -= new UndirectedEdgeAction <TVertex, TEdge>(this.InternalTreeEdge); bfs.GrayTarget -= new UndirectedEdgeAction <TVertex, TEdge>(this.InternalGrayTarget); } } }
public void GetVertexColor() { var graph = new UndirectedGraph <int, Edge <int> >(); graph.AddVerticesAndEdge(new Edge <int>(1, 2)); var algorithm = new UndirectedBreadthFirstSearchAlgorithm <int, Edge <int> >(graph); // Algorithm not run // ReSharper disable once ReturnValueOfPureMethodIsNotUsed Assert.Throws <VertexNotFoundException>(() => algorithm.GetVertexColor(1)); algorithm.Compute(1); Assert.AreEqual(GraphColor.Black, algorithm.GetVertexColor(1)); Assert.AreEqual(GraphColor.Black, algorithm.GetVertexColor(2)); }
private void ComputeNoInit([NotNull] TVertex root) { Debug.Assert(root != null); Debug.Assert(VisitedGraph.ContainsVertex(root)); UndirectedBreadthFirstSearchAlgorithm <TVertex, TEdge> bfs = null; try { bfs = new UndirectedBreadthFirstSearchAlgorithm <TVertex, TEdge>( this, VisitedGraph, _vertexQueue, VerticesColors); bfs.InitializeVertex += InitializeVertex; bfs.DiscoverVertex += DiscoverVertex; bfs.StartVertex += StartVertex; bfs.ExamineEdge += ExamineEdge; #if DEBUG bfs.ExamineEdge += edge => AssertHeap(); #endif bfs.ExamineVertex += ExamineVertex; bfs.FinishVertex += FinishVertex; bfs.TreeEdge += OnDijkstraTreeEdge; bfs.GrayTarget += OnGrayTarget; bfs.Visit(root); } finally { if (bfs != null) { bfs.InitializeVertex -= InitializeVertex; bfs.DiscoverVertex -= DiscoverVertex; bfs.StartVertex -= StartVertex; bfs.ExamineEdge -= ExamineEdge; bfs.ExamineVertex -= ExamineVertex; bfs.FinishVertex -= FinishVertex; bfs.TreeEdge -= OnDijkstraTreeEdge; bfs.GrayTarget -= OnGrayTarget; } } }
public void ComputeNoInit(TVertex s) { this.vertexQueue = new PriorityQueue <TVertex, double>(this.Distances); UndirectedBreadthFirstSearchAlgorithm <TVertex, TEdge> bfs = null; try { bfs = new UndirectedBreadthFirstSearchAlgorithm <TVertex, TEdge>( this, this.VisitedGraph, this.vertexQueue, VertexColors ); bfs.InitializeVertex += this.InitializeVertex; bfs.DiscoverVertex += this.DiscoverVertex; bfs.StartVertex += this.StartVertex; bfs.ExamineEdge += this.ExamineEdge; bfs.ExamineVertex += this.ExamineVertex; bfs.FinishVertex += this.FinishVertex; bfs.TreeEdge += new EdgeEventHandler <TVertex, TEdge>(this.InternalTreeEdge); bfs.GrayTarget += new EdgeEventHandler <TVertex, TEdge>(this.InternalGrayTarget); bfs.Visit(s); } finally { if (bfs != null) { bfs.InitializeVertex -= this.InitializeVertex; bfs.DiscoverVertex -= this.DiscoverVertex; bfs.StartVertex -= this.StartVertex; bfs.ExamineEdge -= this.ExamineEdge; bfs.ExamineVertex -= this.ExamineVertex; bfs.FinishVertex -= this.FinishVertex; bfs.TreeEdge -= new EdgeEventHandler <TVertex, TEdge>(this.InternalTreeEdge); bfs.GrayTarget -= new EdgeEventHandler <TVertex, TEdge>(this.InternalGrayTarget); } } }
private void BFS() { watch.Restart(); var found = new List <int>(); var bfs = new UndirectedBreadthFirstSearchAlgorithm <int, Edge>(graph); bfs.DiscoverVertex += v => found.Add(v); bfs.Compute(0); watch.Stop(); span = watch.Elapsed; elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", span.Hours, span.Minutes, span.Seconds, span.Milliseconds / 10); Console.WriteLine("BFS time: " + elapsedTime); Console.WriteLine("BFS elements: " + found.Count); foreach (int index in indexes) { Console.WriteLine(index + ": " + found[index]); } }
public void Constructor() { var graph = new UndirectedGraph <int, Edge <int> >(); var algorithm = new UndirectedBreadthFirstSearchAlgorithm <int, Edge <int> >(graph); AssertAlgorithmProperties(algorithm, graph); var verticesColors = new Dictionary <int, GraphColor>(); var queue = new BinaryQueue <int, double>(vertex => 1.0); algorithm = new UndirectedBreadthFirstSearchAlgorithm <int, Edge <int> >(graph, queue, verticesColors); AssertAlgorithmProperties(algorithm, graph, verticesColors); algorithm = new UndirectedBreadthFirstSearchAlgorithm <int, Edge <int> >(null, graph, queue, verticesColors); AssertAlgorithmProperties(algorithm, graph, verticesColors); #region Local function void AssertAlgorithmProperties <TVertex, TEdge>( UndirectedBreadthFirstSearchAlgorithm <TVertex, TEdge> algo, IUndirectedGraph <TVertex, TEdge> g, IDictionary <TVertex, GraphColor> vColors = null) where TEdge : IEdge <TVertex> { AssertAlgorithmState(algo, g); if (vColors is null) { CollectionAssert.IsEmpty(algo.VerticesColors); } else { Assert.AreSame(vColors, algo.VerticesColors); } } #endregion }
private static void RunBFSAndCheck <TVertex, TEdge>( [NotNull] IUndirectedGraph <TVertex, TEdge> graph, [NotNull] TVertex sourceVertex) where TEdge : IEdge <TVertex> { var parents = new Dictionary <TVertex, TVertex>(); var distances = new Dictionary <TVertex, int>(); TVertex currentVertex = default; int currentDistance = 0; var algorithm = new UndirectedBreadthFirstSearchAlgorithm <TVertex, TEdge>(graph); algorithm.InitializeVertex += vertex => { Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[vertex]); }; algorithm.StartVertex += vertex => { Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[vertex]); }; algorithm.DiscoverVertex += vertex => { Assert.AreEqual(GraphColor.Gray, algorithm.VerticesColors[vertex]); if (vertex.Equals(sourceVertex)) { currentVertex = sourceVertex; } else { Assert.IsNotNull(currentVertex); Assert.AreEqual(parents[vertex], currentVertex); // ReSharper disable once AccessToModifiedClosure Assert.AreEqual(distances[vertex], currentDistance + 1); Assert.AreEqual(distances[vertex], distances[parents[vertex]] + 1); } }; algorithm.ExamineEdge += edge => { Assert.IsTrue(edge.Source.Equals(currentVertex) || edge.Target.Equals(currentVertex)); }; algorithm.ExamineVertex += vertex => { TVertex u = vertex; currentVertex = u; // Ensure that the distances monotonically increase. // ReSharper disable AccessToModifiedClosure Assert.IsTrue(distances[u] == currentDistance || distances[u] == currentDistance + 1); if (distances[u] == currentDistance + 1) // New level { ++currentDistance; } // ReSharper restore AccessToModifiedClosure }; algorithm.TreeEdge += (sender, args) => { TVertex u = args.Edge.Source; TVertex v = args.Edge.Target; if (algorithm.VerticesColors[v] == GraphColor.Gray) { TVertex temp = u; u = v; v = temp; } Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[v]); Assert.AreEqual(distances[u], currentDistance); parents[v] = u; distances[v] = distances[u] + 1; }; algorithm.NonTreeEdge += (sender, args) => { TVertex u = args.Edge.Source; TVertex v = args.Edge.Target; if (algorithm.VerticesColors[v] != GraphColor.White) { TVertex temp = u; u = v; v = temp; } Assert.IsFalse(algorithm.VerticesColors[v] == GraphColor.White); if (algorithm.VisitedGraph.IsDirected) { // Cross or back edge Assert.IsTrue(distances[v] <= distances[u] + 1); } else { // Cross edge (or going backwards on a tree edge) Assert.IsTrue( distances[v] == distances[u] || distances[v] == distances[u] + 1 || distances[v] == distances[u] - 1); } }; algorithm.GrayTarget += (sender, args) => { Assert.AreEqual(GraphColor.Gray, algorithm.VerticesColors[args.Target]); }; algorithm.BlackTarget += (sender, args) => { Assert.AreEqual(GraphColor.Black, algorithm.VerticesColors[args.Target]); foreach (TEdge edge in algorithm.VisitedGraph.AdjacentEdges(args.Target)) { Assert.IsFalse(algorithm.VerticesColors[edge.Target] == GraphColor.White); } }; algorithm.FinishVertex += vertex => { Assert.AreEqual(GraphColor.Black, algorithm.VerticesColors[vertex]); }; parents.Clear(); distances.Clear(); currentDistance = 0; foreach (TVertex vertex in graph.Vertices) { distances[vertex] = int.MaxValue; parents[vertex] = vertex; } distances[sourceVertex] = 0; var recorder = new UndirectedVertexPredecessorRecorderObserver <TVertex, TEdge>(); using (recorder.Attach(algorithm)) { algorithm.Compute(sourceVertex); } // All white vertices should be unreachable from the source. foreach (TVertex vertex in graph.Vertices) { if (algorithm.VerticesColors[vertex] == GraphColor.White) { // Check !IsReachable(sourceVertex, vertex, graph); if (recorder.TryGetPath(vertex, out IEnumerable <TEdge> path)) { foreach (TEdge edge in path) { Assert.AreNotEqual(sourceVertex, edge.Source); Assert.AreNotEqual(sourceVertex, edge.Target); } } } } // The shortest path to a child should be one longer than // shortest path to the parent. foreach (TVertex vertex in graph.Vertices) { if (!parents[vertex].Equals(vertex)) // Not the root of the BFS tree { Assert.AreEqual(distances[vertex], distances[parents[vertex]] + 1); } } }
private void Search(IUndirectedGraph<string,Edge<string>> graph, string rootVertex) { Console.WriteLine(rootVertex); algo = new UndirectedBreadthFirstSearchAlgorithm<string,Edge<string>>(graph); try { algo.InitializeVertex += new VertexEventHandler<string>(this.InitializeVertex); algo.DiscoverVertex += new VertexEventHandler<string>(this.DiscoverVertex); algo.ExamineVertex += new VertexEventHandler<string>(this.ExamineVertex); algo.TreeEdge += new EdgeEventHandler<string,Edge<string>>(this.TreeEdge); algo.NonTreeEdge += new EdgeEventHandler<string,Edge<string>>(this.NonTreeEdge); algo.GrayTarget += new EdgeEventHandler<string,Edge<string>>(this.GrayTarget); algo.BlackTarget += new EdgeEventHandler<string,Edge<string>>(this.BlackTarget); algo.FinishVertex += new VertexEventHandler<string>(this.FinishVertex); parents.Clear(); distances.Clear(); currentDistance = 0; sourceVertex = rootVertex; foreach (string v in this.algo.VisitedGraph.Vertices) { distances[v] = int.MaxValue; parents[v] = v; } distances[sourceVertex] = 0; algo.Compute(sourceVertex); CheckBfs(); } finally { algo.InitializeVertex -= new VertexEventHandler<string>(this.InitializeVertex); algo.DiscoverVertex -= new VertexEventHandler<string>(this.DiscoverVertex); algo.ExamineVertex -= new VertexEventHandler<string>(this.ExamineVertex); algo.TreeEdge -= new EdgeEventHandler<string,Edge<string>>(this.TreeEdge); algo.NonTreeEdge -= new EdgeEventHandler<string,Edge<string>>(this.NonTreeEdge); algo.GrayTarget -= new EdgeEventHandler<string,Edge<string>>(this.GrayTarget); algo.BlackTarget -= new EdgeEventHandler<string,Edge<string>>(this.BlackTarget); algo.FinishVertex -= new VertexEventHandler<string>(this.FinishVertex); } }
public void Init() { this.parents = new Dictionary<string, string>(); this.distances = new Dictionary<string, int>(); this.currentDistance = 0; this.currentVertex = null; this.algo = null; }