/// <summary> /// Used internally /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void FinishVertex(Object sender, VertexEventArgs args) { IVertex v = args.Vertex; foreach (IEdge e in VisitedGraph.OutEdges(v)) { IVertex w = e.Target; if (this.Components[w] == int.MaxValue) { this.Roots[v] = MinDiscoverTime(this.Roots[v], this.Roots[w]); } } if (Roots[v] == v) { IVertex w = null; do { w = (IVertex)this.stack.Peek(); this.stack.Pop(); this.Components[w] = count; }while (w != v); ++count; } }
//======================================================================= // The main purpose of this routine is to set distance[v] // to the smallest value allowed by the valid labeling constraints, // which are: // distance[t] = 0 // distance[u] <= distance[v] + 1 for every residual edge (u,v) // private int RelabelDistance(IVertex u) { int minEdges = 0; workSinceLastUpdate += beta; int minDistance = VisitedGraph.VerticesCount; distances[u] = minDistance; // Examine the residual out-edges of vertex i, choosing the // edge whose target vertex has the minimal distance. for (int ai = 0; ai < VisitedGraph.OutDegree(u); ai++) { ++workSinceLastUpdate; IEdge a = VisitedGraph.OutEdges(u)[ai]; IVertex v = a.Target; if (IsResidualEdge(a) && distances[v] < minDistance) { minDistance = distances[v]; minEdges = ai; } } ++minDistance; if (minDistance < n) { distances[u] = minDistance; // this is the main action current[u] = minEdges; maxDistance = Math.Max(minDistance, maxDistance); } return(minDistance); }
/// <summary> /// Creates a deep copy of an object using the supplied dictionary of visited objects as /// a source of objects already encountered in the copy traversal. The dictionary of visited /// objects is used for holding objects that have already been copied, to avoid erroneous /// duplication of parts of the object graph. /// </summary> /// <param name="instance">The object to be copied.</param> /// <param name="visited">The graph of objects visited so far.</param> /// <returns></returns> private static object Clone(this object instance, VisitedGraph visited) { if (instance == null) return null; Type instanceType = instance.GetType(); if(typeof(Type).IsAssignableFrom(instanceType)) { return instance; } if (instanceType.IsPointer || instanceType == typeof(Pointer) || instanceType.IsPrimitive || instanceType == typeof(string)) return instance; // Pointers, primitive types and strings are considered immutable if (instanceType.IsArray) { int length = ((Array)instance).Length; Array copied = (Array)Activator.CreateInstance(instanceType, length); visited.Add(instance, copied); for (int i = 0; i < length; ++i) copied.SetValue(((Array)instance).GetValue(i).Clone(visited), i); return copied; } return Clone(instance, visited, DeduceInstance(instance)); }
/// <summary> /// Execute the EDFS starting with the vertex s /// </summary> /// <param name="v">Starting vertex</param> public void Compute(IVertex v) { if (v == null) { throw new ArgumentNullException("entry point"); } Initialize(); // start whith him: OnStartVertex(v); // process each out edge of v foreach (IEdge e in VisitedGraph.InEdges(v)) { if (EdgeColors[e] == GraphColor.White) { OnStartEdge(e); Visit(e, 0); } } // process the rest of the graph edges foreach (IEdge e in VisitedGraph.Edges) { if (EdgeColors[e] == GraphColor.White) { OnStartEdge(e); Visit(e, 0); } } }
private void OnVertexFinished([NotNull] TVertex vertex) { foreach (TEdge edge in VisitedGraph.OutEdges(vertex)) { TVertex target = edge.Target; if (Components[target] == int.MaxValue) { Roots[vertex] = MinDiscoverTime(Roots[vertex], Roots[target]); } } if (Roots[vertex].Equals(vertex)) { TVertex w; do { w = _stack.Pop(); Components[w] = ComponentCount; ComponentsPerStep.Add(ComponentCount); VerticesPerStep.Add(w); ++Steps; }while (!w.Equals(vertex)); ++ComponentCount; } }
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; } }
/// <inheritdoc /> protected override void InternalCompute() { if (VisitedGraph.VertexCount == 0) { return; } if (TryGetRootVertex(out TVertex rootVertex)) { AssertRootInGraph(rootVertex); // Enqueue select root only EnqueueRoot(rootVertex); } else { // Enqueue roots foreach (TVertex root in VisitedGraph.Roots()) { EnqueueRoot(root); } } FlushVisitQueue(); }
private void AddReversedEdges([NotNull, ItemNotNull] IEnumerable <TEdge> notReversedEdges) { foreach (TEdge edge in notReversedEdges) { if (ReversedEdges.ContainsKey(edge)) { continue; } // Already been added if (FindReversedEdge(edge, out TEdge reversedEdge)) { ReversedEdges[edge] = reversedEdge; continue; } // Need to create one reversedEdge = EdgeFactory(edge.Target, edge.Source); if (!VisitedGraph.AddEdge(reversedEdge)) { throw new InvalidOperationException("Cannot add the reversed edge, this should not arrive..."); } _augmentedEdges.Add(reversedEdge); ReversedEdges[edge] = reversedEdge; ReversedEdges[reversedEdge] = edge; OnReservedEdgeAdded(reversedEdge); } }
private bool TryGetSuccessor([NotNull] IDictionary <TEdge, int> visited, [NotNull] TVertex vertex, out TEdge successor) { IEnumerable <TEdge> outEdges = VisitedGraph.OutEdges(vertex); IEnumerable <TEdge> edges = outEdges.Where(edge => !visited.ContainsKey(edge)); return(EdgeChain.TryGetSuccessor(edges, vertex, out successor)); }
private void FirstWalk([NotNull] TVertex vertex) { Debug.Assert(vertex != null); BalloonData data = _data[vertex]; _visitedVertices.Add(vertex); data.D = 0; float s = 0; foreach (TEdge edge in VisitedGraph.OutEdges(vertex)) { TVertex otherVertex = edge.Target; BalloonData otherData = _data[otherVertex]; if (!_visitedVertices.Contains(otherVertex)) { FirstWalk(otherVertex); data.D = Math.Max(data.D, otherData.R); otherData.A = (float)Math.Atan((float)otherData.R / (data.D + otherData.R)); s += otherData.A; } } AdjustChildren(data, s); SetRadius(data); }
private IEdgeEnumerable SelectOutEdgesNotInCircuit(IVertex v) { return(new FilteredEdgeEnumerable( VisitedGraph.OutEdges(v), new NotInCircuitEdgePredicate(Circuit, TemporaryCircuit) )); }
static object Clone(object instance, VisitedGraph visited, object clone) { if (visited.ContainsKey(instance)) { return(visited[instance]); } visited.Add(instance, clone); Type type = instance.GetType(); while (type != null) { var ta = TypeAccessor.GetAccessor(type); foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { object value = ta.GetField(field.Name, instance); object cloneValue = visited.ContainsKey(value) ? visited[value] : Clone(value, visited); ta.SetField(field.Name, clone, cloneValue); } type = type.BaseType; } return(clone); }
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; } }
protected void AssertRootInGraph([NotNull] TVertex root) { if (!VisitedGraph.ContainsVertex(root)) { throw new VertexNotFoundException("Root vertex is not part of the graph."); } }
private void ComputeNoInit([NotNull] TVertex root) { IEnumerable <TVertex> orderedVertices = VisitedGraph.TopologicalSort(); OnDiscoverVertex(root); foreach (TVertex vertex in orderedVertices) { OnStartVertex(vertex); OnExamineVertex(vertex); foreach (TEdge edge in VisitedGraph.OutEdges(vertex)) { OnExamineEdge(edge); OnDiscoverVertex(edge.Target); bool decreased = Relax(edge); if (decreased) { OnTreeEdge(edge); } else { OnEdgeNotRelaxed(edge); } } OnFinishVertex(vertex); } }
internal void ComputeNoInit(IVertex s) { VertexCollection orderedVertices = new VertexCollection(); TopologicalSortAlgorithm topoSorter = new TopologicalSortAlgorithm(VisitedGraph, orderedVertices); topoSorter.Compute(); OnDiscoverVertex(s); foreach (IVertex v in orderedVertices) { OnExamineVertex(v); foreach (IEdge e in VisitedGraph.OutEdges(v)) { OnDiscoverVertex(e.Target); bool decreased = Relax(e); if (decreased) { OnEdgeRelaxed(e); } else { OnEdgeNotRelaxed(e); } } OnFinishVertex(v); } }
/// <summary> /// Used internally /// </summary> /// <param name="sender"></param> /// <param name="args"></param> public void FinishVertex(Object sender, VertexEventArgs args) { IVertex v = args.Vertex; foreach (IEdge e in VisitedGraph.OutEdges(v)) { IVertex w = e.Target; if (Components[w] == int.MaxValue) { Roots[v] = MinDiscoverTime(Roots[v], Roots[w]); } } if (Roots[v] == v) { IVertex w = null; do { w = (IVertex)m_Stack.Peek(); m_Stack.Pop(); Components[w] = m_Count; }while (w != v); ++m_Count; } }
protected override void InternalCompute() { Initialize(); // start whith him: if (this.RootVertex != null) { OnStartVertex(this.RootVertex); // process each out edge of v foreach (Edge e in VisitedGraph.OutEdges(this.RootVertex)) { if (EdgeColors[e] == GraphColor.White) { OnStartEdge(e); Visit(e, 0); } } } // process the rest of the graph edges foreach (Edge e in VisitedGraph.Edges) { if (EdgeColors[e] == GraphColor.White) { OnStartEdge(e); Visit(e, 0); } } }
private void FirstWalk(TVertex v) { var data = _datas[v]; _visitedVertices.Add(v); data.D = 0; float s = 0; foreach (var edge in VisitedGraph.OutEdges(v)) { var otherVertex = edge.Target; var otherData = _datas[otherVertex]; if (_visitedVertices.Contains(otherVertex)) { continue; } FirstWalk(otherVertex); data.D = Math.Max(data.D, otherData.R); otherData.A = (float)Math.Atan(((float)otherData.R) / (data.D + otherData.R)); s += otherData.A; } AdjustChildren(v, data, s); SetRadius(v, data); }
/// <inheritdoc /> protected override void Initialize() { base.Initialize(); FoundNegativeCycle = false; // Initialize colors and distances VerticesColors.Clear(); foreach (TVertex vertex in VisitedGraph.Vertices) { VerticesColors[vertex] = GraphColor.White; SetVertexDistance(vertex, double.PositiveInfinity); OnInitializeVertex(vertex); } if (!TryGetRootVertex(out TVertex root)) { // Try to fallback on first vertex, will throw if the graph is empty root = VisitedGraph.Vertices.First(); } else if (!VisitedGraph.ContainsVertex(root)) { throw new VertexNotFoundException("Root vertex is not part of the graph."); } SetVertexDistance(root, 0); }
private void SecondWalk([NotNull] TVertex vertex, double x, double y, float l, float t) { Debug.Assert(vertex != null); var position = new Point(x, y); VerticesPositions[vertex] = position; _visitedVertices.Add(vertex); BalloonData data = _data[vertex]; float dd = l * data.D; float p = (float)(t + Math.PI); int degree = VisitedGraph.OutDegree(vertex); float fs = degree == 0 ? 0 : data.F / degree; float pr = 0; foreach (TEdge edge in VisitedGraph.OutEdges(vertex)) { TVertex otherVertex = edge.Target; if (_visitedVertices.Contains(otherVertex)) { continue; } BalloonData otherData = _data[otherVertex]; float aa = data.C * otherData.A; float rr = (float)(data.D * Math.Tan(aa) / (1 - Math.Tan(aa))); p += pr + aa + fs; float xx = (float)((l * rr + dd) * Math.Cos(p)); float yy = (l * rr + dd) * Math.Sign(p); pr = aa; SecondWalk(otherVertex, x + xx, y + yy, l * data.C, p); } }
/// <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(); }
private void OnVertexFinished([NotNull] TVertex vertex) { foreach (TVertex target in VisitedGraph.OutEdges(vertex).Select(edge => edge.Target)) { if (Components[target] == int.MaxValue) { Roots[vertex] = MinDiscoverTime(Roots[vertex], Roots[target]); } } if (EqualityComparer <TVertex> .Default.Equals(Roots[vertex], vertex)) { TVertex w; do { w = _stack.Pop(); Components[w] = ComponentCount; ComponentsPerStep.Add(ComponentCount); VerticesPerStep.Add(w); ++Steps; }while (!EqualityComparer <TVertex> .Default.Equals(w, vertex)); ++ComponentCount; } }
private void FirstWalk(TVertex v) { var data = datas[v]; visitedVertices.Add(v); data.d = 0; float s = 0; foreach (var edge in VisitedGraph.OutEdges(v)) { var otherVertex = edge.Target; var otherData = datas[otherVertex]; if (!visitedVertices.Contains(otherVertex)) { FirstWalk(otherVertex); data.d = Math.Max(data.d, otherData.r); otherData.a = (float)Math.Atan(((float)otherData.r) / (data.d + otherData.r)); s += otherData.a; } } AdjustChildren(v, data, s); SetRadius(v, data); }
private void SecondWalk(TVertex v, TVertex r, double x, double y, float l, float t) { Point pos = new Point(x, y); VertexPositions[v] = pos; visitedVertices.Add(v); BalloonData data = datas[v]; float dd = l * data.d; float p = (float)(t + Math.PI); int degree = VisitedGraph.OutDegree(v); float fs = (degree == 0 ? 0 : data.f / degree); float pr = 0; foreach (var edge in VisitedGraph.OutEdges(v)) { var otherVertex = edge.Target; if (visitedVertices.Contains(otherVertex)) { continue; } var otherData = datas[otherVertex]; float aa = data.c * otherData.a; float rr = (float)(data.d * Math.Tan(aa) / (1 - Math.Tan(aa))); p += pr + aa + fs; float xx = (float)((l * rr + dd) * Math.Cos(p)); float yy = (float)((l * rr + dd) * Math.Sign(p)); pr = aa;; SecondWalk(otherVertex, v, x + xx, y + yy, l * data.c, p); } }
private bool FindAdjacentOddVertex( TVertex u, ICollection <TVertex> oddVertices, EdgeFactory <TVertex, TEdge> edgeFactory, out bool foundAdjacent) { bool found = false; foundAdjacent = false; foreach (TEdge edge in VisitedGraph.OutEdges(u)) { TVertex v = edge.Target; if (!EqualityComparer <TVertex> .Default.Equals(v, u) && oddVertices.Contains(v)) { foundAdjacent = true; // Check that v does not have an out-edge towards u if (HasEdgeToward(u, v)) { continue; } // Add temporary edge AddTemporaryEdge(u, v, oddVertices, edgeFactory); // Set u to null found = true; break; } } return(found); }
private void ExpandNode( [NotNull] TVertex n, [NotNull] IDictionary <TEdge, GraphColor> operators, double cost, [NotNull] BinaryHeap <double, TVertex> open) { // Skip self-edges foreach (TEdge edge in VisitedGraph.OutEdges(n).Where(e => !e.IsSelfEdge())) { bool hasColor = operators.TryGetValue(edge, out GraphColor edgeColor); if (!hasColor || edgeColor == GraphColor.White) { double weight = _edgeWeights(edge); double nCost = _distanceRelaxer.Combine(cost, weight); // (7) For each neighboring node of n' mark the operator from n to n' as used // (8) For each node n', if there is no copy of n' in Open add it // else save in open on the copy of n' with lowest cost. Mark as used all operators // as used in any of the copies operators[edge] = GraphColor.Gray; if (open.MinimumUpdate(nCost, edge.Target)) { OnTreeEdge(edge); } } else { Debug.Assert(edgeColor == GraphColor.Gray); // Edge already seen, remove it operators.Remove(edge); } } }
/// <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); } } }
private bool FindAdjacentOddVertex( [NotNull] TVertex u, [NotNull, ItemNotNull] List <TVertex> oddVertices, [NotNull, InstantHandle] EdgeFactory <TVertex, TEdge> edgeFactory, out bool foundAdjacent) { bool found = false; foundAdjacent = false; foreach (TEdge edge in VisitedGraph.OutEdges(u)) { TVertex v = edge.Target; if (!v.Equals(u) && oddVertices.Contains(v)) { foundAdjacent = true; // Check that v does not have an out-edge towards u if (HasEdgeToward(u, v)) { continue; } // Add temporary edge AddTemporaryEdge(u, v, oddVertices, edgeFactory); // Set u to null found = true; break; } } return(found); }
/// <inheritdoc /> protected override void Initialize() { base.Initialize(); if (!_reverserAlgorithm.Augmented) { throw new InvalidOperationException( $"The graph has not been augmented yet.{Environment.NewLine}" + $"Call {nameof(ReversedEdgeAugmentorAlgorithm<int, Edge<int>>)}.{nameof(ReversedEdgeAugmentorAlgorithm<int, Edge<int>>.AddReversedEdges)}() before running this algorithm."); } if (Source == null) { throw new InvalidOperationException("Source is not specified."); } if (Sink == null) { throw new InvalidOperationException("Sink is not specified."); } if (!VisitedGraph.ContainsVertex(Source)) { throw new VertexNotFoundException("Source vertex is not part of the graph."); } if (!VisitedGraph.ContainsVertex(Sink)) { throw new VertexNotFoundException("Sink vertex is not part of the graph."); } }
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); } } } }
/// <summary> /// Creates a deep copy of an object using the supplied dictionary of visited objects as /// a source of objects already encountered in the copy traversal. The dictionary of visited /// objects is used for holding objects that have already been copied, to avoid erroneous /// duplication of parts of the object graph. /// </summary> /// <param name="instance">The object to be copied.</param> /// <param name="visited">The graph of objects visited so far.</param> /// <returns></returns> private static object Clone(this object instance, VisitedGraph visited) { if (instance == null) return null; Type instanceType = instance.GetType(); if (instanceType.IsValueType || instanceType == typeof(string)) return instance; // Value types and strings are immutable else if (instanceType.IsArray) { int length = ((Array)instance).Length; Array copied = (Array)Activator.CreateInstance(instanceType, length); visited.Add(instance, copied); for (int i = 0; i < length; ++i) copied.SetValue(((Array)instance).GetValue(i).Clone(visited), i); return copied; } else return Clone(instance, visited, InstanceCreator.GetInstance(instanceType)); }
private static object Clone(this object instance, VisitedGraph visited, object copy) { if (visited.ContainsKey(instance)) return visited[instance]; else visited.Add(instance, copy); Type type = instance.GetType(); while (type != null) { foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { object value = field.GetValue(instance); if (visited.ContainsKey(value)) field.SetValue(copy, visited[value]); else field.SetValue(copy, value.Clone(visited)); } type = type.BaseType; } return copy; }
private static object Clone(this object instance, VisitedGraph visited, object copy) { visited.Add(instance, copy); var type = instance.GetType(); foreach (var field in GetTypeCopyableFieldList(type)) { object value = field.Getter(instance); object cloned; if (value == null) cloned = null; else if (!visited.TryGetValue(value, out cloned)) cloned = value.Clone(visited); field.Setter(copy, cloned); } return copy; }