private bool Attempt(double eps) { Initialize(); int numRoots = 0; ICancelManager cancelManager = Services.CancelManager; foreach (TVertex vertex in VisitedGraph.Vertices) { if (cancelManager.IsCancelling) { break; } // First pass: exploration if (!Explore(eps, vertex, ref numRoots)) { return(false); } // Second pass: coloration Colorize(vertex); } return(true); }
/// <inheritdoc /> protected override void InternalCompute() { // If there is a starting vertex, start with him if (TryGetRootVertex(out TVertex root)) { OnStartVertex(root); Visit(root, 0); } // Process each vertex ICancelManager cancelManager = Services.CancelManager; foreach (TVertex vertex in VisitedGraph.Vertices) { if (cancelManager.IsCancelling) { return; } if (VerticesColors[vertex] == GraphColor.White) { OnStartVertex(vertex); Visit(vertex, 0); } } }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; while (_taskManager.HasTasks()) { if (cancelManager.IsCancelling) { return; } Task <TVertex, TEdge> task = _taskManager.GetTask(); if (task.IsResultReady()) { BestCost = task.MinCost; ResultPath = task.Path; return; } if (task.Split( out Task <TVertex, TEdge> task1, out Task <TVertex, TEdge> task2)) { _taskManager.AddTask(task1); _taskManager.AddTask(task2); } } }
/// <inheritdoc /> protected override void InternalCompute() { if (!TryGetRootVertex(out TVertex root)) { throw new InvalidOperationException("Root vertex not set."); } // Start with root vertex OnStartVertex(root); ICancelManager cancelManager = Services.CancelManager; // Process each out edge of the root one foreach (TEdge edge in VisitedGraph.OutEdges(root)) { if (cancelManager.IsCancelling) { return; } if (!EdgesColors.ContainsKey(edge)) { OnStartEdge(edge); Visit(edge, 0); } } }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; 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)) { --InDegrees[edge.Target]; Debug.Assert(InDegrees[edge.Target] >= 0); _heap.Update(edge.Target); } } SortedVertices = _sortedVertices.ToArray(); }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; IDictionary <TVertex, double> tempRanks = new Dictionary <TVertex, double>(); // Create filtered graph var filterGraph = new FilteredBidirectionalGraph <TVertex, TEdge, IBidirectionalGraph <TVertex, TEdge> >( VisitedGraph, new InDictionaryVertexPredicate <TVertex, double>(Ranks).Test, edge => true); int iteration = 0; double error; do { if (cancelManager.IsCancelling) { return; } // Compute page ranks error = 0; foreach (KeyValuePair <TVertex, double> pair in Ranks) { if (cancelManager.IsCancelling) { return; } TVertex vertex = pair.Key; double rank = pair.Value; // Compute ARi double r = 0; foreach (TEdge edge in filterGraph.InEdges(vertex)) { r += Ranks[edge.Source] / filterGraph.OutDegree(edge.Source); } // Add sourceRank and store it double newRank = (1 - Damping) + Damping * r; tempRanks[vertex] = newRank; // Compute deviation error += Math.Abs(rank - newRank); } // Swap ranks IDictionary <TVertex, double> temp = Ranks; Ranks = tempRanks; tempRanks = temp; ++iteration; } while (error > Tolerance && iteration < MaxIterations); }
/// <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 }
private void Visit([NotNull] TEdge startingEdge, int depth) { Debug.Assert(startingEdge != null); Debug.Assert(depth >= 0); if (depth > MaxDepth) { return; } // Mark edge as gray EdgesColors[startingEdge] = GraphColor.Gray; // Add edge to the search tree OnTreeEdge(startingEdge); ICancelManager cancelManager = Services.CancelManager; // Iterate over out-edges foreach (TEdge edge in VisitedGraph.OutEdges(startingEdge.Target)) { if (cancelManager.IsCancelling) { return; } // Check edge is not explored yet, // if not, explore it if (!EdgesColors.TryGetValue(edge, out GraphColor color)) { OnDiscoverTreeEdge(startingEdge, edge); Visit(edge, depth + 1); } else { if (color == GraphColor.Gray) { OnBackEdge(edge); } else { OnForwardOrCrossEdge(edge); } } } // All out-edges have been explored EdgesColors[startingEdge] = GraphColor.Black; OnFinishEdge(startingEdge); }
/// <inheritdoc /> protected override void InternalCompute() { if (!TryGetRootVertex(out TVertex rootVertex)) { throw new InvalidOperationException("Root vertex not set."); } ICancelManager cancelManager = Services.CancelManager; // Process root ClearTree(rootVertex); SetInTree(rootVertex); foreach (TVertex vertex in VisitedGraph.Vertices) { if (cancelManager.IsCancelling) { break; } // First pass: exploration { var visitedEdges = new Dictionary <TEdge, int>(); TVertex current = vertex; while (NotInTree(current) && TryGetSuccessor(visitedEdges, current, out TEdge successor)) { visitedEdges[successor] = 0; Tree(current, successor); if (!TryGetNextInTree(current, out current)) { break; } } } // Second pass: coloration { TVertex current = vertex; while (NotInTree(current)) { SetInTree(current); if (!TryGetNextInTree(current, out current)) { break; } } } } }
/// <inheritdoc /> protected override void AugmentGraph() { ICancelManager cancelManager = Services.CancelManager; foreach (TVertex vertex in VisitedGraph.Vertices) { if (cancelManager.IsCancelling) { break; } AddAugmentedEdge(SuperSource, vertex); AddAugmentedEdge(vertex, SuperSink); } }
/// <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 Initialize() { // Put all edges to white ICancelManager cancelManager = Services.CancelManager; foreach (TEdge edge in VisitedGraph.Edges) { if (cancelManager.IsCancelling) { return; } EdgesColors[edge] = GraphColor.White; OnEdgeInitialized(edge); } }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; DirectedGraph = new DirectedGraph(); var nodes = new List <DirectedGraphNode>(VisitedGraph.VertexCount); foreach (TVertex vertex in VisitedGraph.Vertices) { if (cancelManager.IsCancelling) { return; } var node = new DirectedGraphNode { Id = _vertexIdentities(vertex) }; OnFormatNode(vertex, node); nodes.Add(node); } DirectedGraph.Nodes = nodes.ToArray(); var links = new List <DirectedGraphLink>(VisitedGraph.EdgeCount); foreach (TEdge edge in VisitedGraph.Edges) { if (cancelManager.IsCancelling) { return; } var link = new DirectedGraphLink { Label = _edgeIdentities(edge), Source = _vertexIdentities(edge.Source), Target = _vertexIdentities(edge.Target) }; OnFormatEdge(edge, link); links.Add(link); } DirectedGraph.Links = links.ToArray(); OnFormatGraph(); }
private void Visit([NotNull] TEdge rootEdge, int depth) { Debug.Assert(rootEdge != null); if (depth > MaxDepth) { return; } ICancelManager cancelManager = Services.CancelManager; // Mark edge as gray EdgesColors[rootEdge] = GraphColor.Gray; // Add edge to the search tree OnTreeEdge(rootEdge); // Iterate over out-edges foreach (TEdge edge in VisitedGraph.OutEdges(rootEdge.Target)) { if (cancelManager.IsCancelling) { return; } // Check edge is not explored yet, // If not, explore it if (EdgesColors[edge] == GraphColor.White) { OnDiscoverTreeEdge(rootEdge, edge); Visit(edge, depth + 1); } else if (EdgesColors[edge] == GraphColor.Gray) { // Edge is being explored OnBackEdge(edge); } else { // Edge is black OnForwardOrCrossEdge(edge); } } // All out-edges have been explored EdgesColors[rootEdge] = GraphColor.Black; OnFinishEdge(rootEdge); }
/// <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; if (cancelManager.IsCancelling) { return; } // Start with root vertex if (TryGetRootVertex(out TVertex root)) { OnStartVertex(root); // Process each out edge of the root one foreach (TEdge edge in VisitedGraph.OutEdges(root)) { if (cancelManager.IsCancelling) { return; } if (EdgesColors[edge] == GraphColor.White) { OnStartEdge(edge); Visit(edge, 0); } } } // Process the rest of the graph edges foreach (TEdge edge in VisitedGraph.Edges) { if (cancelManager.IsCancelling) { return; } if (EdgesColors[edge] == GraphColor.White) { OnStartEdge(edge); Visit(edge, 0); } } }
private void Visit([NotNull] TVertex u, int depth) { Debug.Assert(u != null); if (depth > MaxDepth) { return; } VertexColors[u] = GraphColor.Gray; OnDiscoverVertex(u); ICancelManager cancelManager = Services.CancelManager; foreach (TEdge edge in VisitedGraph.OutEdges(u)) { if (cancelManager.IsCancelling) { return; } OnExamineEdge(edge); TVertex v = edge.Target; if (!VertexColors.TryGetValue(v, out GraphColor vColor)) { OnTreeEdge(edge); Visit(v, depth + 1); } else { if (vColor == GraphColor.Gray) { OnBackEdge(edge); } else { OnForwardOrCrossEdge(edge); } } } VertexColors[u] = GraphColor.Black; OnVertexFinished(u); }
/// <summary> /// Runs a random tree generation. /// </summary> public void RandomTree() { ICancelManager cancelManager = Services.CancelManager; double eps = 1; bool success; do { if (cancelManager.IsCancelling) { break; } eps /= 2; success = Attempt(eps); } while (!success); }
/// <inheritdoc /> protected override void Initialize() { base.Initialize(); // Initialize vertices ICancelManager cancelManager = Services.CancelManager; if (cancelManager.IsCancelling) { return; } foreach (TVertex vertex in VisitedGraph.Vertices) { VerticesColors[vertex] = GraphColor.White; OnVertexInitialized(vertex); } }
private void FlushVisitQueue() { ICancelManager cancelManager = Services.CancelManager; while (_vertexQueue.Count > 0) { if (cancelManager.IsCancelling) { return; } TVertex u = _vertexQueue.Dequeue(); OnExamineVertex(u); foreach (TEdge edge in OutEdgesFilter(VisitedGraph.OutEdges(u))) { TVertex v = edge.Target; OnExamineEdge(edge); GraphColor vColor = VerticesColors[v]; if (vColor == GraphColor.White) { OnTreeEdge(edge); VerticesColors[v] = GraphColor.Gray; OnDiscoverVertex(v); _vertexQueue.Enqueue(v); } else { OnNonTreeEdge(edge); if (vColor == GraphColor.Gray) { OnGrayTarget(edge); } else { OnBlackTarget(edge); } } } VerticesColors[u] = GraphColor.Black; OnVertexFinished(u); } }
private void Visit([NotNull] TVertex u, int depth) { Debug.Assert(u != null); if (depth > MaxDepth) { return; } VerticesColors[u] = GraphColor.Gray; OnDiscoverVertex(u); ICancelManager cancelManager = Services.CancelManager; foreach (TEdge edge in VisitedGraph.OutEdges(u)) { if (cancelManager.IsCancelling) { return; } OnExamineEdge(edge); TVertex v = edge.Target; ProcessEdge(depth, v, edge); } foreach (TEdge edge in VisitedGraph.InEdges(u)) { if (cancelManager.IsCancelling) { return; } OnExamineEdge(edge); TVertex v = edge.Source; ProcessEdge(depth, v, edge); } VerticesColors[u] = GraphColor.Black; OnVertexFinished(u); }
private void FlushVisitQueue() { ICancelManager cancelManager = Services.CancelManager; while (_vertexQueue.Count > 0) { if (cancelManager.IsCancelling) { return; } TVertex u = _vertexQueue.Dequeue(); OnExamineVertex(u); ExploreAdjacentEdges(u); VerticesColors[u] = GraphColor.Black; OnVertexFinished(u); } }
/// <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; if (cancelManager.IsCancelling) { return; } TVertex[] vertices = VisitedGraph.Vertices.ToArray(); // Walk each vertices and make sure cost self-cost 0 foreach (TVertex vertex in vertices) { _data[new SEquatableEdge <TVertex>(vertex, vertex)] = new VertexData(0, default(TEdge)); } if (cancelManager.IsCancelling) { return; } // Iterate k, i, j foreach (TVertex vk in vertices) { if (cancelManager.IsCancelling) { return; } FillIData(vertices, vk); } // Check negative cycles CheckNegativeCycles(vertices); }
/// <inheritdoc /> protected override void AugmentGraph() { ICancelManager cancelManager = Services.CancelManager; foreach (TVertex vertex in VisitedGraph.Vertices) { if (cancelManager.IsCancelling) { break; } // Is source if (VisitedGraph.IsInEdgesEmpty(vertex)) { AddAugmentedEdge(SuperSource, vertex); } // Is sink if (VisitedGraph.IsOutEdgesEmpty(vertex)) { AddAugmentedEdge(vertex, SuperSink); } } }
/// <inheritdoc /> protected override void InternalCompute() { TVertex root = GetAndAssertRootInGraph(); if (!TryGetTargetVertex(out TVertex target)) { throw new InvalidOperationException("Target vertex not set."); } if (!VisitedGraph.ContainsVertex(target)) { throw new VertexNotFoundException("Target vertex is not part of the graph."); } // Little shortcut if (root.Equals(target)) { OnTargetReached(); return; // Found it } ICancelManager cancelManager = Services.CancelManager; var open = new BinaryHeap <double, TVertex>(_distanceRelaxer.Compare); // (1) Place the initial node in Open, with all its operators marked unused open.Add(0, root); Dictionary <TEdge, GraphColor> operators = VisitedGraph.OutEdges(root).ToDictionary(edge => edge, edge => GraphColor.White); while (open.Count > 0) { if (cancelManager.IsCancelling) { return; } // (3) Else, choose an Open node n of lowest cost for expansion KeyValuePair <double, TVertex> entry = open.RemoveMinimum(); double cost = entry.Key; TVertex n = entry.Value; // (4) If node n is a target node, terminate with success if (n.Equals(target)) { OnTargetReached(); return; } // (5) Else, expand node n, generating all // successors n' reachable via unused legal operators, // compute their cost and delete node n ExpandNode(n, operators, cost, open); #if DEBUG OperatorMaxCount = Math.Max(OperatorMaxCount, operators.Count); #endif // (6) In a directed graph, generate each predecessor node n via an unused operator // and create dummy nodes for each with costs of infinity foreach (TEdge edge in VisitedGraph.InEdges(n)) { if (operators.TryGetValue(edge, out GraphColor edgeColor) && edgeColor == GraphColor.Gray) { // Delete node n operators.Remove(edge); } } } }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; BipartiteToMaximumFlowGraphAugmentorAlgorithm <TVertex, TEdge> augmentor = null; ReversedEdgeAugmentorAlgorithm <TVertex, TEdge> reverser = null; try { if (cancelManager.IsCancelling) { return; } // Augmenting the graph augmentor = new BipartiteToMaximumFlowGraphAugmentorAlgorithm <TVertex, TEdge>( this, VisitedGraph, SourceToVertices, VerticesToSink, VertexFactory, EdgeFactory); augmentor.Compute(); if (cancelManager.IsCancelling) { return; } // Adding reverse edges reverser = new ReversedEdgeAugmentorAlgorithm <TVertex, TEdge>( VisitedGraph, EdgeFactory); reverser.AddReversedEdges(); if (cancelManager.IsCancelling) { return; } // Compute maximum flow var flow = new EdmondsKarpMaximumFlowAlgorithm <TVertex, TEdge>( this, VisitedGraph, edge => 1.0, EdgeFactory, reverser); flow.Compute(augmentor.SuperSource, augmentor.SuperSink); if (cancelManager.IsCancelling) { return; } foreach (TEdge edge in VisitedGraph.Edges) { if (Math.Abs(flow.ResidualCapacities[edge]) < float.Epsilon) { if (edge.Source.Equals(augmentor.SuperSource) || edge.Source.Equals(augmentor.SuperSink) || edge.Target.Equals(augmentor.SuperSource) || edge.Target.Equals(augmentor.SuperSink)) { // Skip all edges that connect to SuperSource or SuperSink continue; } _matchedEdges.Add(edge); } } } finally { if (reverser != null && reverser.Augmented) { reverser.RemoveReversedEdges(); } if (augmentor != null && augmentor.Augmented) { augmentor.Rollback(); } } }
/// <inheritdoc /> protected override void InternalCompute() { // Create condensed graph CondensedGraph = new BidirectionalGraph <TGraph, CondensedEdge <TVertex, TEdge, TGraph> >(false); if (VisitedGraph.VertexCount == 0) { return; } // Compute strongly connected components var components = new Dictionary <TVertex, int>(VisitedGraph.VertexCount); int componentCount = ComputeComponentCount(components); ICancelManager cancelManager = Services.CancelManager; if (cancelManager.IsCancelling) { return; } // Create vertices list var condensedVertices = new Dictionary <int, TGraph>(componentCount); for (int i = 0; i < componentCount; ++i) { var vertex = new TGraph(); condensedVertices.Add(i, vertex); CondensedGraph.AddVertex(vertex); } // Adding vertices foreach (TVertex vertex in VisitedGraph.Vertices) { condensedVertices[components[vertex]].AddVertex(vertex); } if (cancelManager.IsCancelling) { return; } // Condensed edges var condensedEdges = new Dictionary <EdgeKey, CondensedEdge <TVertex, TEdge, TGraph> >(componentCount); // Iterate over edges and condensate graph foreach (TEdge edge in VisitedGraph.Edges) { // Get component ids int sourceID = components[edge.Source]; int targetID = components[edge.Target]; // Get vertices TGraph sources = condensedVertices[sourceID]; if (sourceID == targetID) { sources.AddEdge(edge); continue; } // At last add edge var edgeKey = new EdgeKey(sourceID, targetID); if (!condensedEdges.TryGetValue(edgeKey, out CondensedEdge <TVertex, TEdge, TGraph> condensedEdge)) { TGraph targets = condensedVertices[targetID]; condensedEdge = new CondensedEdge <TVertex, TEdge, TGraph>(sources, targets); condensedEdges.Add(edgeKey, condensedEdge); CondensedGraph.AddEdge(condensedEdge); } condensedEdge.Edges.Add(edge); } }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; TVertex root = GetAndAssertRootInGraph(); if (!TryGetTargetVertex(out TVertex target)) { throw new InvalidOperationException("Target vertex not set."); } if (!VisitedGraph.ContainsVertex(target)) { throw new VertexNotFoundException("Target vertex is not part of the graph."); } // Start by building the minimum tree starting from the target vertex. ComputeMinimumTree( target, out IDictionary <TVertex, TEdge> successors, out IDictionary <TVertex, double> distances); if (cancelManager.IsCancelling) { return; } var queue = new FibonacciQueue <DeviationPath, double>(deviationPath => deviationPath.Weight); int vertexCount = VisitedGraph.VertexCount; // First shortest path EnqueueFirstShortestPath(queue, successors, distances, root); while (queue.Count > 0 && ComputedShortestPathCount < ShortestPathCount) { if (cancelManager.IsCancelling) { return; } DeviationPath deviation = queue.Dequeue(); // Turn into path var path = new List <TEdge>(); for (int i = 0; i < deviation.DeviationIndex; ++i) { path.Add(deviation.ParentPath[i]); } path.Add(deviation.DeviationEdge); int startEdge = path.Count; AppendShortestPath(path, successors, deviation.DeviationEdge.Target); Debug.Assert(Math.Abs(deviation.Weight - path.Sum(e => _edgeWeights(e))) < float.Epsilon); Debug.Assert(path.Count > 0); // Add to list if has no cycle if (!path.HasCycles <TVertex, TEdge>()) { AddComputedShortestPath(path); } // Append new deviation paths if (path.Count < vertexCount) { EnqueueDeviationPaths( queue, root, distances, path.ToArray(), startEdge); } } }