Exemplo n.º 1
0
        /// <summary>
        /// FindPathForward, finds the fastes route between a and b
        /// </summary>
        /// <param name="a">stop number of the departuring station</param>
        /// <param name="b">stop number of the arrival station</param>
        /// <param name="utcStart">Departuretime in UTC format.</param>
        /// <returns>List of TimeTableId, describing the route for the path</returns>
        private List <PathItem> FindPathForward(int a, int b, long utcStart)
        {
            // the path we find as shortest
            var cameFrom = new Dictionary <int, TraceBackNode>();

            // gScore is the actual linuxtime to arrive at a stop: <stopId, arrival time>
            var gScore = new Dictionary <int, long>();

            gScore[a] = utcStart;

            // a min heap
            var heap = new FastPriorityQueue <QueueNode>(5000);

            heap.Enqueue(new QueueNode {
                StopId = a, Time = utcStart, TripId = -1
            }, DistanceTime(a, b));

            while (heap.Count != 0)
            {
                var currentNode = heap.Dequeue();
                // is arrival station found?
                if (currentNode.StopId == b)
                {
                    var path = ReconstructPath(cameFrom, currentNode.StopId);
                    path.Reverse();
                    return(path);
                }

                // get the neighbours to the currentNode
                var neighbours = ts.Edges
                                 .Where(e => e.FromStop == currentNode.StopId)
                                 .Select(e => new { e.EdgeId, e.ToStop, e.DistanceWalk });
                foreach (var n in neighbours)
                {
                    Iterations += 1;
                    long arrivalTime;  // time when arriving to n.ToStop
                    int  timeTableId = -1;
                    int  tripId      = -1;
                    if (n.DistanceWalk > 0)
                    {
                        if ((TimeToWalkSeconds(n.DistanceWalk) > cachedGlobal.MaxWalkingtime) | (currentNode.TripId == -1))
                        {
                            continue;  // to long to walk, or 2 sections in a row is walking!
                        }
                        arrivalTime = gScore[currentNode.StopId] + TimeToWalkSeconds(n.DistanceWalk);
                    }

                    else
                    {
                        long      gScoreTemp = gScore[currentNode.StopId]; // TryGetValueOrMax (currentNode.StopId)??
                        TimeTable timeTableEntry;
                        timeTableEntry = GetNextDeparture(n.EdgeId, gScoreTemp);

                        if (timeTableEntry == null) // no path found
                        {
                            continue;
                        }

                        // now chek if previous node is not walking, and change of transport and changetime is available
                        // othwise add changeTime, and search again.
                        if ((currentNode.TripId != -1)
                            & (currentNode.TripId != timeTableEntry.TripId)
                            & (timeTableEntry.DepartureTime < gScoreTemp + cachedGlobal.TimeToChangeTransport))
                        {
                            gScoreTemp    += cachedGlobal.TimeToChangeTransport;
                            timeTableEntry = GetNextDeparture(n.EdgeId, gScoreTemp);

                            if (timeTableEntry == null)  // no path found
                            {
                                continue;
                            }
                        }

                        arrivalTime = timeTableEntry.ArrivalTime;
                        timeTableId = timeTableEntry.TimeTableId;
                        tripId      = timeTableEntry.TripId;
                    }
                    if (arrivalTime < gScore.TryGetValueOrMax(n.ToStop))  // quicker way found
                    {
                        cameFrom[n.ToStop] = new TraceBackNode {
                            ToStop = currentNode.StopId, EdgeId = n.EdgeId, TimeTableId = timeTableId
                        };
                        gScore[n.ToStop] = arrivalTime;
                        QueueNode qn = new QueueNode {
                            StopId = n.ToStop, Time = arrivalTime, TripId = tripId
                        };
                        if (!heap.Contains(qn))
                        {
                            int heuristik = DistanceTime(n.ToStop, b);  // estimated traveltime from this node to the end
                            heap.Enqueue(qn, heuristik + arrivalTime);
                        }
                    }
                }
            }

            return(null);


            // Local: Get the next timetable entry in respect to departuetime given
            TimeTable GetNextDeparture(int edgeId, long departureTime)
            {
                return(ts.TimeTables
                       .Where(t => t.EdgeId == edgeId && (t.DepartureTime >= departureTime))
                       .OrderBy(t => t.DepartureTime)
                       .FirstOrDefault());
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// FindPathReverse, finds the fastes route between a and b
        /// </summary>
        /// <param name="a">stop number of the departuring station</param>
        /// <param name="b">stop number of the arrival station</param>
        /// <param name="finalArrivalTime">ArrivalTime in UTC format.</param>
        /// <returns>List of TimeTableId, describing the route for the path</returns>
        private List <PathItem> FindPathReverse(int a, int b, long finalArrivalTime)
        {
            // the path we find as shortest
            var cameFrom = new Dictionary <int, TraceBackNode>();

            // gScore is the actual UTCtime to get to a stop
            var gScore = new Dictionary <int, long>();

            gScore[b] = finalArrivalTime;

            // a min heap, now 'turned' into a max heap
            var heap = new FastPriorityQueue <QueueNode>(5000);

            heap.Enqueue(new QueueNode {
                StopId = b, Time = finalArrivalTime, TripId = -1
            }, -DistanceTime(a, b));

            while (heap.Count != 0)
            {
                var currentNode = heap.Dequeue();
                // is arrival station found?
                if (currentNode.StopId == a)
                {
                    return(ReconstructPath(cameFrom, currentNode.StopId));
                }

                // get the neighbours to the currentNode
                var neighbours = ts.Edges
                                 .Where(e => e.ToStop == currentNode.StopId)
                                 .Select(e => new { e.EdgeId, e.FromStop, e.DistanceWalk });

                foreach (var n in neighbours)
                {
                    Iterations += 1;
                    long departureTime;  // utctime when departing from n.ToStop
                    int  timeTableId = -1;
                    int  tripId      = -1;
                    if (n.DistanceWalk > 0)
                    {
                        if ((TimeToWalkSeconds(n.DistanceWalk) > cachedGlobal.MaxWalkingtime) & (currentNode.TripId == -1))
                        {
                            continue; // to long to walk, or 2 sections in a row is walking!
                        }
                        departureTime = gScore[currentNode.StopId] - TimeToWalkSeconds(n.DistanceWalk);
                    }
                    else
                    {
                        long      gScoreTemp = gScore[currentNode.StopId];
                        TimeTable timeTableEntry;
                        timeTableEntry = GetNextArrival(n.EdgeId, gScoreTemp);
                        if (timeTableEntry == null)
                        {
                            continue;
                        }

                        // now chek if previous node is not walking, and change of transport and changetime is available
                        // othwise add changeTime, and search again.
                        if ((currentNode.TripId != -1)
                            & (currentNode.TripId != timeTableEntry.TripId)
                            & (timeTableEntry.ArrivalTime < gScoreTemp - cachedGlobal.TimeToChangeTransport))
                        {
                            gScoreTemp    -= cachedGlobal.TimeToChangeTransport;
                            timeTableEntry = GetNextArrival(n.EdgeId, gScoreTemp);

                            if (timeTableEntry == null)  // no path found
                            {
                                continue;
                            }
                        }

                        departureTime = timeTableEntry.DepartureTime;
                        timeTableId   = timeTableEntry.TimeTableId;
                        tripId        = timeTableEntry.TripId;
                    }

                    if (departureTime > gScore.TryGetValueOrMin(n.FromStop))  // quicker way found, with a smaller value
                    {
                        cameFrom[n.FromStop] = new TraceBackNode {
                            ToStop = currentNode.StopId, EdgeId = n.EdgeId, TimeTableId = timeTableId
                        };
                        gScore[n.FromStop] = departureTime;
                        QueueNode qn = new QueueNode {
                            StopId = n.FromStop, Time = departureTime, TripId = tripId
                        };
                        if (!heap.Contains(qn))
                        {
                            int heuristik = DistanceTime(n.FromStop, a);  // estimated traveltime from this node to the start
                            heap.Enqueue(qn, heuristik - departureTime);
                        }
                    }
                }
            }
            // no path found!
            return(null);

            // Local: Get the next timeTable entry in respect to arrival time given
            TimeTable GetNextArrival(int edgeId, long arrivalTime)
            {
                return(ts.TimeTables
                       .Where(t => t.EdgeId == edgeId && (t.ArrivalTime <= arrivalTime))
                       .OrderByDescending(t => t.ArrivalTime)
                       .FirstOrDefault());
            }
        }