示例#1
0
        /// <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));
        }
示例#4
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);
                }
            }
        }
示例#5
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;
            }
        }
示例#6
0
        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;
            }
        }
示例#7
0
        /// <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);
        }
示例#11
0
 private IEdgeEnumerable SelectOutEdgesNotInCircuit(IVertex v)
 {
     return(new FilteredEdgeEnumerable(
                VisitedGraph.OutEdges(v),
                new NotInCircuitEdgePredicate(Circuit, TemporaryCircuit)
                ));
 }
示例#12
0
        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;
            }
        }
示例#14
0
 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);
            }
        }
示例#16
0
        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);
                }
            }
        }
示例#19
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);
        }
示例#20
0
        /// <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);
                }
            }
        }
示例#28
0
        /// <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);
                }
            }
        }
示例#29
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);
        }
示例#30
0
        /// <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);
                    }
                }
            }
        }
示例#32
0
        /// <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));
        }
示例#33
0
        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;
        }
示例#34
0
        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;
        }