Exemple #1
0
        /// <summary>
        /// Gets sequence 2, the last vertices right before the end vertex with a maximum of n.
        /// </summary>
        public static uint[] GetSequence2 <T>(this EdgePath <T> path, DirectedDynamicGraph.EdgeEnumerator enumerator, int n)
            where T : struct
        {
            if (path.From == null)
            {
                return(Constants.EMPTY_SEQUENCE);
            }

            List <uint> s = null;

            while (true)
            {
                if (path.IsOriginal(enumerator))
                { // current segment is original.
                    if (s == null)
                    {
                        s = new List <uint>();
                    }
                    s.Add(path.From.Vertex);
                    if (s.Count < n && path.From.From != null)
                    { // we need more vertices and there are some more available.
                        path = path.From;
                    }
                    else
                    { // we have enough.
                        var result = s.ToArray();
                        result.Reverse();
                        return(result);
                    }
                }
                else
                { // not an original edge, just return the start sequence.
                    if (s != null)
                    {
                        var s2     = enumerator.GetSequence2();
                        var result = new uint[s.Count + s2.Length];
                        for (var i = 0; i < s.Count; i++)
                        {
                            result[result.Length - 1 - i] = s[i];
                        }
                        for (var i = 0; i < s2.Length; i++)
                        {
                            result[i] = s2[i];
                        }
                        return(result);
                    }
                    return(enumerator.GetSequence2());
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Expands the last edge in the given edge path.
        /// </summary>
        private static EdgePath <T> ExpandLast <T>(this EdgePath <T> edgePath, DirectedDynamicGraph.EdgeEnumerator enumerator, WeightHandler <T> weightHandler, bool direction)
            where T : struct
        {
            if (edgePath.Edge != Constants.NO_EDGE &&
                edgePath.From != null &&
                edgePath.From.Vertex != Constants.NO_VERTEX)
            {
                enumerator.MoveToEdge(edgePath.Edge);
                var contractedId = enumerator.GetContracted();
                if (contractedId.HasValue)
                { // there is a contracted vertex here!
                    // get source/target sequences.
                    var sequence1 = enumerator.GetSequence1();
                    sequence1.Reverse();
                    var sequence2 = enumerator.GetSequence2();

                    if (enumerator.Neighbour != edgePath.Vertex)
                    {
                        sequence1.Reverse();
                        sequence2.Reverse();

                        var t = sequence2;
                        sequence2 = sequence1;
                        sequence1 = t;
                    }

                    // move to the first edge (contracted -> from vertex) and keep details.
                    bool?localDirection;
                    if (!enumerator.MoveToEdge(contractedId.Value, edgePath.From.Vertex, sequence1, weightHandler, !direction))
                    {
                        throw new Exception(string.Format("Edge between {0} -> {1} with sequence {2} could not be found.",
                                                          contractedId.Value, edgePath.From.Vertex, sequence1.ToStringSafe()));
                    }
                    var edge1   = enumerator.IdDirected();
                    var weight1 = weightHandler.GetEdgeWeight(enumerator.Current, out localDirection);

                    // move to the second edge (contracted -> to vertex) and keep details.
                    if (!enumerator.MoveToEdge(contractedId.Value, edgePath.Vertex, sequence2, weightHandler, direction))
                    {
                        throw new Exception(string.Format("Edge between {0} -> {1} with sequence {2} could not be found.",
                                                          contractedId.Value, edgePath.Vertex, sequence2.ToStringSafe()));
                    }
                    var weight2 = weightHandler.GetEdgeWeight(enumerator.Current, out localDirection);
                    var edge2   = enumerator.IdDirected();

                    var contractedPath = new EdgePath <T>(contractedId.Value, weightHandler.Add(edgePath.From.Weight, weight1), edge1, edgePath.From);
                    contractedPath = contractedPath.ExpandLast(enumerator, weightHandler, direction);
                    return((new EdgePath <T>(edgePath.Vertex, edgePath.Weight, edge2, contractedPath)).ExpandLast(enumerator, weightHandler, direction));
                }
            }
            return(edgePath);
        }
        /// <summary>
        /// Expands the last edge in the given edge path.
        /// </summary>
        private static EdgePath <T> ExpandLast <T>(this EdgePath <T> edgePath, DirectedDynamicGraph.EdgeEnumerator enumerator, WeightHandler <T> weightHandler)
            where T : struct
        {
            bool?direction;

            if (edgePath.Edge != Constants.NO_EDGE &&
                edgePath.From != null &&
                edgePath.From.Vertex != Constants.NO_VERTEX)
            {
                enumerator.MoveToEdge(edgePath.Edge);
                var contractedId = enumerator.GetContracted();
                if (contractedId.HasValue)
                { // there is a contracted vertex here!
                    // get source/target sequences.
                    var sequence1 = enumerator.GetSequence1();
                    sequence1.Reverse();
                    var sequence2 = enumerator.GetSequence2();

                    // move to the first edge (contracted -> from vertex) and keep details.
                    enumerator.MoveToEdge(contractedId.Value, edgePath.From.Vertex, sequence1);
                    var edge1   = enumerator.IdDirected();
                    var weight1 = weightHandler.GetEdgeWeight(enumerator.Current, out direction);

                    // move to the second edge (contracted -> to vertex) and keep details.
                    enumerator.MoveToEdge(contractedId.Value, edgePath.Vertex, sequence2);
                    var weight2 = weightHandler.GetEdgeWeight(enumerator.Current, out direction);
                    var edge2   = enumerator.IdDirected();

                    if (edgePath.Edge > 0)
                    {
                        var contractedPath = new EdgePath <T>(contractedId.Value, weightHandler.Add(edgePath.From.Weight, weight1), -edge1, edgePath.From);
                        contractedPath = contractedPath.ExpandLast(enumerator, weightHandler);
                        return((new EdgePath <T>(edgePath.Vertex, edgePath.Weight, edge2, contractedPath)).ExpandLast(enumerator, weightHandler));
                    }
                    else
                    {
                        var contractedPath = new EdgePath <T>(contractedId.Value, weightHandler.Add(edgePath.From.Weight, weight1), edge1, edgePath.From);
                        contractedPath = contractedPath.ExpandLast(enumerator, weightHandler);
                        return((new EdgePath <T>(edgePath.Vertex, edgePath.Weight, -edge2, contractedPath)).ExpandLast(enumerator, weightHandler));
                    }
                }
            }
            return(edgePath);
        }