Esempio n. 1
0
        /// <summary>
        /// Creates a route segment statistics
        /// </summary>
        /// <param name="startTime"></param>
        /// <param name="startStop"></param>
        /// <param name="endStop"></param>
        /// <returns></returns>
        public RouteSegmentStatistics CreateRouteSegmentStatistics(TimeSpan startTime, RouteStop startStop, RouteStop endStop)
        {
            // determine if time arrived within time window and calculate wait time
            bool early = startTime < endStop.WindowStart;
            bool late  = startTime > endStop.WindowEnd;

            TimeSpan waitTime = TimeSpan.Zero;
            bool     whiffed  = false;

            if (early)
            {
                waitTime = endStop.WindowStart.Subtract(startTime);
                whiffed  = waitTime > _configuration.MaximumWaitTimeAtStop;
            }
            else if (late)
            {
                // we started past the time window
                whiffed = true;
            }

            var executionTime = _routeStopDelayService.GetDelay(endStop);

            // calculate the trip between the current and next stop
            var tripLength = CalculateTripLength(startStop, endStop);

            var routeStatistics = new RouteStatistics()
            {
                TotalExecutionTime  = executionTime,
                TotalWaitTime       = waitTime,
                TotalTravelTime     = tripLength.Time,
                TotalTravelDistance = tripLength.Distance,
            };

            var result = new RouteSegmentStatistics
            {
                StartStop         = startStop,
                EndStop           = endStop,
                StartTime         = startTime,
                Statistics        = routeStatistics,
                WhiffedTimeWindow = whiffed
            };

            return(result);
        }
Esempio n. 2
0
        public Drayage.Optimization.Model.Planning.Plan MapDomainToModelWithoutPlaceHolder(FRATIS.SFL.Domain.Planning.Plan plan)
        {
            var model = new Plan();

            model.InjectFrom <DomainToModelValueInjection>(plan);

            foreach (var driverPlan in plan.DriverPlans)
            {
                var modelDriverPlan = model.DriverPlans.FirstOrDefault(f => f.Id == driverPlan.Id);

                if (modelDriverPlan == null)
                {
                    continue;
                }

                var driver = driverPlan.Driver ?? _driverService.GetById(driverPlan.DriverId);

                var driverModel = new Drayage.Optimization.Model.Orders.Driver();
                driverModel.InjectFrom <DomainToModelValueInjection>(driver);

                modelDriverPlan.Driver = driverModel.InjectFrom(driver) as Drayage.Optimization.Model.Orders.Driver;

                modelDriverPlan.RouteSegmentStatistics = new List <RouteSegmentStatistics>();

                if (driverPlan.Driver.IsPlaceholderDriver)
                {
                    continue;
                }

                modelDriverPlan.JobPlans = modelDriverPlan.JobPlans.OrderBy(f => f.SortOrder).ToList();
                foreach (var jobPlan in driverPlan.JobPlans)
                {
                    //var driverPlanJob = _planService.GetPlanDriverJobsById(jobPlan.Id);

                    var modelJobPlan = modelDriverPlan.JobPlans.FirstOrDefault(f => f.Id == jobPlan.Id);
                    modelJobPlan.Job = modelJobPlan.Job ?? new Drayage.Optimization.Model.Orders.Job();

                    MapDomainToModel(jobPlan.Job, modelJobPlan.Job, plan.PlanConfig.DueDate);
                }
                if (driverPlan.RouteSegmentMetrics == null)
                {
                    driverPlan.RouteSegmentMetrics = new List <RouteSegmentMetric>();
                }

                foreach (var x in driverPlan.RouteSegmentMetrics)
                {
                    var rss        = new RouteSegmentStatistics();
                    var endStop    = ConvertRouteStop(x.EndStop);
                    var startStop  = ConvertRouteStop(x.StartStop);
                    var statistics = new RouteStatistics();
                    var startTime  = new TimeSpan(x.StartTime ?? 0);

                    statistics.TotalCapacity       = 0;
                    statistics.TotalExecutionTime  = new TimeSpan(x.TotalExecutionTime);
                    statistics.TotalIdleTime       = new TimeSpan(x.TotalIdleTime);
                    statistics.TotalQueueTime      = new TimeSpan(x.TotalQueueTime);
                    statistics.TotalTravelDistance = x.TotalTravelDistance;
                    statistics.TotalTravelTime     = new TimeSpan(x.TotalTravelTime);

                    rss.EndStop           = endStop;
                    rss.StartStop         = startStop;
                    rss.StartTime         = startTime;
                    rss.Statistics        = statistics;
                    rss.WhiffedTimeWindow = false;
                    modelDriverPlan.RouteSegmentStatistics.Add(rss);
                }
            }

            return(model);
        }
Esempio n. 3
0
        public JobNode CreateJobNode(Job job, TimeSpan?startTime = null, bool ignoreFirstStopExecutionTime = false)
        {
            var routeStops = FilterExtraniousFecMiamiTerminalStops(job.RouteStops.ToList()).ToList();

            job.RouteStops = routeStops;

            job.RouteSegmentStatisticses = new List <RouteSegmentStatistics>();

            _array = new double[11, routeStops.Count];

            if (job.RouteStops != null && job.RouteStops.Any())
            {
                SetTravelTimes(routeStops);
                SetTimeWindowValues(routeStops);
                SetServiceTimes(routeStops, startTime == null || ignoreFirstStopExecutionTime);
                SetSumValues(routeStops);
                SetResultTimeWindows(routeStops);

                SetDepartureTime(startTime, routeStops);
                //SetArrivalTime(routeStops);
                SetViolationsAndWait(routeStops);

                var result = new JobNode(job, _array)
                {
                    Priority = job.Priority > 0 && job.Priority < 4 ? job.Priority : 1
                };

                // TODO URGENT - use automapper to assure that future
                //  properties will be mapped automatically without needing to create a manual mapping

                try { result.Job.IsHazmat = job.IsHazmat; }
                catch (Exception e) { Console.WriteLine(e.ToString()); }

                try { result.WindowStart = TimeSpan.FromSeconds(_array[RowIndexResultTwl, 0]); }
                catch { result.WindowStart = TimeSpan.Zero; }

                try { result.WindowEnd = TimeSpan.FromSeconds(_array[RowIndexResultTwu, 0]); }
                catch { result.WindowEnd = _array[RowIndexResultTwu, 0] > 0 ? TimeSpan.MaxValue : result.WindowStart; }


                if (result.WindowEnd < result.WindowStart)
                {
                    result.WindowStart = result.WindowEnd;
                }

                if (DoesViolationExist(routeStops))
                {
                    result.IsInvalid = true;
                    //throw new Exception("Invalid Jobnode - violation detected");
                }

                for (var i = 1; i < routeStops.Count; i++)
                {
                    var distance = _distanceService.CalculateDistance(routeStops[i - 1].Location, routeStops[i].Location);
                    var rss      = new RouteSegmentStatistics()
                    {
                        StartStop         = routeStops[i - 1],
                        EndStop           = routeStops[i],
                        StartTime         = TimeSpan.FromSeconds(_array[RowIndexArrival, i]),
                        WhiffedTimeWindow = _array[RowIndexViolations, i] == 0,
                        Statistics        = new RouteStatistics
                        {
                            TotalExecutionTime  = TimeSpan.FromSeconds(_array[RowIndexServiceTime, i]),
                            TotalIdleTime       = TimeSpan.FromSeconds(_array[RowIndexWaitTime, i]),
                            TotalQueueTime      = TimeSpan.Zero,
                            TotalTravelTime     = distance.Time,
                            TotalTravelDistance = distance.Distance
                        }
                    };
                    job.RouteSegmentStatisticses.Add(rss);
                }

                return(result);
            }

            return(new JobNode(job)
            {
                IsInvalid = true
            });
        }
Esempio n. 4
0
        public RouteSegmentStatistics CreateRouteSegmentStatistics(TimeSpan startTime, RouteStop startStop, RouteStop endStop, bool setIdleTime = true, bool driverFirstStop = false)
        {
            if (startTime.Days > 0)
            {
                startTime = new TimeSpan(startTime.Hours, startTime.Minutes, startTime.Seconds);
            }
            if (startStop.WindowStart > endStop.WindowStart)
            {
                endStop.WindowStart = endStop.WindowStart.Add(TimeSpan.FromDays(1));
            }
            if (startStop.WindowEnd > endStop.WindowEnd)
            {
                endStop.WindowEnd = endStop.WindowEnd.Add(TimeSpan.FromDays(1));
            }



            // calculate the trip between the current and next stop
            var tripLength = CalculateTripLength(startStop, endStop);

            // determine if time arrived within time window and calculate wait time
            var adjustedStartTime = startTime.Ticks - tripLength.Time.Ticks;

            if (adjustedStartTime < startTime.Ticks)
            {
                adjustedStartTime = startTime.Ticks;
            }

            var earlyLateFlagTime = new TimeSpan((startTime + tripLength.Time).Hours, (startTime + tripLength.Time).Minutes, (startTime + tripLength.Time).Seconds);

            bool early = earlyLateFlagTime < endStop.WindowStart;
            bool late  = earlyLateFlagTime > endStop.WindowEnd;

            TimeSpan idleTime = TimeSpan.Zero;
            bool     whiffed  = false;

            if (early)
            {
                if (setIdleTime)
                {
                    idleTime = endStop.WindowStart.Subtract(startTime);
                }
                var idleTime2 = idleTime.Ticks - tripLength.Time.Ticks;
                if (idleTime2 > startTime.Ticks)
                {
                    // idletime 2 is the new adjusted start time
                    if (setIdleTime)
                    {
                        idleTime = new TimeSpan(idleTime2);
                    }
                }

                whiffed = idleTime > _configuration.MaximumIdleTimeAtStop;
                // subtract travel time if not driver start time
            }
            else if (late)
            {
                // we started past the time window
                whiffed = true;
            }

            bool isDriverFirstSegment = true;

            if (idleTime > tripLength.Time)
            {
                idleTime = idleTime - tripLength.Time;
            }

            var arrivalTimeAtEndStop = new TimeSpan((startTime + tripLength.Time).Hours, (startTime + tripLength.Time).Minutes, (startTime + tripLength.Time).Seconds);

            var executionTime = _routeStopDelayService.GetExecutionTime(startStop, endStop, arrivalTimeAtEndStop, driverFirstStop);

            TimeSpan queueTime = _routeStopDelayService.GetQueueTime(startStop, endStop, arrivalTimeAtEndStop);

            var routeStatistics = new RouteStatistics()
            {
                TotalExecutionTime  = executionTime,
                TotalIdleTime       = idleTime,
                TotalTravelTime     = tripLength.Time,
                TotalTravelDistance = tripLength.Distance,
                TotalQueueTime      = queueTime
            };

            var result = new RouteSegmentStatistics
            {
                StartStop         = startStop,
                EndStop           = endStop,
                StartTime         = startTime,
                Statistics        = routeStatistics,
                WhiffedTimeWindow = whiffed
            };

            return(result);
        }