/// <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; }
/// <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); }
/// <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; } } }
/// <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)); }
/// <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); }
/// <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)); }
/// <summary> /// Gets the weight from a meta-edge. /// </summary> public abstract T GetEdgeWeight(DirectedDynamicGraph.EdgeEnumerator edge, out bool?direction);
/// <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)); } } } } }
public override float GetEdgeWeight(DirectedDynamicGraph.EdgeEnumerator edge, out bool?direction) { throw new NotImplementedException(); }