/// <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); }
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); }
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 }); }
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); }