/// <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; } }
/// <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(); }
/// <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.OutEdges(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 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); } }
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(); }
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); } }
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); }
//======================================================================= // 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); }
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 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 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); }
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); } }
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 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 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); }
/// <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; } }
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 IEdgeEnumerable SelectOutEdgesNotInCircuit(IVertex v) { return(new FilteredEdgeEnumerable( VisitedGraph.OutEdges(v), new NotInCircuitEdgePredicate(Circuit, TemporaryCircuit) )); }
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); }
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); } } }
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)); }
/// <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); } } }
/// <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); }
/// <summary> /// Compute the condensation graph and store it in the supplied graph 'cg' /// </summary> /// <param name="cg"> /// Instance of mutable graph in which the condensation graph /// transformation is stored /// </param> public void Create(IMutableVertexAndEdgeListGraph cg) { if (cg == null) { throw new ArgumentNullException("cg"); } if (components == null) { ComputeComponents(); } // components list contains collection of // input graph Vertex for each SCC Vertex_ID // (i.e Vector< Vector<Vertex> > ) // Key = SCC Vertex ID sccVertexMap = BuildSCCVertexMap(components); // Lsit of SCC vertices VertexCollection toCgVertices = new VertexCollection(); IDictionaryEnumerator it = sccVertexMap.GetEnumerator(); while (it.MoveNext()) // as scc_vertex_map is a sorted list, order of SCC IDs will match CG vertices { IVertex curr = cg.AddVertex(); OnInitCondensationGraphVertex(new CondensationGraphVertexEventArgs(curr, (IVertexCollection)it.Value)); toCgVertices.Add(curr); } for (int srcSccId = 0; srcSccId < sccVertexMap.Keys.Count; srcSccId++) { VertexCollection adj = new VertexCollection(); foreach (IVertex u in (IVertexCollection)sccVertexMap[srcSccId]) { foreach (IEdge e in VisitedGraph.OutEdges(u)) { IVertex v = e.Target; int targetSccId = components[v]; if (srcSccId != targetSccId) { // Avoid loops in the condensation graph IVertex sccV = toCgVertices[targetSccId]; if (!adj.Contains(sccV)) // Avoid parallel edges { adj.Add(sccV); } } } } IVertex s = toCgVertices[srcSccId]; foreach (IVertex t in adj) { cg.AddEdge(s, t); } } }
private bool HasEdgeToward([NotNull] TVertex u, [NotNull] TVertex v) { Debug.Assert(u != null); Debug.Assert(v != null); return(VisitedGraph .OutEdges(v) .Any(outEdge => EqualityComparer <TVertex> .Default.Equals(outEdge.Target, u))); }
private IEnumerable <TEdge> SelectOutEdgesNotInCircuit(TVertex v) { foreach (var edge in VisitedGraph.OutEdges(v)) { if (this.NotInCircuit(edge)) { yield return(edge); } } }
/// <summary> /// Does a depth first search on the vertex u /// </summary> /// <param name="u">vertex to explore</param> /// <exception cref="ArgumentNullException">u cannot be null</exception> public void Visit(IVertex u) { if (u == null) { throw new ArgumentNullException("u"); } IVertex v = null; Colors[u] = GraphColor.Gray; VertexEventArgs uArgs = new VertexEventArgs(u); if (this.DiscoverVertex != null) { DiscoverVertex(this, uArgs); } foreach (IEdge e in VisitedGraph.OutEdges(u)) { EdgeEventArgs eArgs = new EdgeEventArgs(e); if (this.ExamineEdge != null) { ExamineEdge(this, eArgs); } v = e.Target; if (Colors[v] == GraphColor.White) { if (this.TreeEdge != null) { TreeEdge(this, eArgs); } Visit(v); } else if (Colors[v] == GraphColor.Gray) { if (this.BackEdge != null) { BackEdge(this, eArgs); } } else { if (this.ForwardOrCrossEdge != null) { ForwardOrCrossEdge(this, eArgs); } } } Colors[u] = GraphColor.Black; if (this.FinishVertex != null) { FinishVertex(this, uArgs); } }
private bool IsFlow() { // check edge flow values foreach (IVertex u in VisitedGraph.Vertices) { foreach (IEdge a in VisitedGraph.OutEdges(u)) { if (Capacities[a] > 0) { if ((ResidualCapacities[a] + ResidualCapacities[ReversedEdges[a]] != Capacities[a] + Capacities[ReversedEdges[a]]) || (ResidualCapacities[a] < 0) || (ResidualCapacities[ReversedEdges[a]] < 0)) { return(false); } } } } // check conservation double sum; foreach (IVertex u in VisitedGraph.Vertices) { if (u != src && u != sink) { if (excessFlow[u] != 0) { return(false); } sum = 0; foreach (IEdge a in VisitedGraph.OutEdges(u)) { if (Capacities[a] > 0) { sum -= Capacities[a] - ResidualCapacities[a]; } else { sum += ResidualCapacities[a]; } } if (excessFlow[u] != sum) { return(false); } } } return(true); }
public void Visit(TVertex s) { if (this.IsAborting) { return; } this.VertexColors[s] = GraphColor.Gray; OnDiscoverVertex(s); this.vertexQueue.Push(s); while (this.vertexQueue.Count != 0) { if (this.IsAborting) { return; } TVertex u = this.vertexQueue.Pop(); OnExamineVertex(u); foreach (TEdge e in VisitedGraph.OutEdges(u)) { TVertex v = e.Target; OnExamineEdge(e); GraphColor vColor = VertexColors[v]; if (vColor == GraphColor.White) { OnTreeEdge(e); VertexColors[v] = GraphColor.Gray; OnDiscoverVertex(v); this.vertexQueue.Push(v); } else { OnNonTreeEdge(e); if (vColor == GraphColor.Gray) { OnGrayTarget(e); } else { OnBlackTarget(e); } } } VertexColors[u] = GraphColor.Black; OnFinishVertex(u); } }
//======================================================================= // This function is called "push" in Goldberg's h_prf implementation, // but it is called "discharge" in the paper and in hi_pr.c. private void Discharge(IVertex u) { while (true) { int ai; for (ai = current[u]; ai < VisitedGraph.OutDegree(u); ai++) { IEdge a = VisitedGraph.OutEdges(u)[ai]; if (IsResidualEdge(a)) { IVertex v = a.Target; if (IsAdmissible(u, v)) { if (v != sink && excessFlow[v] == 0) { RemoveFromInactiveList(v); AddToActiveList(v, layers[distances[v]]); } PushFlow(a); if (excessFlow[u] == 0) { break; } } } } PreflowLayer layer = layers[distances[u]]; int du = distances[u]; if (ai == VisitedGraph.OutDegree(u)) // i must be relabeled { RelabelDistance(u); if (layer.ActiveVertices.Count == 0 && layer.InactiveVertices.Count == 0) { Gap(du); } if (distances[u] == n) { break; } } else { // i is no longer active current[u] = ai; AddToInactiveList(u, layer); break; } } }