Example #1
0
 /// <summary>
 /// Creates a new instance of search algorithm.
 /// </summary>
 public BidirectionalDykstra(Dykstra <T> sourceSearch, Dykstra <T> targetSearch, WeightHandler <T> weightHandler)
 {
     _sourceSearch  = sourceSearch;
     _targetSearch  = targetSearch;
     _weightHandler = weightHandler;
 }
Example #2
0
        /// <summary>
        /// Executes the actual run of the algorithm.
        /// </summary>
        protected override void DoRun(CancellationToken cancellationToken)
        {
            _best = new EdgePath <T> [_targets.Count];

            // register the targets and determine one-edge-paths.
            var sourcePaths            = _source.ToEdgePaths(_routerDb, _weightHandler, true);
            var targetIndexesPerVertex = new Dictionary <uint, LinkedTarget>();
            var targetPaths            = new IEnumerable <EdgePath <T> > [_targets.Count];

            for (var i = 0; i < _targets.Count; i++)
            {
                var targets = _targets[i].ToEdgePaths(_routerDb, _weightHandler, false);
                targetPaths[i] = targets;

                // determine one-edge-paths.
                if (_source.EdgeId == _targets[i].EdgeId)
                { // on same edge.
                    _best[i] = _source.EdgePathTo(_routerDb, _weightHandler, _targets[i]);
                }

                // register targets.
                for (var t = 0; t < targets.Length; t++)
                {
                    var target = targetIndexesPerVertex.TryGetValueOrDefault(targets[t].Vertex);
                    targetIndexesPerVertex[targets[t].Vertex] = new LinkedTarget()
                    {
                        Target = i,
                        Next   = target
                    };
                }
            }

            // determine the best max search radius.
            var max = _weightHandler.Zero;

            for (var s = 0; s < _best.Length; s++)
            {
                if (_best[s] == null)
                {
                    max = _maxSearch;
                }
                else
                {
                    if (_weightHandler.IsLargerThan(_best[s].Weight, max))
                    {
                        max = _best[s].Weight;
                    }
                }
            }

            // run the search.
            var dykstra = new Dykstra <T>(_routerDb.Network.GeometricGraph.Graph, null, _weightHandler,
                                          sourcePaths, max, false);

            dykstra.WasFound += (vertex, weight) =>
            {
                LinkedTarget target;
                if (targetIndexesPerVertex.TryGetValue(vertex, out target))
                { // there is a target for this vertex.
                    while (target != null)
                    {
                        var best = _best[target.Target];
                        foreach (var targetPath in targetPaths[target.Target])
                        {
                            EdgePath <T> path;
                            dykstra.TryGetVisit(vertex, out path);
                            if (targetPath.Vertex == vertex)
                            { // there is a path here.
                                var total = _weightHandler.Add(targetPath.Weight, weight);
                                if (best == null ||
                                    _weightHandler.IsSmallerThan(total, best.Weight))
                                {     // not a best path yet, just add this one.
                                    if (_targets[target.Target].IsVertex(_routerDb, path.Vertex))
                                    { // target is the exact vertex.
                                        best = path;
                                    }
                                    else
                                    { // target is not the exact vertex.
                                        best = new EdgePath <T>(_targets[target.Target].VertexId(_routerDb),
                                                                total, path);
                                    }
                                }
                                break;
                            }
                        }

                        // set again.
                        _best[target.Target] = best;

                        // move to next target.
                        target = target.Next;
                    }
                }
                return(false);
            };
            dykstra.Run(cancellationToken);

            this.HasSucceeded = true;
        }