コード例 #1
0
        /// <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);
                }
            }
        }
コード例 #2
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();
        }
コード例 #3
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);
        }
コード例 #4
0
        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();
        }
コード例 #5
0
        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);
                }
            }
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        /// <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);
                }
            }
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        /// <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);
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        /// <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();
        }
コード例 #14
0
        /// <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);
                    }
                }
            }
        }
コード例 #15
0
        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();
        }