/// <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 InitAlgorithm() { vertices = new LinLogVertex[VisitedGraph.VertexCount]; var vertexMap = new Dictionary <TVertex, LinLogVertex>(); //vertexek indexelése int i = 0; foreach (TVertex v in VisitedGraph.Vertices) { vertices[i] = new LinLogVertex { Index = i, OriginalVertex = v, Attractions = new LinLogEdge[VisitedGraph.Degree(v)], RepulsionWeight = 0, Position = VertexPositions[v] }; vertexMap[v] = vertices[i]; i++; } //minden vertex-hez felépíti az attractionWeights, attractionIndexes, //és a repulsionWeights struktúrát, valamint átmásolja a pozícióját a VertexPositions-ból foreach (var v in vertices) { int attrIndex = 0; foreach (var e in VisitedGraph.InEdges(v.OriginalVertex)) { double weight = e is WeightedEdge <TVertex>?((e as WeightedEdge <TVertex>).Weight) : 1; v.Attractions[attrIndex] = new LinLogEdge { Target = vertexMap[e.Source], AttractionWeight = weight }; //TODO look at this line below //v.RepulsionWeight += weight; v.RepulsionWeight += 1; attrIndex++; } foreach (var e in VisitedGraph.OutEdges(v.OriginalVertex)) { double weight = e is WeightedEdge <TVertex>?((e as WeightedEdge <TVertex>).Weight) : 1; v.Attractions[attrIndex] = new LinLogEdge { Target = vertexMap[e.Target], AttractionWeight = weight }; //v.RepulsionWeight += weight; v.RepulsionWeight += 1; attrIndex++; } v.RepulsionWeight = Math.Max(v.RepulsionWeight, Parameters.gravitationMultiplier); } repulsionMultiplier = ComputeRepulsionMultiplier(); }
/// <summary> /// Does a depth first search on the vertex u /// </summary> /// <param name="u">vertex to explore</param> /// <param name="depth">current recursion depth</param> /// <exception cref="ArgumentNullException">u cannot be null</exception> public void Visit(IVertex u, int depth) { if (depth > this.maxDepth) { return; } if (u == null) { throw new ArgumentNullException("u"); } Colors[u] = GraphColor.Gray; OnDiscoverVertex(u); IVertex v = null; foreach (IEdge e in VisitedGraph.OutEdges(u)) { OnExamineOutEdge(e); v = e.Target; GraphColor c = Colors[v]; if (c == GraphColor.White) { OnTreeOutEdge(e); Visit(v, depth + 1); } else if (c == GraphColor.Gray) { OnBackOutEdge(e); } else { OnForwardOrCrossOutEdge(e); } } foreach (IEdge e in VisitedGraph.InEdges(u)) { OnExamineInEdge(e); v = e.Source; GraphColor c = Colors[v]; if (c == GraphColor.White) { OnTreeInEdge(e); Visit(v, depth + 1); } else if (c == GraphColor.Gray) { OnBackInEdge(e); } else { OnForwardOrCrossInEdge(e); } } Colors[u] = GraphColor.Black; OnFinishVertex(u); }
private void InitAlgorithm() { _vertices = new LinLogVertex[VisitedGraph.VertexCount]; var verticesMap = new Dictionary <TVertex, LinLogVertex>(); // Index vertices int i = 0; foreach (TVertex vertex in VisitedGraph.Vertices) { _vertices[i] = new LinLogVertex(i, vertex, new LinLogEdge[VisitedGraph.Degree(vertex)]) { RepulsionWeight = 0, Position = VerticesPositions[vertex] }; verticesMap[vertex] = _vertices[i]; ++i; } // Compute best attraction weight and attraction index for each vertex foreach (LinLogVertex vertex in _vertices) { int attractionIndex = 0; foreach (TEdge edge in VisitedGraph.InEdges(vertex.OriginalVertex)) { var weightedEdge = edge as WeightedEdge <TVertex>; double weight = weightedEdge?.Weight ?? 1; vertex.Attractions[attractionIndex] = new LinLogEdge(verticesMap[edge.Source], weight); // TODO update repulsion weight? ++vertex.RepulsionWeight; ++attractionIndex; } foreach (TEdge edge in VisitedGraph.OutEdges(vertex.OriginalVertex)) { var weightedEdge = edge as WeightedEdge <TVertex>; double weight = weightedEdge?.Weight ?? 1; vertex.Attractions[attractionIndex] = new LinLogEdge(verticesMap[edge.Target], weight); ++vertex.RepulsionWeight; ++attractionIndex; } vertex.RepulsionWeight = Math.Max(vertex.RepulsionWeight, Parameters.GravitationMultiplier); } _repulsionMultiplier = ComputeRepulsionMultiplier(); }
private void BuildTemporaryGraphs( [NotNull] ICollection <TVertex> side1, [NotNull] ICollection <TVertex> side2, [NotNull] out BidirectionalGraph <TVertex, Edge <TVertex> > graph1, [NotNull] out BidirectionalGraph <TVertex, TEdge> graph2) { // // The IN side // // on the IN side we should reverse the edges graph1 = new BidirectionalGraph <TVertex, Edge <TVertex> >(); graph1.AddVertexRange(side1); foreach (TVertex vertex in side1) { VerticesInfos[vertex] = DoubleTreeVertexType.Backward; foreach (TEdge edge in VisitedGraph.InEdges(vertex)) { if (!side1.Contains(edge.Source) || edge.IsSelfEdge()) { continue; } // Reverse the edge graph1.AddEdge(new Edge <TVertex>(edge.Target, edge.Source)); } } // // The OUT side // graph2 = new BidirectionalGraph <TVertex, TEdge>(); graph2.AddVertexRange(side2); foreach (TVertex vertex in side2) { VerticesInfos[vertex] = DoubleTreeVertexType.Forward; foreach (TEdge edge in VisitedGraph.OutEdges(vertex)) { if (!side2.Contains(edge.Target) || edge.IsSelfEdge()) { continue; } // Simply add the edge graph2.AddEdge(edge); } } }
public int GetBalancingIndex([NotNull] TVertex vertex) { if (vertex == null) { throw new ArgumentNullException(nameof(vertex)); } int balancingIndex = VisitedGraph.OutEdges(vertex).Sum(edge => _preFlow[edge]); foreach (TEdge edge in VisitedGraph.InEdges(vertex)) { int preFlow = _preFlow[edge]; balancingIndex -= preFlow; } return(balancingIndex); }
/// <summary> /// Visits vertex s /// </summary> /// <param name="u">vertex to visit</param> public void Visit(IVertex u) { VertexEventArgs uArgs = new VertexEventArgs(u); Colors[u] = GraphColor.Gray; OnDiscoverVertex(u); IEdgeEnumerable outEdges = VisitedGraph.OutEdges(u); VisitEdges(outEdges, true); IEdgeEnumerable intEdges = VisitedGraph.InEdges(u); VisitEdges(intEdges, false); Colors[u] = GraphColor.Black; OnFinishVertex(u); }
/// <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); } } }
public void Visit(TVertex u, int depth) { if (depth > this.maxDepth) { return; } if (u == null) { throw new ArgumentNullException("u"); } if (this.IsAborting) { return; } VertexColors[u] = GraphColor.Gray; OnDiscoverVertex(u); TVertex v = default(TVertex); foreach (TEdge e in VisitedGraph.OutEdges(u)) { if (this.IsAborting) { return; } OnExamineEdge(e); v = e.Target; ProcessEdge(depth, v, e); } foreach (TEdge e in VisitedGraph.InEdges(u)) { if (this.IsAborting) { return; } OnExamineEdge(e); v = e.Source; ProcessEdge(depth, v, e); } VertexColors[u] = GraphColor.Black; OnFinishVertex(u); }
public void Visit(TVertex u, int depth) { Contract.Requires(u != null); if (depth > this.maxDepth) { return; } VertexColors[u] = GraphColor.Gray; OnDiscoverVertex(u); var cancelManager = this.Services.CancelManager; TVertex v = default(TVertex); foreach (var e in VisitedGraph.OutEdges(u)) { if (cancelManager.IsCancelling) { return; } OnExamineEdge(e); v = e.Target; ProcessEdge(depth, v, e); } foreach (var e in VisitedGraph.InEdges(u)) { if (cancelManager.IsCancelling) { return; } OnExamineEdge(e); v = e.Source; ProcessEdge(depth, v, e); } VertexColors[u] = GraphColor.Black; OnFinishVertex(u); }
/// <summary> /// Does a depth first search on the vertex u /// </summary> /// <param name="se">edge to explore</param> /// <param name="depth">current exploration depth</param> /// <exception cref="ArgumentNullException">se cannot be null</exception> public void Visit(IEdge se, int depth) { if (depth > this.maxDepth) { return; } if (se == null) { throw new ArgumentNullException("se"); } // mark edge as gray EdgeColors[se] = GraphColor.Gray; // add edge to the search tree OnTreeEdge(se); // iterate over out-edges foreach (IEdge e in VisitedGraph.InEdges(se.Target)) { // check edge is not explored yet, // if not, explore it. if (EdgeColors[e] == GraphColor.White) { OnDiscoverTreeEdge(se, e); Visit(e, depth + 1); } else if (EdgeColors[e] == GraphColor.Gray) { // edge is being explored OnBackEdge(e); } else { // edge is black OnForwardOrCrossEdge(e); } } // all out-edges have been explored EdgeColors[se] = GraphColor.Black; OnFinishEdge(se); }
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); }
/// <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(); }
/// <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); } } } }
protected override void InternalCompute() { // // Separate the two sides // HashSet <TVertex> side1, side2; SeparateSides(VisitedGraph, root, out side1, out side2); #region Build the temporary graph for the two sides // // The IN side // //on the IN side we should reverse the edges var graph1 = new BidirectionalGraph <TVertex, Edge <TVertex> >(); graph1.AddVertexRange(side1); foreach (var v in side1) { vertexInfos[v] = DoubleTreeVertexType.Backward; foreach (var e in VisitedGraph.InEdges(v)) { if (!side1.Contains(e.Source) || e.Source.Equals(e.Target)) { continue; } //reverse the edge graph1.AddEdge(new Edge <TVertex>(e.Target, e.Source)); } } // // The OUT side // var graph2 = new BidirectionalGraph <TVertex, TEdge>(); graph2.AddVertexRange(side2); foreach (var v in side2) { vertexInfos[v] = DoubleTreeVertexType.Forward; foreach (var e in VisitedGraph.OutEdges(v)) { if (!side2.Contains(e.Target) || e.Source.Equals(e.Target)) { continue; } //simply add the edge graph2.AddEdge(e); } } vertexInfos[root] = DoubleTreeVertexType.Center; #endregion LayoutDirection side2Direction = Parameters.Direction; LayoutDirection side1Direction = Parameters.Direction; switch (side2Direction) { case LayoutDirection.BottomToTop: side1Direction = LayoutDirection.TopToBottom; break; case LayoutDirection.LeftToRight: side1Direction = LayoutDirection.RightToLeft; break; case LayoutDirection.RightToLeft: side1Direction = LayoutDirection.LeftToRight; break; case LayoutDirection.TopToBottom: side1Direction = LayoutDirection.BottomToTop; break; } // // SimpleTree layout on the two side // var side1LayoutAlg = new SimpleTreeLayoutAlgorithm <TVertex, Edge <TVertex>, BidirectionalGraph <TVertex, Edge <TVertex> > >( graph1, VertexPositions, vertexSizes, new SimpleTreeLayoutParameters { LayerGap = Parameters.LayerGap, VertexGap = Parameters.VertexGap, Direction = side1Direction, SpanningTreeGeneration = SpanningTreeGeneration.BFS }); var side2LayoutAlg = new SimpleTreeLayoutAlgorithm <TVertex, TEdge, BidirectionalGraph <TVertex, TEdge> >( graph2, VertexPositions, vertexSizes, new SimpleTreeLayoutParameters { LayerGap = Parameters.LayerGap, VertexGap = Parameters.VertexGap, Direction = side2Direction, SpanningTreeGeneration = SpanningTreeGeneration.BFS }); side1LayoutAlg.Compute(); side2LayoutAlg.Compute(); // // Merge the layouts // var side2Translate = side1LayoutAlg.VertexPositions[root] - side2LayoutAlg.VertexPositions[root]; foreach (var v in side1) { VertexPositions[v] = side1LayoutAlg.VertexPositions[v]; } foreach (var v in side2) { VertexPositions[v] = side2LayoutAlg.VertexPositions[v] + side2Translate; } NormalizePositions(); }