Exemple #1
0
 /// <summary>
 /// Creates a new edge keeping the current state of the given enumerator.
 /// </summary>
 internal DynamicEdge(DirectedDynamicGraph.EdgeEnumerator enumerator)
 {
     this.Neighbour   = enumerator.Neighbour;
     this.Data        = enumerator.Data;
     this.DynamicData = enumerator.DynamicData;
     this.Id          = enumerator.Id;
 }
Exemple #2
0
        /// <summary>
        /// Gets the weight from the given edge and sets the direction.
        /// </summary>
        public sealed override float GetEdgeWeight(DirectedDynamicGraph.EdgeEnumerator edge, out bool?direction)
        {
            float weight;

            Data.Contracted.Edges.ContractedEdgeDataSerializer.Deserialize(edge.Data0,
                                                                           out weight, out direction);
            return(weight);
        }
Exemple #3
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);
            }

            return(path.GetSequence2 <T>(enumerator, n, new List <uint>()));
        }
        /// <summary>
        /// Gets sequence 1, the first vertices right after the start vertex with a maximum of n.
        /// </summary>
        public static uint[] GetSequence1 <T>(this EdgePath <T> path, DirectedDynamicGraph.EdgeEnumerator enumerator, int n)
            where T : struct
        {
            if (path.From == null)
            {
                return(Constants.EMPTY_SEQUENCE);
            }

            var s = new List <uint>();

            s.Add(path.Vertex);
            while (true)
            {
                if (path.IsOriginal(enumerator))
                { // current segment is original.
                    if (s == null)
                    {
                        s = new List <uint>();
                    }
                    if (path.From.From != null)
                    { // we need more vertices and there are some more available.
                        s.Add(path.From.Vertex);
                        path = path.From;
                    }
                    else
                    { // we have enough.
                        var result = s.ToArray();
                        if (n < result.Length)
                        { // TODO: this can be way more efficient by creating only one array.
                            result = result.SubArray(result.Length - n, n);
                        }
                        result.Reverse();
                        return(result);
                    }
                }
                else
                { // not an original edge, just return the start sequence.
                    var sequence = enumerator.GetSequence1();
                    if (path.From.From == null)
                    {
                        if (sequence.Length > n)
                        {
                            sequence = sequence.SubArray(sequence.Length - n, n);
                        }
                        return(sequence);
                    }
                    s.Clear();
                    sequence.Reverse();
                    s.AddRange(sequence);
                    s.Add(path.From.Vertex);
                    path = path.From;
                }
            }
        }
Exemple #5
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 all edges in the given edge path.
        /// </summary>
        public static EdgePath <T> Expand <T>(this EdgePath <T> edgePath, DirectedDynamicGraph.EdgeEnumerator enumerator, WeightHandler <T> weightHandler)
            where T : struct
        {
            if (edgePath.From == null)
            {
                return(edgePath);
            }

            // expand everything before.
            edgePath = new EdgePath <T>(edgePath.Vertex, edgePath.Weight, edgePath.Edge, edgePath.From.Expand(enumerator, weightHandler));

            // expand list.
            return(edgePath.ExpandLast(enumerator, weightHandler));
        }
Exemple #7
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());
                }
            }
        }
 /// <summary>
 /// Returns true if the last edge in this path is an original edge.
 /// </summary>
 public static bool IsOriginal <T>(this EdgePath <T> path, DirectedDynamicGraph.EdgeEnumerator enumerator)
     where T : struct
 {
     if (path.From == null)
     { // when there is no previous vertex this is not an edge.
         throw new ArgumentException("The path is not an edge, cannot decide about originality.");
     }
     if (path.Edge == Constants.NO_EDGE)
     { // when there is no edge info, edge has to be original otherwise the info can never be recovered.
         return(true);
     }
     enumerator.MoveToEdge(path.Edge);
     if (enumerator.IsOriginal())
     { // ok, edge is original.
         return(true);
     }
     return(false);
 }
Exemple #9
0
        /// <summary>
        /// Initializes and resets.
        /// </summary>
        public void Initialize()
        {
            // algorithm always succeeds, it may be dealing with an empty network and there are no targets.
            this.HasSucceeded = true;

            // intialize dykstra data structures.
            _visits = new Dictionary <uint, LinkedEdgePath <T> >();
            _heap   = new BinaryHeap <EdgePath <T> >();

            // queue all sources.
            foreach (var source in _sources)
            {
                _heap.Push(source, _weightHandler.GetMetric(source.Weight));
            }

            // gets the edge enumerator.
            _edgeEnumerator = _graph.GetEdgeEnumerator();
        }
        /// <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);
        }
 /// <summary>
 /// Gets sequence 2, the last vertices right before the end vertex.
 /// </summary>
 public static uint[] GetSequence2 <T>(this EdgePath <T> path, DirectedDynamicGraph.EdgeEnumerator enumerator)
     where T : struct
 {
     return(path.GetSequence2(enumerator, int.MaxValue));
 }
Exemple #12
0
 /// <summary>
 /// Gets the weight from a meta-edge.
 /// </summary>
 public abstract T GetEdgeWeight(DirectedDynamicGraph.EdgeEnumerator edge, out bool?direction);
Exemple #13
0
        /// <summary>
        /// Search backward from one vertex.
        /// </summary>
        /// <returns></returns>
        private void SearchBackward(DirectedDynamicGraph.EdgeEnumerator edgeEnumerator, EdgePath <T> current, IEnumerable <uint[]> restrictions)
        {
            if (current != null)
            { // there is a next vertex found.
                // get the edge enumerator.
                var currentSequence = current.GetSequence2(edgeEnumerator);
                currentSequence = currentSequence.Append(current.Vertex);

                // get neighbours.
                edgeEnumerator.MoveTo(current.Vertex);

                // add the neighbours to the queue.
                while (edgeEnumerator.MoveNext())
                {
                    bool?neighbourDirection;
                    var  neighbourWeight = _weightHandler.GetEdgeWeight(edgeEnumerator.Current, out neighbourDirection);

                    if (neighbourDirection == null || !neighbourDirection.Value)
                    { // the edge is forward, and is to higher or was not contracted at all.
                        var neighbourNeighbour = edgeEnumerator.Neighbour;
                        var neighbourSequence  = Constants.EMPTY_SEQUENCE;
                        if (edgeEnumerator.IsOriginal())
                        {     // original edge.
                            if (currentSequence.Length > 1 && currentSequence[currentSequence.Length - 2] == neighbourNeighbour)
                            { // this is a u-turn.
                                continue;
                            }
                            if (restrictions != null)
                            {
                                neighbourSequence = currentSequence.Append(neighbourNeighbour);
                            }
                        }
                        else
                        { // not an original edge, use the sequence.
                            neighbourSequence = edgeEnumerator.GetSequence1();
                            if (currentSequence.Length > 1 && currentSequence[currentSequence.Length - 2] == neighbourSequence[0])
                            { // this is a u-turn.
                                continue;
                            }
                            if (restrictions != null)
                            {
                                neighbourSequence = currentSequence.Append(neighbourSequence);
                            }
                        }

                        if (restrictions != null)
                        { // check restrictions.
                            neighbourSequence.Reverse();
                            if (!restrictions.IsSequenceAllowed(neighbourSequence))
                            {
                                continue;
                            }
                        }

                        // build route to neighbour and check if it has been visited already.
                        var routeToNeighbour = new EdgePath <T>(
                            neighbourNeighbour, _weightHandler.Add(current.Weight, neighbourWeight), edgeEnumerator.IdDirected(), current);
                        LinkedEdgePath edgePath = null;
                        if (!_backwardVisits.TryGetValue(current.Vertex, out edgePath) ||
                            !edgePath.HasPath(routeToNeighbour))
                        { // this vertex has not been visited in this way before.
                            _backwardQueue.Push(routeToNeighbour, _weightHandler.GetMetric(routeToNeighbour.Weight));
                        }
                    }
                }
            }
        }
Exemple #14
0
 public override float GetEdgeWeight(DirectedDynamicGraph.EdgeEnumerator edge, out bool?direction)
 {
     throw new NotImplementedException();
 }