void SearchGraph( BidirectionalGraph <Vertex, SEdge <Vertex> > graph, VertexPredecessorRecorderObserver <Vertex, SEdge <Vertex> > observer = null ) { BreadthFirstSearchAlgorithm <Vertex, SEdge <Vertex> > bfs = new BreadthFirstSearchAlgorithm <Vertex, SEdge <Vertex> > (graph); if (observer == null) { bfs.Compute(); } else { using (observer.Attach(bfs)) { bfs.Compute(); foreach ( KeyValuePair <Vertex, SEdge <Vertex> > pair in observer.VerticesPredecessors ) { Debug.Log( pair.Value.Source.Point + " -> " + pair.Value.Target.Point ); } } } }
protected virtual void GenerateSpanningTree(CancellationToken cancellationToken) { SpanningTree = new BidirectionalGraph <TVertex, Edge <TVertex> >(false); SpanningTree.AddVertexRange(VisitedGraph.Vertices.OrderBy(v => VisitedGraph.InDegree(v))); EdgeAction <TVertex, TEdge> action = e => { cancellationToken.ThrowIfCancellationRequested(); SpanningTree.AddEdge(new Edge <TVertex>(e.Source, e.Target)); }; switch (Parameters.SpanningTreeGeneration) { case SpanningTreeGeneration.BFS: var bfsAlgo = new BreadthFirstSearchAlgorithm <TVertex, TEdge>(VisitedGraph); bfsAlgo.TreeEdge += action; bfsAlgo.Compute(); break; case SpanningTreeGeneration.DFS: var dfsAlgo = new DepthFirstSearchAlgorithm <TVertex, TEdge>(VisitedGraph); dfsAlgo.TreeEdge += action; dfsAlgo.ForwardOrCrossEdge += action; dfsAlgo.Compute(); break; } }
public static TryFunc <TVertex, IEnumerable <TEdge> > TreeBreadthFirstSearch <TVertex, TEdge>( #if !NET20 this #endif 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 BreadthFirstSearchAlgorithm <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); }); }
public void Walk() { var breadthFirstSearchAlgorithm = new BreadthFirstSearchAlgorithm <string, ToscaGraphEdge>(graph); breadthFirstSearchAlgorithm.DiscoverVertex += nodeTypeName => { action(nodeTypeName, nodeTypes[nodeTypeName]); }; breadthFirstSearchAlgorithm.Compute(ToscaDefaults.ToscaNodesRoot); }
protected override void InternalCompute() { this.bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>(this.VisitedGraph); this.observer = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); try { this.observer.Attach(this.bfs); this.bfs.DiscoverVertex += new VertexEventHandler <TVertex>(bfs_DiscoverVertex); bfs.Compute(); this.OnIterationEnded(EventArgs.Empty); } finally { if (this.observer != null) { this.observer.Detach(this.bfs); this.observer = null; } if (this.bfs != null) { this.bfs.DiscoverVertex -= new VertexEventHandler <TVertex>(bfs_DiscoverVertex); this.bfs = null; } } }
//======================================================================= // This is a breadth-first search over the residual graph // (well, actually the reverse of the residual graph). // Would be cool to have a graph view adaptor for hiding certain // edges, like the saturated (non-residual) edges in this case. // Goldberg's implementation abused "distance" for the coloring. private void GlobalDistanceUpdate() { foreach (IVertex u in VisitedGraph.Vertices) { Colors[u] = GraphColor.White; Distances[u] = n; } Distances[sink] = 0; for (int l = 0; l <= maxDistance; ++l) { layers[l].ActiveVertices.Clear(); layers[l].InactiveVertices.Clear(); } maxDistance = maxActive = 0; minActive = n; BreadthFirstSearchAlgorithm bfs = new BreadthFirstSearchAlgorithm( ResidualGraph, new VertexBuffer(), Colors ); DistanceRecorderVisitor vis = new DistanceRecorderVisitor(Distances); bfs.TreeEdge += new EdgeEventHandler(vis.TreeEdge); bfs.DiscoverVertex += new VertexEventHandler(GlobalDistanceUpdateHelper); bfs.Compute(sink); }
private void GenerateSpanningTree() { _spanningTree = new BidirectionalGraph <TVertex, Edge <TVertex> >(false); _spanningTree.AddVertexRange(VisitedGraph.Vertices); IQueue <TVertex> vb = new QuikGraph.Collections.Queue <TVertex>(); vb.Enqueue(VisitedGraph.Vertices.OrderBy(v => VisitedGraph.InDegree(v)).First()); switch (Parameters.SpanningTreeGeneration) { case SpanningTreeGeneration.BFS: var bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>(VisitedGraph, vb, new Dictionary <TVertex, GraphColor>()); bfs.TreeEdge += e => { ThrowIfCancellationRequested(); _spanningTree.AddEdge(new Edge <TVertex>(e.Source, e.Target)); }; bfs.Compute(); break; case SpanningTreeGeneration.DFS: var dfs = new DepthFirstSearchAlgorithm <TVertex, TEdge>(VisitedGraph); dfs.TreeEdge += e => { ThrowIfCancellationRequested(); _spanningTree.AddEdge(new Edge <TVertex>(e.Source, e.Target)); }; dfs.Compute(); break; } }
/// <summary> /// Computes the maximum flow between Source and Sink. /// </summary> /// <returns></returns> protected override void InternalCompute() { if (this.Source == null) { throw new InvalidOperationException("Source is not specified"); } if (this.Sink == null) { throw new InvalidOperationException("Sink is not specified"); } if (this.Services.CancelManager.IsCancelling) { return; } var g = this.VisitedGraph; foreach (var u in g.Vertices) { foreach (var e in g.OutEdges(u)) { var capacity = this.Capacities(e); if (capacity < 0) { throw new InvalidOperationException("negative edge capacity"); } this.ResidualCapacities[e] = capacity; } } this.VertexColors[Sink] = GraphColor.Gray; while (this.VertexColors[Sink] != GraphColor.White) { var vis = new VertexPredecessorRecorderObserver <TVertex, TEdge>( this.Predecessors ); var queue = new QuickGraph.Collections.Queue <TVertex>(); var bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>( this.ResidualGraph, queue, this.VertexColors ); using (vis.Attach(bfs)) bfs.Compute(this.Source); if (this.VertexColors[this.Sink] != GraphColor.White) { this.Augment(this.Source, this.Sink); } } // while this.MaxFlow = 0; foreach (var e in g.OutEdges(Source)) { this.MaxFlow += (this.Capacities(e) - this.ResidualCapacities[e]); } }
public void Walk(string nodeTypeNameToStart, Action <string, ToscaNodeType> action) { var breadthFirstSearchAlgorithm = new BreadthFirstSearchAlgorithm <string, ToscaGraphEdge>(graph); breadthFirstSearchAlgorithm.DiscoverVertex += nodeTypeName => { action(nodeTypeName, nodeTypes[nodeTypeName]); }; breadthFirstSearchAlgorithm.Compute(nodeTypeNameToStart); }
private void RemoveIrrelevantBranches(AdjacencyGraph <IBuilder, EquatableEdge <IBuilder> > graph, IBuilder rootBuilder) { var bfs = new BreadthFirstSearchAlgorithm <IBuilder, EquatableEdge <IBuilder> >(graph); bfs.Compute(rootBuilder); var toKeep = new HashSet <IBuilder>(bfs.VisitedGraph.Vertices); graph.RemoveVertexIf(v => !toKeep.Contains(v)); }
/// <summary> /// Computes the maximum flow between Source and Sink. /// </summary> protected override void InternalCompute() { if (Source == null) { throw new InvalidOperationException("Source is not specified."); } if (Sink == null) { throw new InvalidOperationException("Sink is not specified."); } if (Services.CancelManager.IsCancelling) { return; } var graph = VisitedGraph; foreach (TVertex vertex in graph.Vertices) { foreach (TEdge edge in graph.OutEdges(vertex)) { double capacity = Capacities(edge); if (capacity < 0) { throw new InvalidOperationException("Negative edge capacity."); } ResidualCapacities[edge] = capacity; } } VerticesColors[Sink] = GraphColor.Gray; while (VerticesColors[Sink] != GraphColor.White) { var verticesPredecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(Predecessors); var queue = new Queue <TVertex>(); var bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>( ResidualGraph, queue, VerticesColors); using (verticesPredecessors.Attach(bfs)) bfs.Compute(Source); if (VerticesColors[Sink] != GraphColor.White) { Augment(Source, Sink); } } MaxFlow = 0; foreach (TEdge edge in graph.OutEdges(Source)) { MaxFlow += (Capacities(edge) - ResidualCapacities[edge]); } }
private void RemoveIrrelevantBranches(AdjacencyGraph <IBuilder, EquatableEdge <IBuilder> > graph, IBuilder rootBuilder) { var bfs = new BreadthFirstSearchAlgorithm <IBuilder, EquatableEdge <IBuilder> >(graph); var toKeep = new HashSet <EquatableEdge <IBuilder> >(); var buildersToKeep = new HashSet <IBuilder>(); bfs.TreeEdge += e => toKeep.Add(e); bfs.NonTreeEdge += e => toKeep.Add(e); bfs.DiscoverVertex += b => buildersToKeep.Add(b); bfs.Compute(rootBuilder); graph.RemoveEdgeIf(edge => !toKeep.Contains(edge)); graph.RemoveVertexIf(vertex => !buildersToKeep.Contains(vertex)); }
/// <summary> /// Computes the maximum flow between <paramref name="src"/> and /// <paramref name="sink"/> /// </summary> /// <param name="src"></param> /// <param name="sink"></param> /// <returns></returns> public override double Compute(IVertex src, IVertex sink) { if (src == null) { throw new ArgumentNullException("src"); } if (sink == null) { throw new ArgumentNullException("sink"); } foreach (IVertex u in VisitedGraph.Vertices) { foreach (IEdge e in VisitedGraph.OutEdges(u)) { ResidualCapacities[e] = Capacities[e]; } } Colors[sink] = GraphColor.Gray; while (Colors[sink] != GraphColor.White) { PredecessorRecorderVisitor vis = new PredecessorRecorderVisitor( Predecessors ); VertexBuffer Q = new VertexBuffer(); BreadthFirstSearchAlgorithm bfs = new BreadthFirstSearchAlgorithm( ResidualGraph, Q, Colors ); bfs.RegisterPredecessorRecorderHandlers(vis); bfs.Compute(src); if (Colors[sink] != GraphColor.White) { Augment(src, sink); } } // while double flow = 0; foreach (IEdge e in VisitedGraph.OutEdges(src)) { flow += (Capacities[e] - ResidualCapacities[e]); } return(flow); }
public static BreadthFirstSearchAlgorithm <T, Edge <T> > CreateAlgorithmAndMaybeDoComputation <T>( [NotNull] ContractScenario <T> scenario) { var graph = new AdjacencyGraph <T, Edge <T> >(); graph.AddVerticesAndEdgeRange(scenario.EdgesInGraph.Select(e => new Edge <T>(e.Source, e.Target))); graph.AddVertexRange(scenario.SingleVerticesInGraph); var algorithm = new BreadthFirstSearchAlgorithm <T, Edge <T> >(graph); if (scenario.DoComputation) { algorithm.Compute(scenario.Root); } return(algorithm); }
public static VertexPredecessorRecorderObserver <TVertex, TEdge> GetPredecessors <TVertex, TEdge> (this IVertexListGraph <TVertex, TEdge> graph, TVertex obj, VertexAction <TVertex> onVertex) where TEdge : IEdge <TVertex> { var bfsa = new BreadthFirstSearchAlgorithm <TVertex, TEdge> (graph); bfsa.ExamineVertex += (vertex) => { onVertex?.Invoke(vertex); }; var vertexPredecessorRecorderObserver = new VertexPredecessorRecorderObserver <TVertex, TEdge> (); using (vertexPredecessorRecorderObserver.Attach(bfsa)) { bfsa.Compute(obj); } return(vertexPredecessorRecorderObserver); }
private bool IsOptimal(MaximumFlowAlgorithm maxFlow) { // check if mincut is saturated... FilteredVertexListGraph residualGraph = new FilteredVertexListGraph( maxFlow.VisitedGraph, new ReversedResidualEdgePredicate(maxFlow.ResidualCapacities, maxFlow.ReversedEdges) ); BreadthFirstSearchAlgorithm bfs = new BreadthFirstSearchAlgorithm(residualGraph); VertexIntDictionary distances = new VertexIntDictionary(); DistanceRecorderVisitor vis = new DistanceRecorderVisitor(distances); bfs.RegisterDistanceRecorderHandlers(vis); bfs.Compute(sink); return distances[source] >= maxFlow.VisitedGraph.VerticesCount; }
/// <summary> /// Computes the maximum flow between <paramref name="src"/> and /// <paramref name="sink"/> /// </summary> /// <param name="src"></param> /// <param name="sink"></param> /// <returns></returns> protected override void InternalCompute() { if (this.Source == null) { throw new InvalidOperationException("Source is not specified"); } if (this.Sink == null) { throw new InvalidOperationException("Sink is not specified"); } foreach (TVertex u in VisitedGraph.Vertices) { foreach (TEdge e in VisitedGraph.OutEdges(u)) { ResidualCapacities[e] = Capacities[e]; } } VertexColors[Sink] = GraphColor.Gray; while (VertexColors[Sink] != GraphColor.White) { VertexPredecessorRecorderObserver <TVertex, TEdge> vis = new VertexPredecessorRecorderObserver <TVertex, TEdge>( Predecessors ); VertexBuffer <TVertex> Q = new VertexBuffer <TVertex>(); BreadthFirstSearchAlgorithm <TVertex, TEdge> bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>( ResidualGraph, Q, VertexColors ); vis.Attach(bfs); bfs.Compute(this.Source); vis.Detach(bfs); if (VertexColors[this.Sink] != GraphColor.White) { Augment(this.Source, this.Sink); } } // while this.MaxFlow = 0; foreach (TEdge e in VisitedGraph.OutEdges(Source)) { this.MaxFlow += (Capacities[e] - ResidualCapacities[e]); } }
public void GetVertexColor() { var graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVerticesAndEdge(new Edge <int>(1, 2)); var algorithm = new BreadthFirstSearchAlgorithm <int, Edge <int> >(graph); // Algorithm not run // ReSharper disable once ReturnValueOfPureMethodIsNotUsed Assert.Throws <VertexNotFoundException>(() => algorithm.GetVertexColor(1)); algorithm.Compute(); Assert.AreEqual(GraphColor.Black, algorithm.GetVertexColor(1)); Assert.AreEqual(GraphColor.Black, algorithm.GetVertexColor(2)); }
public double[] Compute(double[] input) { if (input.Length != _inputNeurons.Count) { throw new ArgumentException("input.Count != inputNeurons.Count"); } Enumerable.Zip(input, _inputNeurons, (d, neuron) => neuron.AddToInput(d)).Consume(); _algorithm.Compute(); var result = _outputNeurons.Select(x => x.Signal).ToArray(); Reset(); return(result); }
/// Summary /// Time: 8 min 17 sec /// Pattern: AAAA, Parameterized stub /// Pex Limitations - Not able to generate any test due to the following issue: /// <boundary> maxbranches - 40000 (maximum number of branches exceeded) /// [execution] Please notice: A branch in the method System.Collections.Hashtable+HashtableEnumerator.MoveNext was executed 5777 times; /// please check that the code is not stuck in an infinite loop. /// [test] (run 1) GraphWithoutSelfEdgesPUT01, pathboundsexceeded (duplicate) /// [execution] Please notice: A branch in the method System.Collections.Hashtable+HashtableEnumerator.MoveNext was executed 4344 times; /// please check that the code is not stuck in an infinite loop. /// [test] (run 2) GraphWithoutSelfEdgesPUT01, pathboundsexceeded (duplicate) /// <summary> /// @Author:Madhuri /// </summary> public void GraphWithSelfEdgesPUT(AdjacencyGraph g, int loopBound) { Random rnd = new Random(); Init(); for (int i = 0; i < loopBound; ++i) { for (int j = 0; j < i * i; ++j) { RandomGraph.Graph(g, i, j, rnd, true); BreadthFirstSearchAlgorithm bfs = new BreadthFirstSearchAlgorithm(g); bfs.InitializeVertex += new VertexHandler(this.InitializeVertex); bfs.DiscoverVertex += new VertexHandler(this.DiscoverVertex); bfs.ExamineEdge += new EdgeHandler(this.ExamineEdge); bfs.ExamineVertex += new VertexHandler(this.ExamineVertex); bfs.TreeEdge += new EdgeHandler(this.TreeEdge); bfs.NonTreeEdge += new EdgeHandler(this.NonTreeEdge); bfs.GrayTarget += new EdgeHandler(this.GrayTarget); bfs.BlackTarget += new EdgeHandler(this.BlackTarget); bfs.FinishVertex += new VertexHandler(this.FinishVertex); Parents.Clear(); Distances.Clear(); m_CurrentDistance = 0; m_SourceVertex = RandomGraph.Vertex(g, rnd); var choose = PexChoose.FromCall(this); if (choose.ChooseValue <bool>("to add a self ede")) { IVertex selfEdge = RandomGraph.Vertex(g, rnd); g.AddEdge(selfEdge, selfEdge); } // g.RemoveEdge(RandomGraph.Edge(g, rnd)); foreach (IVertex v in g.Vertices) { Distances[v] = int.MaxValue; Parents[v] = v; } Distances[SourceVertex] = 0; bfs.Compute(SourceVertex); CheckBfs(g, bfs); } } }
public static IEnumerable <TVertex> BfSearch <TVertex, TEdge>(IVertexListGraph <TVertex, TEdge> graph) where TEdge : class, IEdge <TVertex> { //var parents = new Dictionary<TVertex, TVertex>(); //var distances = new Dictionary<TVertex, int>(); //TVertex currentVertex = default(TVertex); //int currentDistance = 0; var bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>(g: graph); var v1 = graph.Vertices.First(); //bfs.Visit(v1); List <TVertex> outVertices = new List <TVertex>(); //bfs.DiscoverVertex += u => //{ // outVertices.Add(u); //}; bfs.FinishVertex += u => { outVertices.Add(u); }; //bfs.di //bfs.TreeEdge bfs.Compute(v1); ////bfs.sto Func <IEnumerable <TEdge>, IEnumerable <TEdge> > searchFunc = bfs.OutEdgeEnumerator; //var path = searchFunc(() //BestFirstFrontierSearchAlgorithm<> bb = return(outVertices); }
/// <summary> /// Computes the maximum flow between <see cref="MaximumFlowAlgorithm{TVertex,TEdge}.Source"/> /// and <see cref="MaximumFlowAlgorithm{TVertex,TEdge}.Sink"/>. /// </summary> protected override void InternalCompute() { ThrowIfCancellationRequested(); IMutableVertexAndEdgeListGraph <TVertex, TEdge> graph = VisitedGraph; foreach (TVertex vertex in graph.Vertices) { foreach (TEdge edge in graph.OutEdges(vertex)) { double capacity = Capacities(edge); if (capacity < 0) { throw new NegativeCapacityException(); } ResidualCapacities[edge] = capacity; } } VerticesColors[Sink] = GraphColor.Gray; while (VerticesColors[Sink] != GraphColor.White) { var verticesPredecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(Predecessors); var queue = new Collections.Queue <TVertex>(); var bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>( ResidualGraph, queue, VerticesColors); using (verticesPredecessors.Attach(bfs)) bfs.Compute(Source); if (VerticesColors[Sink] != GraphColor.White) { Augment(Source, Sink); } } MaxFlow = 0; foreach (TEdge edge in graph.OutEdges(Source)) { MaxFlow += (Capacities(edge) - ResidualCapacities[edge]); } }
public IEnumerable <ReferenceEdge> GetShortestPathToRoot(long addr) { if (cachedAddr == addr && cachedResult != null) { return(cachedResult); } if (Roots.ContainsKey(addr)) { cachedResult = new List <ReferenceEdge>(); cachedAddr = addr; return(cachedResult); } if (!referencesFromBuilt) { referencesFromBuilt = true; var sw = Stopwatch.StartNew(); BuildReferencesFrom(); sw.Stop(); } var bfsa = new BreadthFirstSearchAlgorithm <long, ReferenceEdge>(this); var vis = new VertexPredecessorRecorderObserver <long, ReferenceEdge>(); vis.Attach(bfsa); long foundRoot = 0; //possible optimisation to find only shortest path, worthiness is questionable bfsa.ExamineVertex += (vertex) => { if (Roots.ContainsKey(vertex)) { bfsa.Services.CancelManager.Cancel(); foundRoot = vertex; } }; bfsa.Compute(addr); if (!vis.TryGetPath(foundRoot, out var path)) { path = new List <ReferenceEdge>(); } //Find shortest path cachedResult = path; cachedAddr = addr; return(cachedResult); }
public void GraphWithSelfEdges() { Random rnd = new Random(); for (int i = 0; i < 10; ++i) { for (int j = 0; j < i * i; ++j) { AdjacencyGraph g = new AdjacencyGraph( new QuickGraph.Providers.VertexProvider(), new QuickGraph.Providers.EdgeProvider(), true); RandomGraph.Graph(g, i, j, rnd, true); BreadthFirstSearchAlgorithm bfs = new BreadthFirstSearchAlgorithm(g); bfs.InitializeVertex += new VertexEventHandler(this.InitializeVertex); bfs.DiscoverVertex += new VertexEventHandler(this.DiscoverVertex); bfs.ExamineEdge += new EdgeEventHandler(this.ExamineEdge); bfs.ExamineVertex += new VertexEventHandler(this.ExamineVertex); bfs.TreeEdge += new EdgeEventHandler(this.TreeEdge); bfs.NonTreeEdge += new EdgeEventHandler(this.NonTreeEdge); bfs.GrayTarget += new EdgeEventHandler(this.GrayTarget); bfs.BlackTarget += new EdgeEventHandler(this.BlackTarget); bfs.FinishVertex += new VertexEventHandler(this.FinishVertex); Parents.Clear(); Distances.Clear(); m_CurrentDistance = 0; m_SourceVertex = RandomGraph.Vertex(g, rnd); foreach (IVertex v in g.Vertices) { Distances[v] = int.MaxValue; Parents[v] = v; } Distances[SourceVertex] = 0; bfs.Compute(SourceVertex); CheckBfs(g, bfs); } } }
private AdjacencyGraph <string, SEdge <string> > GetDependencyGraph(IEnumerable <string> targetNames) { var baseTargetNames = targetNames.Where(_targets.ContainsKey); var subgraph = new AdjacencyGraph <string, SEdge <string> >(); foreach (var baseTarget in baseTargetNames) { var search = new BreadthFirstSearchAlgorithm <string, SEdge <string> >(_dependencies); subgraph.AddVertex(baseTarget); search.SetRootVertex(baseTarget); search.TreeEdge += x => { Console.WriteLine("{0}->{1}", x.Source, x.Target); subgraph.AddVerticesAndEdge(x); }; search.Compute(); } return(subgraph); }
public void Build() { ExpansionTreeNode rootNode; switch (_numberOfNodes) { case 3: rootNode = ExpansionTree.BuildThreeNodesTree(); NumberOfQueryGraphs = 2; break; case 4: rootNode = ExpansionTree.BuildFourNodesTree(); NumberOfQueryGraphs = 6; break; case 5: rootNode = ExpansionTree.BuildFiveNodesTree(); NumberOfQueryGraphs = 21; break; default: throw new System.NotSupportedException("Subgraph sizes below 3 and above 5 are not supported, unless you supply a query graph."); } //TODO: Construct the tree. // It turns out there's yet no formula to determine the number of isomorphic trees that can be formed // from n nodes; hence no way(?) of writing a general code var bfs = new BreadthFirstSearchAlgorithm <ExpansionTreeNode>(ExpansionTree); bfs.SetRootVertex(rootNode); bfs.Compute(); VerticesSorted = new Queue <ExpansionTreeNode>(bfs.VertexColors.Count); foreach (var item in bfs.VertexColors) { VerticesSorted.Enqueue(item.Key); } bfs.VertexColors.Clear(); bfs = null; VerticesSorted.Dequeue(); // remove the root }
public List <IEnumerable <ReferenceEdge> > GetTop5PathsToRoots(long addr) { if (cachedAddr == addr && cachedResult != null) { return(cachedResult); } cachedResult = new List <IEnumerable <ReferenceEdge> > (); cachedAddr = addr; if (Roots.ContainsKey(addr)) { return(cachedResult); } BuildReferencesFrom(); var result = new List <List <ReferenceEdge> > (); var bfsa = new BreadthFirstSearchAlgorithm <long, ReferenceEdge> (this); var vis = new VertexPredecessorRecorderObserver <long, ReferenceEdge> (); vis.Attach(bfsa); var visitedRoots = new HashSet <long> (); bfsa.ExamineVertex += (vertex) => { if (Roots.ContainsKey(vertex)) { visitedRoots.Add(vertex); if (visitedRoots.Count == 5) { bfsa.Services.CancelManager.Cancel(); } } }; bfsa.Compute(addr); foreach (var root in visitedRoots) { if (vis.TryGetPath(root, out var path)) { cachedResult.Add(path); } } return(cachedResult); }
public double Compute(Vertex src, Vertex sink) { m_ResidualEdgeCapacities = new EdgeDoubleDictionary(); // initializing foreach (Vertex u in VisitedGraph.Vertices) { foreach (Edge e in u.OutEdges) { ResidualCapacities[e] = Capacities[e]; } } Colors[sink] = GraphColor.Gray; while (Colors[sink] != GraphColor.White) { VertexBuffer Q = new VertexBuffer(); ResidualEdgePredicate ep = new ResidualEdgePredicate(ResidualCapacities); BreadthFirstSearchAlgorithm bfs = new BreadthFirstSearchAlgorithm(resg, Q, Colors); PredecessorVisitor pred = new PredecessorVisitor(Predecessors); pred.RegisterHandlers(bfs); bfs.Compute(src); if (Colors[sink] != GraphColor.White) { Augment(src, sink, pred.Predecessors); } } // while double flow = 0; foreach (Edge e in src.OutEdges) { flow += (EdgeCapacities[e] - ResidualEdgeCapacities[e]); } return(flow); }
private IEnumerable <ICollection <TEdge> > TrailsInternal(TVertex startingVertex) { int index = FindFirstEdgeInCircuit(startingVertex); // Create trail var trail = new List <TEdge>(); var bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>(VisitedGraph); var vis = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (vis.Attach(bfs)) { bfs.Compute(startingVertex); // Go through the edges and build the predecessor table int start = index; for (; index < _circuit.Count; ++index) { TEdge edge = _circuit[index]; if (_temporaryEdges.Contains(edge)) { // Store previous trail and start new one if (trail.Count != 0) { yield return(trail); } // Start new trail // Take the shortest path from the start vertex to the target vertex if (!vis.TryGetPath(edge.Target, out IEnumerable <TEdge> path)) { throw new InvalidOperationException(); } trail = new List <TEdge>(path); } else { trail.Add(edge); } } // Starting again on the circuit for (index = 0; index < start; ++index) { TEdge edge = _circuit[index]; if (_temporaryEdges.Contains(edge)) { // Store previous trail and start new one if (trail.Count != 0) { yield return(trail); } // Start new trail // Take the shortest path from the start vertex to the target vertex if (!vis.TryGetPath(edge.Target, out IEnumerable <TEdge> path)) { throw new InvalidOperationException(); } trail = new List <TEdge>(path); } else { trail.Add(edge); } } } // Adding the last element if (trail.Count != 0) { yield return(trail); } }
public void RunBfsAndCheck <TVertex, TEdge>( [NotNull] IVertexAndEdgeListGraph <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 BreadthFirstSearchAlgorithm <TVertex, TEdge>(graph); algorithm.InitializeVertex += u => { Assert.AreEqual(algorithm.VerticesColors[u], GraphColor.White); }; algorithm.DiscoverVertex += u => { Assert.AreEqual(algorithm.VerticesColors[u], GraphColor.Gray); if (u.Equals(sourceVertex)) { currentVertex = sourceVertex; } else { Assert.IsNotNull(currentVertex); Assert.AreEqual(parents[u], currentVertex); // ReSharper disable once AccessToModifiedClosure Assert.AreEqual(distances[u], currentDistance + 1); Assert.AreEqual(distances[u], distances[parents[u]] + 1); } }; algorithm.ExamineEdge += args => { Assert.AreEqual(args.Source, currentVertex); }; algorithm.ExamineVertex += args => { TVertex u = args; 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 += args => { TVertex u = args.Source; TVertex v = args.Target; Assert.AreEqual(algorithm.VerticesColors[v], GraphColor.White); Assert.AreEqual(distances[u], currentDistance); parents[v] = u; distances[v] = distances[u] + 1; }; algorithm.NonTreeEdge += args => { TVertex u = args.Source; TVertex v = args.Target; 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 += args => { Assert.AreEqual(algorithm.VerticesColors[args.Target], GraphColor.Gray); }; algorithm.BlackTarget += args => { Assert.AreEqual(algorithm.VerticesColors[args.Target], GraphColor.Black); foreach (TEdge edge in algorithm.VisitedGraph.OutEdges(args.Target)) { Assert.IsFalse(algorithm.VerticesColors[edge.Target] == GraphColor.White); } }; algorithm.FinishVertex += args => { Assert.AreEqual(algorithm.VerticesColors[args], GraphColor.Black); }; parents.Clear(); distances.Clear(); currentDistance = 0; foreach (TVertex vertex in graph.Vertices) { distances[vertex] = int.MaxValue; parents[vertex] = vertex; } distances[sourceVertex] = 0; algorithm.Compute(sourceVertex); // All white vertices should be unreachable from the source. foreach (TVertex vertex in graph.Vertices) { if (algorithm.VerticesColors[vertex] == GraphColor.White) { //!IsReachable(start,u,g); } } // 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); } } }