protected override void DoRun() { bool?nullable = new bool?(); Dictionary <ushort, Factor> dictionary = new Dictionary <ushort, Factor>(); Graph.EdgeEnumerator edgeEnumerator = this._source.GetEdgeEnumerator(); for (uint vertex = 0; vertex < this._source.VertexCount; ++vertex) { edgeEnumerator.MoveTo(vertex); edgeEnumerator.Reset(); while (edgeEnumerator.MoveNext()) { float distance; ushort profile; EdgeDataSerializer.Deserialize(edgeEnumerator.Data0, out distance, out profile); Factor factor = Factor.NoFactor; if (!dictionary.TryGetValue(profile, out factor)) { factor = this._getFactor(profile); dictionary[profile] = factor; } if ((double)factor.Value != 0.0) { bool?direction = new bool?(); if ((int)factor.Direction == 1) { direction = new bool?(true); if (edgeEnumerator.DataInverted) { direction = new bool?(false); } } else if ((int)factor.Direction == 2) { direction = new bool?(false); if (edgeEnumerator.DataInverted) { direction = new bool?(true); } } uint data = ContractedEdgeDataSerializer.Serialize(distance * factor.Value, direction); int num = (int)this._target.AddEdge(edgeEnumerator.From, edgeEnumerator.To, data, 4294967294U); } } } this.HasSucceeded = true; }
/// <summary> /// Executes one step in the search. /// </summary> public bool Step() { // while the visit list is not empty. _current = null; if (_heap.Count > 0) { // choose the next vertex. _current = _heap.Pop(); while (_current != null && _visits.ContainsKey(_current.Vertex)) { // keep dequeuing. if (_heap.Count == 0) { // nothing more to pop. break; } if (this.Visit != null && this.Visit(_current)) { // edge was found and true was returned, this search should stop. return(false); } _current = _heap.Pop(); } } if (_current != null && !_visits.ContainsKey(_current.Vertex)) { // we visit this one, set visit. _visits[_current.Vertex] = _current; } else { // route is not found, there are no vertices left // or the search went outside of the max bounds. return(false); } if (this.WasFound != null && this.WasFound(_current.Vertex, _current.Weight)) { // vertex was found and true was returned, this search should stop. return(false); } // check for restrictions. var restriction = Constants.NO_VERTEX; if (_getRestriction != null) { restriction = _getRestriction(_current.Vertex); } if (restriction != Constants.NO_VERTEX) { // this vertex is restricted, step is a success but just move // to the next one because this vertex's neighbours are not allowed. return(true); } if (this.Visit != null && this.Visit(_current)) { // edge was found and true was returned, this search should stop. return(false); } // get neighbours and queue them. _edgeEnumerator.MoveTo(_current.Vertex); while (_edgeEnumerator.MoveNext()) { var edge = _edgeEnumerator; var neighbour = edge.To; if (_current.From != null && _current.From.Vertex == neighbour) { // don't go back continue; } if (this.Visit == null) { if (_visits.ContainsKey(neighbour)) { // has already been choosen continue; } } // get the speed from cache or calculate. float distance; ushort edgeProfile; EdgeDataSerializer.Deserialize(edge.Data0, out distance, out edgeProfile); var factor = Factor.NoFactor; var totalWeight = _weightHandler.Add(_current.Weight, edgeProfile, distance, out factor); // check the tags against the interpreter. if (factor.Value > 0 && (factor.Direction == 0 || (!_backward && (factor.Direction == 1) != edge.DataInverted) || (_backward && (factor.Direction == 1) == edge.DataInverted))) { // it's ok; the edge can be traversed by the given vehicle. // calculate neighbors weight. var edgeWeight = (distance * factor.Value); if (_weightHandler.IsSmallerThan(totalWeight, _sourceMax)) { // update the visit list. _heap.Push(new EdgePath <T>(neighbour, totalWeight, edge.IdDirected(), _current), _weightHandler.GetMetric(totalWeight)); } else { // the maxium was reached. this.MaxReached = true; } } } return(true); }
/// <summary> /// Moves to the next edge. /// </summary> /// <returns></returns> public bool MoveNext() { return(_enumerator.MoveNext()); }
/// <summary> /// Executes one step in the search. /// </summary> public bool Step() { // while the visit list is not empty. var cPointer = uint.MaxValue; while (cPointer == uint.MaxValue) { // choose the next edge. if (_pointerHeap.Count == 0) { return(false); } cPointer = _pointerHeap.Pop(); } // get details. uint cEdge, cPreviousPointer; T cWeight; _weightHandler.GetPathTree(_pathTree, cPointer, out cEdge, out cWeight, out cPreviousPointer); if (_visits.Contains(cEdge)) { return(true); } _visits.Add(cEdge); var cDirectedEdge = new DirectedEdgeId() { Raw = cEdge }; // signal was found. if (this.WasFound != null) { this.WasFound(cPointer, cDirectedEdge, cWeight); } // move to the current edge's target vertex. _edgeEnumerator.MoveToEdge(cDirectedEdge.EdgeId); var cOriginalEdge = new OriginalEdge(_edgeEnumerator.From, _edgeEnumerator.To); if (!cDirectedEdge.Forward) { cOriginalEdge = cOriginalEdge.Reverse(); } var cEdgeWeightAndDirection = _weightHandler.GetEdgeWeight(_edgeEnumerator); // calculate total weight. var totalWeight = _weightHandler.Add(cEdgeWeightAndDirection.Weight, cWeight); if (!_weightHandler.IsSmallerThan(totalWeight, _sourceMax)) { // weight is too big. this.MaxReached = true; return(true); } // loop over all neighbours. _edgeEnumerator.MoveTo(cOriginalEdge.Vertex2); var turn = new Turn(cOriginalEdge, Constants.NO_VERTEX); _restrictions.Update(turn.Vertex2); while (_edgeEnumerator.MoveNext()) { turn.Vertex3 = _edgeEnumerator.To; if (turn.IsUTurn || turn.IsRestrictedBy(_restrictions)) { // turn is restricted. continue; } var nDirectedEdgeId = _edgeEnumerator.DirectedEdgeId(); if (_visits.Contains(nDirectedEdgeId.Raw)) { // has already been choosen. continue; } // get the speed from cache or calculate. var nWeightAndDirection = _weightHandler.GetEdgeWeight(_edgeEnumerator); var nWeightMetric = _weightHandler.GetMetric(nWeightAndDirection.Weight); if (nWeightMetric <= 0) { // edge is not valid for profile. continue; } if (!_backward && !nWeightAndDirection.Direction.F) { // cannot do forward search on edge. continue; } if (_backward && !nWeightAndDirection.Direction.B) { // cannot do backward on edge. continue; } // update the visit list. _pointerHeap.Push(_weightHandler.AddPathTree(_pathTree, nDirectedEdgeId.Raw, totalWeight, cPointer), _weightHandler.GetMetric(totalWeight)); } return(true); }