Exemple #1
0
        /// <summary>
        /// Returns true if the route statistics exceed our exit criteria
        /// </summary>
        /// <param name="routeStatistics">the generated metrics for the route</param>
        /// <param name="driver">the driver of the route</param>
        /// <returns>true if route exceeds criteria, otherwise false</returns>
        public bool ExeedsExitCriteria(RouteStatistics routeStatistics, Driver driver)
        {
            var result = routeStatistics.TotalTravelTime > driver.AvailableDrivingTime || routeStatistics.TotalTime > driver.AvailableDutyTime;

            if (result && this._logger.IsDebugEnabled)
            {
                if (routeStatistics.TotalTravelTime > driver.AvailableDrivingTime)
                {
                    this._logger.Debug("Route exceeds AvailableDrivingTime. TotalTravelTime={0}, AvailableDrivingTime={1}",
                                       routeStatistics.TotalTravelTime.TotalHours,
                                       driver.AvailableDrivingTime.TotalHours);
                }

                if (routeStatistics.TotalTime > driver.AvailableDutyTime)
                {
                    this._logger.Debug("Route exceeds AvailableDutyTime. TotalTime={0}, AvailableDutyTime={1}",
                                       routeStatistics.TotalTime.TotalHours,
                                       driver.AvailableDutyTime.TotalHours);
                }
            }

            if (result)
            {
                return(result);
            }

            return(result);
        }
Exemple #2
0
        /// <summary>
        /// Compares route solutions
        /// </summary>
        public int CompareRouteStatistics(RouteStatistics left, RouteStatistics right)
        {
            var leftMeasure  = _objectiveFunction.GetObjectiveMeasure(left);
            var rightMeasure = _objectiveFunction.GetObjectiveMeasure(right);

            return(leftMeasure.CompareTo(rightMeasure));
        }
Exemple #3
0
        /// <summary>
        /// Returns true if the given route solution is feasable within time windows and exit criteria
        /// </summary>
        /// <param name="nodeRouteSolution"></param>
        /// <returns></returns>
        public bool IsFeasableRouteSolution(NodeRouteSolution nodeRouteSolution)
        {
            var driverNode                = nodeRouteSolution.DriverNode;
            var currentNodeEndTime        = driverNode.Driver.EarliestStartTime;
            var cumulativeRouteStatistics = new RouteStatistics();
            var allNodes = nodeRouteSolution.AllNodes;

            for (int i = 0; i < allNodes.Count - 1; i++)
            {
                var nodeTiming = _nodeService.GetNodeTiming(allNodes[i], allNodes[i + 1], currentNodeEndTime, cumulativeRouteStatistics);

                if (nodeTiming.IsFeasableTimeWindow)
                {
                    // is it a feasable route
                    var lastConnection       = _nodeService.GetNodeConnection(nodeTiming.Node, driverNode);
                    var finalRouteStatistics = nodeTiming.CumulativeRouteStatistics + lastConnection.RouteStatistics;

                    if (_routeExitFunction.ExeedsExitCriteria(finalRouteStatistics, driverNode.Driver))
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }

                currentNodeEndTime        = nodeTiming.EndExecutionTime;
                cumulativeRouteStatistics = nodeTiming.CumulativeRouteStatistics;
            }

            return(true);
        }
        public double GetObjectiveMeasure(RouteStatistics statistics)
        {
            var result =
                (statistics.TotalTime.TotalSeconds - statistics.TotalIdleTime.TotalSeconds)
                * ((double)1 / (statistics.DriversWithAssignments + 1));

            return(result);
        }
Exemple #5
0
 public JobNode(Job job, double[,] statisticsMatrix) : this(job)
 {
     RouteStatisticsMatrix = statisticsMatrix;
     RouteStatistics       = new RouteStatistics
     {
         DriversWithAssignments = 1,
         PriorityValue          = job.Priority,
         TotalCapacity          = 0,
         //TotalExecutionTime = statisticsMatrix[]
     };
 }
        /// <summary>
        /// Returns the <see cref="NodeTiming"/> for the next node
        /// </summary>
        /// <returns></returns>
        public NodeTiming GetNodeTiming(INode currentNode, INode nextNode, DateTime currentNodeEndTime, RouteStatistics currentRouteStatistics)
        {
            var connection = GetNodeConnection(currentNode, nextNode);

            DateTime nextNodeArrivalTime = currentNodeEndTime + connection.LocalRouteStatistics.TotalTime;

            bool isFirstStop = currentNode is DriverNode;

            // determine if time arrived within time window and calculate wait time
            bool early = nextNodeArrivalTime < nextNode.WindowStart;
            bool late  = nextNodeArrivalTime > nextNode.WindowEnd;

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

            if (early)
            {
                waitTime = nextNode.WindowStart.Subtract(nextNodeArrivalTime);

                TimeSpan maxWaitTime = isFirstStop ? _configuration.MaximumWaitTimeBeforeStart : _configuration.MaximumWaitTimeAtStop;

                isFeasableTimeWindow = waitTime < maxWaitTime;
            }
            else if (late)
            {
                // we started past the time window
                isFeasableTimeWindow = false;
            }
            else
            {
                isFeasableTimeWindow = true;
            }

            DateTime nextNodeStartTime = nextNodeArrivalTime + waitTime;
            DateTime nextNodeEndTime   = nextNodeStartTime + nextNode.LocalRouteStatistics.TotalTime;

            RouteStatistics cumulativeRouteStatistics = currentRouteStatistics + connection.LocalRouteStatistics + nextNode.LocalRouteStatistics;

            var result = new NodeTiming()
            {
                Node                      = nextNode,
                ArrivalTime               = nextNodeArrivalTime,
                StartTime                 = nextNodeStartTime,
                EndTime                   = nextNodeEndTime,
                IsFeasableTimeWindow      = isFeasableTimeWindow,
                CumulativeRouteStatistics = cumulativeRouteStatistics
            };

            //var st = (result.ArrivalTime - DateTime.Now.Date).TotalMinutes;
            //var et = (result.EndTime - DateTime.Now.Date).TotalMinutes;
            //Console.WriteLine("{0},{1},{2}", nextNode, st, et);

            return(result);
        }
Exemple #7
0
        /// <summary>
        /// Compares route solutions
        /// </summary>
        public int Compare(RouteStatistics left, RouteStatistics right)
        {
            if (left.DriversWithAssignments == 1 || right.DriversWithAssignments == 1)
            {
                ;
            }
            double leftMeasure  = _objectiveFunction.GetObjectiveMeasure(left);
            double rightMeasure = _objectiveFunction.GetObjectiveMeasure(right);

            return(leftMeasure.CompareTo(rightMeasure));
        }
        /// <summary>
        /// Computes the Solution Performance Statistics
        /// </summary>
        /// <param name="solution">The solution from which the report is generated</param>
        /// <returns>The generated Performance Statistics from the Solution</returns>
        public SolutionPerformanceStatistics GetSolutionPerformanceStatistics(Solution solution)
        {
            var truckStatisticBySolution         = new Dictionary <NodeRouteSolution, TruckPerformanceStatistics>();
            var totalRouteStatisticsByTruckState = new Dictionary <TruckState, RouteStatistics>();
            var totalPerformanceStatistics       = new PerformanceStatistics();
            var totalRouteStatistics             = new RouteStatistics();

            foreach (var routeSolution in solution.RouteSolutions)
            {
                // calculate truck performance statistics
                var truckStatistics = CalculateTruckPerformanceStatistics(routeSolution);
                truckStatisticBySolution[routeSolution] = truckStatistics;

                // calculate total route statistics by truck state
                foreach (var truckState in truckStatistics.RouteStatisticsByTruckState.Keys)
                {
                    if (!totalRouteStatisticsByTruckState.ContainsKey(truckState))
                    {
                        totalRouteStatisticsByTruckState[truckState] = new RouteStatistics();
                    }

                    totalRouteStatisticsByTruckState[truckState] += truckStatistics.RouteStatisticsByTruckState[truckState];
                }

                // sum up performance & route stats
                totalPerformanceStatistics += truckStatistics.PerformanceStatistics;
                totalRouteStatistics       += truckStatistics.RouteStatistics;
            }

            double solutionCount = solution.RouteSolutions.Count;

            var result = new SolutionPerformanceStatistics
            {
                TruckStatistics = truckStatisticBySolution,
                TotalRouteStatisticsByTruckState = totalRouteStatisticsByTruckState,
                TotalRouteStatistics             = totalRouteStatistics,
                NumberOfBackhauls          = totalPerformanceStatistics.NumberOfBackhauls,
                AverageNumberOfBackhauls   = totalPerformanceStatistics.NumberOfBackhauls / solutionCount,
                NumberOfLoadmatches        = totalPerformanceStatistics.NumberOfLoadmatches,
                AverageNumberOfLoadmatches = totalPerformanceStatistics.NumberOfLoadmatches / solutionCount,
                NumberOfJobs        = totalPerformanceStatistics.NumberOfJobs,
                AverageNumberOfJobs = totalPerformanceStatistics.NumberOfJobs / solutionCount,
                AverageDriverDutyHourUtilization = totalPerformanceStatistics.DriverDutyHourUtilization / solutionCount,
                AverageDriverDrivingUtilization  = totalPerformanceStatistics.DriverDrivingUtilization / solutionCount,
                DrivingTimePercentage            = totalRouteStatistics.TotalTravelTime.TotalHours / totalRouteStatistics.TotalTime.TotalHours,
                WaitingTimePercentage            = totalRouteStatistics.TotalIdleTime.TotalHours / totalRouteStatistics.TotalTime.TotalHours
            };

            return(result);
        }
Exemple #9
0
        /// <summary>
        /// Generates node sequence iteration
        /// </summary>
        /// <param name="nodes"></param>
        /// <param name="driverNode"> </param>
        /// <returns></returns>
        public virtual NodeRouteSolution GenerateRouteSolution(IList <INode> nodes, DriverNode driverNode)
        {
            IList <INode> processedNodes            = new List <INode>();
            INode         currentNode               = driverNode;
            var           startTime                 = driverNode.Driver.EarliestStartTime;
            var           currentNodeEndTime        = startTime;
            var           cumulativeRouteStatistics = new RouteStatistics();

            int exitCounter = 0;

            while (exitCounter++ < 1000)
            {
                // getting avaiable nodes that have not been processed
                var feasibleNodeTimings = GetFeasibleNodes(nodes, driverNode, processedNodes, currentNodeEndTime, cumulativeRouteStatistics);

                if (!feasibleNodeTimings.Any())
                {
                    break;
                }

                var feasibleNodeTimingsByNode = feasibleNodeTimings.ToDictionary(f => f.Node);

                // build probability matrix for the available nodes
                var probabilityData = _probabilityMatrix.BuildProbabilityDataMatrix(currentNode, feasibleNodeTimings);

                // find a suitable node based on the cumulative probability
                var selectedNode = (INode)_probabilityMatrix.GetNominatedElement(probabilityData);
                processedNodes.Add(selectedNode);
                currentNode = selectedNode;

                // now we update the current node's end time
                var selectedNodeTiming = feasibleNodeTimingsByNode[selectedNode];

                if (processedNodes.Count == 1 && selectedNodeTiming.DepartureTime != currentNodeEndTime)
                {
                    startTime = selectedNodeTiming.DepartureTime;
                }

                currentNodeEndTime        = selectedNodeTiming.EndExecutionTime;
                cumulativeRouteStatistics = selectedNodeTiming.CumulativeRouteStatistics;
            }

            // create solution object
            var result = _routeService.CreateRouteSolution(processedNodes, driverNode);

            result.StartTime = startTime;
            return(result);
        }
Exemple #10
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);
        }
        /// <summary>
        /// Calculates the toal route statistics a list of route stops
        /// </summary>
        /// <param name="stops"></param>
        /// <param name="ignoreFirstStopDelays"> </param>
        /// <returns></returns>
        public RouteStatistics CalculateRouteStatistics(IList <RouteStop> stops, bool ignoreFirstStopDelays, RouteStop lastNodeEndStop = null)
        {
            var result = new RouteStatistics();

            for (int i = 0; i < stops.Count; i++)
            {
                var currentStop  = stops[i];
                var previousStop = i > 0 ? stops[i - 1] : null;

                if (!ignoreFirstStopDelays || !(i == 0 || i == stops.Count - 1))
                {
                    var executionTime = _routeStopDelayService.GetExecutionTime(previousStop, currentStop, TimeSpan.Zero);

                    var staticStats = new RouteStatistics()
                    {
                        TotalExecutionTime = executionTime,
                    };

                    result += staticStats;
                }

                // add travel cost
                if (i < stops.Count - 1)
                {
                    var nextStop = stops[i + 1];

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

                    var travelStats = new RouteStatistics()
                    {
                        TotalTravelTime     = tripLength.Time,
                        TotalTravelDistance = tripLength.Distance,
                    };

                    result += travelStats;
                }
            }

            return(result);
        }
Exemple #12
0
        /// <summary>
        /// Calculates the toal route statistics a list of route stops
        /// </summary>
        /// <param name="stops"></param>
        /// <param name="ignoreFirstStopDelays"> </param>
        /// <returns></returns>
        public RouteStatistics CalculateRouteStatistics(IList <RouteStop> stops, bool ignoreFirstStopDelays = false)
        {
            var result = new RouteStatistics();

            // TODO : This does not take WaitTime into account

            for (int i = 0; i < stops.Count; i++)
            {
                var currentStop = stops[i];

                if (!ignoreFirstStopDelays && (i == 0 || i == stops.Count - 1))
                {
                    var executionTime = _routeStopDelayService.GetDelay(currentStop);

                    var staticStats = new RouteStatistics()
                    {
                        TotalExecutionTime = executionTime,
                    };
                    result += staticStats;
                }

                // add travel cost
                if (i < stops.Count - 1)
                {
                    var nextStop = stops[i + 1];

                    // calculate the trip between the current and next stop
                    var tripLength  = CalculateTripLength(currentStop, nextStop);
                    var travelStats = new RouteStatistics()
                    {
                        TotalTravelTime     = tripLength.Time,
                        TotalTravelDistance = tripLength.Distance,
                    };
                    result += travelStats;
                }
            }

            return(result);
        }
        public bool JobNodeTimings(IList <Job> jobs, Driver driver, out List <NodeTiming> nodeTimings, out IList <int> ints)
        {
            nodeTimings = new List <NodeTiming>();
            ints        = new List <int>();
            if (driver == null || jobs == null || !jobs.Any())
            {
                {
                    return(true);
                }
            }

            var jobNodes                  = jobs.Select((job, i) => _jobNodeService.CreateJobNode(job, null, i != 0)).Cast <INode>().ToList();
            var driverNode                = new DriverNode(driver);
            var processedNodes            = new List <INode>();
            var cumulativeRouteStatistics = new RouteStatistics();

            //var routeSolution = GenerateRouteSolution(jobNodes, driverNode);

            //GetFeasibleNodes(jobNodes, driverNode, processedNodes, )
            //var isFirstStop = processedNodes.Count == 0;
            //var currentNode = isFirstStop ? driverNode : processedNodes.Last();

            // first check feasibility for driver to first node
            var nodeTimingResult = _routeStatisticsService.GetNodeTiming(
                driverNode, jobNodes.FirstOrDefault(), driverNode.WindowStart, cumulativeRouteStatistics);


            if (!nodeTimingResult.IsFeasableTimeWindow)
            {
                // all are infeasible
                {
                    ints = jobNodes.Select(p => p.Id).ToList();
                    return(true);
                }
            }

            nodeTimings = new List <NodeTiming>()
            {
                nodeTimingResult
            };

            for (int i = 1; i < jobNodes.Count; i++)
            {
                var currentNode        = (JobNode)jobNodes[i];
                var lastNode           = jobNodes[i - 1];
                var iterationStartTime = nodeTimingResult.EndExecutionTime;

                nodeTimingResult = _routeStatisticsService.GetNodeTiming(
                    lastNode, currentNode, iterationStartTime, cumulativeRouteStatistics);

                nodeTimingResult.CumulativeRouteStatistics = cumulativeRouteStatistics + nodeTimingResult.CumulativeRouteStatistics;

                if (_routeExitFunction.ExeedsExitCriteria(nodeTimingResult.CumulativeRouteStatistics, driverNode.Driver))
                {
                    nodeTimingResult.IsFeasableTimeWindow = false;
                }

                nodeTimings.Add(nodeTimingResult);
            }

            var lastLeg = _routeStatisticsService.GetRouteStatistics(nodeTimingResult.Node, driverNode, nodeTimingResult.EndExecutionTime);
            var finalRouteStatistics = nodeTimingResult.CumulativeRouteStatistics + lastLeg;

            if (_routeExitFunction.ExeedsExitCriteria(finalRouteStatistics, driverNode.Driver))
            {
                nodeTimingResult.IsFeasableTimeWindow = false;
            }

            nodeTimings.Add(nodeTimingResult);
            return(false);
        }
        public virtual NodeRouteSolution GenerateIterativeRouteSolution(IList <INode> nodes, DriverNode driverNode, bool reOrder = true)
        {
            IList <INode> processedNodes            = new List <INode>();
            INode         currentNode               = driverNode;
            var           startTime                 = driverNode.Driver.EarliestStartTimeSpan;
            var           currentNodeEndTime        = startTime;
            var           cumulativeRouteStatistics = new RouteStatistics();

            nodes = SortINodes(nodes, driverNode.Driver, reOrder).ToList();

            int exitCounter = 0;

            while (exitCounter++ < 1000)
            {
                nodes = nodes.Where(x => !processedNodes.Select(y => y.Id).ToList().Contains(x.Id)).ToList();

                // getting avaiable nodes that have not been processed
                if (!nodes.Any())
                {
                    break;
                }

                var feasibleNodeTimingsList = SortINodes(nodes, driverNode.Driver, reOrder).ToList();

                var firstHitFeasibleNodeTiming = feasibleNodeTimingsList.FirstOrDefault(y => y.WindowEnd > currentNodeEndTime);

                if (firstHitFeasibleNodeTiming == null)
                {
                    break;
                }

                var firstHitFeasibleNodeTimingNode = firstHitFeasibleNodeTiming;

                var selectedNode    = firstHitFeasibleNodeTimingNode;
                var selectedJobNode = selectedNode is JobNode ? selectedNode as JobNode : null;

                var processedRouteStops   = processedNodes.SelectMany(x => x.RouteStops);
                var provisionalRouteStops = new Queue <RouteStop>();
                foreach (var processedRouteStop in processedRouteStops)
                {
                    provisionalRouteStops.Enqueue(processedRouteStop);
                }
                foreach (var routeStop in selectedNode.RouteStops)
                {
                    provisionalRouteStops.Enqueue(routeStop);
                }

                var tempJob = new Job
                {
                    RouteStops = provisionalRouteStops.Select(x => x).ToList(),
                    IsHazmat   = selectedJobNode != null && selectedJobNode.Job != null ? selectedJobNode.Job.IsHazmat : false
                };

                var tempJobNode = _jobNodeService.CreateJobNode(tempJob, driverNode.Driver.EarliestStartTimeSpan, false);

                if (!tempJobNode.IsInvalid)
                {
                    var serviceTimeIndex = _jobNodeService.GetMatrixIndex("ServiceTime");
                    var waitTimeIndex    = _jobNodeService.GetMatrixIndex("WaitTime");
                    var travelTimeIndex  = _jobNodeService.GetMatrixIndex("TravelTime");
                    var entryCount       = tempJobNode.RouteStatisticsMatrix.GetLength(1);

                    var travelTime  = TimeSpan.Zero;
                    var serviceTime = TimeSpan.Zero;
                    var waitTime    = TimeSpan.Zero;

                    for (var i = 0; i < entryCount; i++)
                    {
                        travelTime  += TimeSpan.FromSeconds(tempJobNode.RouteStatisticsMatrix[travelTimeIndex, i]);
                        serviceTime += TimeSpan.FromSeconds(tempJobNode.RouteStatisticsMatrix[serviceTimeIndex, i]);
                        waitTime    += TimeSpan.FromSeconds(tempJobNode.RouteStatisticsMatrix[waitTimeIndex, i]);
                    }

                    var statistics = new RouteStatistics
                    {
                        TotalExecutionTime = serviceTime,
                        TotalIdleTime      = waitTime,
                        TotalTravelTime    = travelTime,
                        TotalQueueTime     = TimeSpan.Zero
                    };
                    if (!_routeExitFunction.ExeedsExitCriteria(statistics, driverNode.Driver) &&
                        _routeExitFunction.MeetsPortCriteria(tempJobNode.RouteStops, driverNode.Driver) &&
                        PassesFilterCriteria(driverNode, tempJobNode, new List <INode>())
                        )
                    {
                        processedNodes.Add(selectedNode);
                        driverNode.Driver.EarliestStartTime = tempJobNode.WindowStart.Ticks;
                    }
                    else
                    {
                        nodes.RemoveAt(0);
                    }
                }
                else
                {
                    nodes.RemoveAt(0);
                }
            }

            // create solution object, adjust start time
            var result           = _routeService.CreateRouteSolution(driverNode, processedNodes);
            var driverStartTicks = Math.Max(driverNode.Driver.EarliestStartTime, startTime.Ticks);

            result.StartTime = TimeSpan.FromTicks(driverStartTicks);

            var s = string.Join("\t", result.Nodes.Select(f => "[" + f.Id + "]").ToArray());

            Console.WriteLine(s);
            Console.WriteLine(result.RouteStatistics.ToString());

            return(result);
        }
        /// <summary>
        /// Generates node sequence iteration
        /// </summary>
        /// <param name="nodes"></param>
        /// <param name="driverNode"> </param>
        /// <returns></returns>
        public virtual NodeRouteSolution GenerateRouteSolution(IList <INode> nodes, DriverNode driverNode)
        {
            IList <INode> processedNodes            = new List <INode>();
            INode         currentNode               = driverNode;
            var           startTime                 = driverNode.Driver.EarliestStartTimeSpan;
            var           currentNodeEndTime        = startTime;
            var           cumulativeRouteStatistics = new RouteStatistics();

            int exitCounter = 0;

            while (exitCounter++ < 1000)
            {
                // getting avaiable nodes that have not been processed
                var feasibleNodeTimings = GetFeasibleNodes(nodes, driverNode, processedNodes, currentNodeEndTime, cumulativeRouteStatistics);
                if (!feasibleNodeTimings.Any())
                {
                    break;
                }

                var feasibleNodeTimingsByNode = feasibleNodeTimings.ToDictionary(f => f.Node);

                // build probability matrix for the available nodes
                var probabilityData = _probabilityMatrix.BuildProbabilityDataMatrix(currentNode, feasibleNodeTimings);

                // find a suitable node based on the cumulative probability
                var selectedNode = (INode)_probabilityMatrix.GetNominatedElement(probabilityData);

                selectedNode.DepartureTime = feasibleNodeTimingsByNode[selectedNode].DepartureTime; // set the Departure Time

                // break if we nominated the driver node
                if (selectedNode == driverNode)
                {
                    break;
                }

                processedNodes.Add(selectedNode);
                currentNode = selectedNode;

                // now we update the current node's end time
                var selectedNodeTiming = feasibleNodeTimingsByNode[selectedNode];

                if (processedNodes.Count == 1 && selectedNodeTiming.DepartureTime != currentNodeEndTime.Ticks)
                {
                    startTime = new TimeSpan(selectedNodeTiming.DepartureTime);
                }

                currentNodeEndTime        = selectedNodeTiming.EndExecutionTime;
                cumulativeRouteStatistics = selectedNodeTiming.CumulativeRouteStatistics;

                var processedRouteStops   = processedNodes.SelectMany(x => x.RouteStops);
                var provisionalRouteStops = new Queue <RouteStop>();
                foreach (var processedRouteStop in processedRouteStops)
                {
                    provisionalRouteStops.Enqueue(processedRouteStop);
                }
                foreach (var routeStop in selectedNode.RouteStops)
                {
                    provisionalRouteStops.Enqueue(routeStop);
                }

                var tempJob = new Job
                {
                    RouteStops = provisionalRouteStops.Select(x => x).ToList()
                };

                var tempJobNode = _jobNodeService.CreateJobNode(tempJob, driverNode.Driver.EarliestStartTimeSpan, false);

                if (!tempJobNode.IsInvalid)
                {
                    var serviceTimeIndex = _jobNodeService.GetMatrixIndex("ServiceTime");
                    var waitTimeIndex    = _jobNodeService.GetMatrixIndex("WaitTime");
                    var travelTimeIndex  = _jobNodeService.GetMatrixIndex("TravelTime");
                    var entryCount       = tempJobNode.RouteStatisticsMatrix.GetLength(1);

                    var travelTime  = TimeSpan.Zero;
                    var serviceTime = TimeSpan.Zero;
                    var waitTime    = TimeSpan.Zero;

                    for (var i = 0; i < entryCount; i++)
                    {
                        travelTime  += TimeSpan.FromSeconds(tempJobNode.RouteStatisticsMatrix[travelTimeIndex, i]);
                        serviceTime += TimeSpan.FromSeconds(tempJobNode.RouteStatisticsMatrix[serviceTimeIndex, i]);
                        waitTime    += TimeSpan.FromSeconds(tempJobNode.RouteStatisticsMatrix[waitTimeIndex, i]);
                    }

                    var statistics = new RouteStatistics
                    {
                        TotalExecutionTime = serviceTime,
                        TotalIdleTime      = waitTime,
                        TotalTravelTime    = travelTime,
                        TotalQueueTime     = TimeSpan.Zero
                    };
                    if (!_routeExitFunction.ExeedsExitCriteria(statistics, driverNode.Driver))
                    {
                        processedNodes.Add(selectedNode);
                        driverNode.Driver.EarliestStartTime = tempJobNode.WindowStart.Ticks;
                    }
                }
            }

            // create solution object, adjust start time
            var result           = _routeService.CreateRouteSolution(driverNode, processedNodes);
            var driverStartTicks = Math.Max(driverNode.Driver.EarliestStartTime, startTime.Ticks);

            result.StartTime = TimeSpan.FromTicks(driverStartTicks);

            var s = string.Join("\t", result.Nodes.Select(f => "[" + f.Id + "]").ToArray());

            Console.WriteLine(s);
            Console.WriteLine(result.RouteStatistics.ToString());

            return(result);
        }
Exemple #16
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);
        }
Exemple #17
0
 /// <summary>
 /// Returns the objective measure that we are minimizing
 /// </summary>
 /// <param name="routeStatistics">the route from which the selection criteria is selected</param>
 /// <returns>the value of the selection criteria</returns>
 public double GetObjectiveMeasure(RouteStatistics routeStatistics)
 {
     return((double)routeStatistics.TotalTravelDistance);
 }
 /// <summary>
 /// Returns the objective measure that we are minimizing
 /// </summary>
 /// <param name="routeStatistics"></param>
 /// <returns></returns>
 public double GetObjectiveMeasure(RouteStatistics routeStatistics)
 {
     return(routeStatistics.TotalTime.TotalMinutes);
 }
Exemple #19
0
 /// <summary>
 /// Returns the objective measure that we are minimizing
 /// </summary>
 /// <param name="statistics"></param>
 /// <returns></returns>
 public double GetObjectiveMeasure(RouteStatistics statistics)
 {
     return(statistics.TotalTime.TotalSeconds);
 }
        /// <summary>
        /// Calculates the route statistics for a list of stops
        /// </summary>
        /// <param name="stops"></param>
        /// <param name="startTime"></param>
        /// <param name="ignoreFirstStopDelays"> </param>
        /// <returns></returns>
        public RouteStatistics CalculateRouteStatistics(IList <RouteStop> stops, TimeSpan startTime, bool ignoreFirstStopDelays, RouteStop lastNodeEndStop = null)
        {
            var result = new RouteStatistics();

            var currentTime = startTime;

            for (int i = 0; i < stops.Count; i++)
            {
                var currentStop  = stops[i];
                var previousStop = i > 0 ? stops[i - 1] : lastNodeEndStop;
                var waitTime     = TimeSpan.Zero;
                if (currentTime < currentStop.WindowStart)
                {
                    // early
                    waitTime = currentStop.WindowStart.Subtract(currentTime);
                }
                else if (currentTime > currentStop.WindowEnd)
                {
                    ;
                    // late
                    //var lateTime = currentTime.Subtract(currentStop.WindowEnd);
                }

                if (ignoreFirstStopDelays)
                {
                    if (i != 0)
                    {
                        var executionTime = _routeStopDelayService.GetExecutionTime(previousStop, currentStop,
                                                                                    currentTime);
                        var staticStats = new RouteStatistics()
                        {
                            TotalExecutionTime = executionTime,
                            TotalIdleTime      = waitTime,
                        };

                        result += staticStats;
                    }
                }
                else
                {
                    // todo refactor
                    var executionTime = _routeStopDelayService.GetExecutionTime(previousStop, currentStop, currentTime);
                    var staticStats   = new RouteStatistics()
                    {
                        TotalExecutionTime = executionTime,
                        TotalIdleTime      = waitTime,
                    };

                    result += staticStats;
                }

                // update current time with accumulated total time
                currentTime = startTime + result.TotalTime;

                // add travel cost
                if (i < stops.Count - 1)
                {
                    var nextStop = stops[i + 1];
                    if (currentStop.Location != null && nextStop.Location != null)
                    {
                        // calculate the trip between the current and next stop
                        var tripLength  = CalculateTripLength(currentStop, nextStop, currentTime);
                        var queueTime   = _routeStopDelayService.GetQueueTime(currentStop, nextStop, currentTime);
                        var travelStats = new RouteStatistics()
                        {
                            TotalTravelTime     = tripLength.Time,
                            TotalTravelDistance = tripLength.Distance,
                            TotalQueueTime      = queueTime,
                        };

                        result += travelStats;
                    }
                }

                // update current time once again with accumulated total time
                currentTime = startTime + result.TotalTime;
            }

            return(result);
        }
        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);
        }
Exemple #22
0
        public virtual List <NodeTiming> GetFeasibleNodes(IList <INode> availableNodes, DriverNode driverNode, IList <INode> processedNodes,
                                                          TimeSpan currentNodeEndTime, RouteStatistics cumulativeRouteStatistics)
        {
            var isFirstStop = (processedNodes.Count == 0);
            var currentNode = isFirstStop ? driverNode : processedNodes.Last();

            if (currentNode is JobNode)
            {
                ;
            }
            var filteredAvailableNodes = new List <INode>();

            // filter available nodes based on predefined criteria
            foreach (var availableNode in availableNodes)
            {
                if (availableNode is JobNode)
                {
                    //if (PassesFilterCriteria(driverNode, (JobNode)availableNode))
                    {
                        filteredAvailableNodes.Add(availableNode);
                    }
                }
                else
                {
                    filteredAvailableNodes.Add(availableNode);  // we are only filtering JobNodes
                }
            }

            availableNodes = filteredAvailableNodes.ToList();

            // get the node timings for all of the available nodes
            var nodeTimings = availableNodes.Except(processedNodes)
                              .Select(nextNode => _nodeService.GetNodeTiming(currentNode, nextNode, currentNodeEndTime, cumulativeRouteStatistics))
                              .ToList();

            var feasibleNodes = new List <NodeTiming>();

            foreach (var nodeTiming in nodeTimings.Where(f => f.IsFeasableTimeWindow))
            {
                var finalConnection      = _nodeService.GetNodeConnection(nodeTiming.Node, driverNode);
                var finalRouteStatistics = nodeTiming.CumulativeRouteStatistics + finalConnection.RouteStatistics;

                if (!_routeExitFunction.ExeedsExitCriteria(finalRouteStatistics, driverNode.Driver))
                {
                    feasibleNodes.Add(nodeTiming);
                }
            }

            return(feasibleNodes);
        }
        public virtual List <NodeTiming> GetFeasibleNodes(IList <INode> availableNodes, DriverNode driverNode, IList <INode> processedNodes,
                                                          TimeSpan currentNodeEndTime, RouteStatistics cumulativeRouteStatistics)
        {
            var isFirstStop = (processedNodes.Count == 0);
            var currentNode = isFirstStop ? driverNode : processedNodes.Last();

            var filteredAvailableNodes = new List <INode>();

            var updatedNodes = new List <INode>();

            if (currentNode is JobNode)
            {
                // update nodes to adjust for potentially shortened execution time
                foreach (var n in availableNodes)
                {
                    if (n is JobNode)
                    {
                        var node = _jobNodeService.CreateJobNode(((JobNode)n).Job, currentNodeEndTime,
                                                                 IsExecutionTimeIgnored(currentNode, n));
                        updatedNodes.Add(node);
                    }
                    else
                    {
                        updatedNodes.Add(n);
                    }
                }

                availableNodes = updatedNodes.ToList();
            }

            // filter available nodes based on predefined criteria
            foreach (var availableNode in availableNodes)
            {
                if (availableNode is JobNode)
                {
                    if (PassesFilterCriteria(driverNode, (JobNode)availableNode, filteredAvailableNodes))
                    {
                        filteredAvailableNodes.Add(availableNode);
                    }
                    else
                    {
                        ;
                    }
                }
                else
                {
                    filteredAvailableNodes.Add(availableNode);  // we are only filtering JobNodes
                }
            }

            availableNodes = filteredAvailableNodes.ToList();

            // get the node timings for all of the available nodes
            var unprocessedNodes = availableNodes.Where(x => !processedNodes.Select(y => y.Id).ToList().Contains(x.Id));

            unprocessedNodes = new List <INode>();
            foreach (var availableNode in availableNodes)
            {
                var processedNodesIds = processedNodes.Select(x => x.Id);
                if (!processedNodesIds.Contains(availableNode.Id))
                {
                    unprocessedNodes = unprocessedNodes.Concat(new List <INode> {
                        availableNode
                    });
                }
            }

            var nodeTimings = unprocessedNodes.Select(nextNode =>
                                                      _routeStatisticsService.GetNodeTiming(currentNode, nextNode, currentNodeEndTime, cumulativeRouteStatistics));

            var feasibleNodes = new List <NodeTiming>();

            foreach (var nodeTiming in nodeTimings.Where(f => f.IsFeasableTimeWindow))
            {
                // calculate for return home to driver node
                var lastLeg = _routeStatisticsService.GetRouteStatistics(nodeTiming.Node, driverNode, nodeTiming.EndExecutionTime);
                var finalRouteStatistics = nodeTiming.CumulativeRouteStatistics + lastLeg;

                if (!_routeExitFunction.ExeedsExitCriteria(finalRouteStatistics, driverNode.Driver))
                {
                    feasibleNodes.Add(nodeTiming);
                }
            }

            return(feasibleNodes);
        }
        /// <summary>
        /// Returns the <see cref="NodeTiming"/> for the next node
        /// </summary>
        /// <returns></returns>
        public virtual NodeTiming GetNodeTiming(INode startNode, INode endNode, TimeSpan startNodeEndTime, RouteStatistics currentRouteStatistics)
        {
            bool isFirstStop = startNode is DriverNode;
            var  connectionRouteStatistics = GetRouteStatistics(startNode, endNode, startNodeEndTime);
            var  originalStartNodeEndTime  = startNodeEndTime.Ticks;

            if (isFirstStop)
            {
                var travelTime      = connectionRouteStatistics.TotalTravelTime.Ticks;
                var driverStartTime = originalStartNodeEndTime;
                var jobNodeEnd      = endNode.WindowEnd.Ticks;
                var jobNodeStart    = endNode.WindowStart.Ticks;

                startNodeEndTime = TimeSpan.FromTicks(Math.Max(jobNodeEnd - travelTime, driverStartTime));
                startNodeEndTime = TimeSpan.FromTicks(Math.Max(jobNodeStart - travelTime, driverStartTime));
            }

            TimeSpan endNodeArrivalTime = startNodeEndTime + connectionRouteStatistics.TotalTravelTime;

            // cbs 16 Sep 14 Scheduling Night Shift starts with day orders
            if (endNodeArrivalTime.Days > 0)
            {
                endNodeArrivalTime = endNodeArrivalTime.Add(TimeSpan.FromDays(endNodeArrivalTime.Days * -1));
            }

            // determine if time arrived within time window and calculate wait time
            var firstStopWaitMinutes         = isFirstStop ? endNodeArrivalTime.Subtract(TimeSpan.FromTicks(originalStartNodeEndTime)).TotalMinutes : 0;
            var isDriverAlreadyLate          = startNodeEndTime > endNode.WindowEnd;
            var isFirstStopWithinDelayPeriod = isFirstStop && !isDriverAlreadyLate &&
                                               firstStopWaitMinutes <= _configuration.MaximumIdleTimeBeforeStart.TotalMinutes;



            bool early = endNodeArrivalTime <= endNode.WindowStart;
            bool late  = (endNodeArrivalTime > endNode.WindowEnd) || (isFirstStop && !isFirstStopWithinDelayPeriod);

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


            if (early)
            {
                // if we are early to make it to the first stop, there's no need to wait, we will
                // adjust the nextNodeArrivalTime to reflect the windowStartTime of the first
                // location to goto.

                if (!isFirstStop)
                {
                    idleTime = endNode.WindowStart.Subtract(endNodeArrivalTime);
                }
                else
                {
                    startNodeEndTime   = endNode.WindowStart - connectionRouteStatistics.TotalTime;
                    startNodeEndTime   = endNode.WindowStart - connectionRouteStatistics.TotalNonIdleTime;
                    endNodeArrivalTime = startNodeEndTime + connectionRouteStatistics.TotalTravelTime;
                    idleTime           = endNode.WindowStart.Subtract(endNodeArrivalTime);
                }

                var maxIdleTime = isFirstStop ? _configuration.MaximumIdleTimeBeforeStart : _configuration.MaximumIdleTimeAtStop;
                isFeasableTimeWindow = idleTime < maxIdleTime;
            }
            else if (late)
            {
                // we started past the time window
                isFeasableTimeWindow = false;
            }
            else
            {
                isFeasableTimeWindow = true;
            }

            var endNodeRouteStatistics = GetRouteStatistics(endNode, endNodeArrivalTime);

            TimeSpan queueTime = endNodeRouteStatistics.TotalQueueTime;

            TimeSpan nextNodeStartTime = endNodeArrivalTime + idleTime;

            TimeSpan nextNodeEndTime = nextNodeStartTime + endNodeRouteStatistics.TotalTime;

            // wait?
            RouteStatistics localRouteStatistics = new RouteStatistics()
            {
                TotalIdleTime = idleTime
            };

            RouteStatistics cumulativeRouteStatistics =
                currentRouteStatistics + connectionRouteStatistics + endNodeRouteStatistics + localRouteStatistics;

            var result = new NodeTiming()
            {
                Node                      = endNode,
                DepartureTime             = startNodeEndTime.Ticks,
                ArrivalTime               = endNodeArrivalTime,
                StartExecutionTime        = nextNodeStartTime,
                IdleTime                  = isFirstStop ? TimeSpan.Zero : idleTime,
                QueueTime                 = queueTime,
                EndExecutionTime          = nextNodeEndTime,
                IsFeasableTimeWindow      = isFeasableTimeWindow,
                CumulativeRouteStatistics = cumulativeRouteStatistics
            };

            return(result);
        }
Exemple #25
0
        /// <summary>
        /// Returns the <see cref="NodeTiming"/> for the next node
        /// </summary>
        /// <returns></returns>
        public virtual NodeTiming GetNodeTiming(INode startNode, INode endNode, TimeSpan currentNodeEndTime, RouteStatistics currentRouteStatistics)
        {
            var connection = GetNodeConnection(startNode, endNode);

            TimeSpan nextNodeArrivalTime = currentNodeEndTime + connection.RouteStatistics.TotalTime;
            TimeSpan nextNodeCompletionTime = endNode.RouteStops != null
                                                  ? nextNodeArrivalTime.Add(
                                                      endNode.RouteStops.FirstOrDefault().StopDelay.Value)
                                                  : nextNodeArrivalTime;

            bool isFirstStop = startNode is DriverNode;
            bool early = nextNodeArrivalTime < endNode.WindowStart;
            bool late = nextNodeArrivalTime > endNode.WindowEnd;

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

            if (early)
            {
                waitTime = endNode.WindowStart.Subtract(nextNodeArrivalTime);

                TimeSpan maxWaitTime = isFirstStop ? _configuration.MaximumWaitTimeBeforeStart : _configuration.MaximumWaitTimeAtStop;

                isFeasableTimeWindow = waitTime < maxWaitTime;

                if (isFirstStop && isFeasableTimeWindow)
                {
                    waitTime = TimeSpan.Zero;
                    currentNodeEndTime = endNode.WindowStart - connection.RouteStatistics.TotalTime;
                    nextNodeArrivalTime = currentNodeEndTime + connection.RouteStatistics.TotalTime;
                }
            }
            else if (late)
            {
                // we started past the time window
                isFeasableTimeWindow = false;
            }
            else
            {
                isFeasableTimeWindow = true;
            }


            var cumulatingCompletionTime = new TimeSpan(nextNodeCompletionTime.Ticks);
            if (isFeasableTimeWindow)
            {
                // make sure that the following subsequent route stops would not be violated                
                if (endNode is JobNode)
                {
                    var jn = endNode as JobNode;
                    
                    for (int i=1; i<jn.RouteStops.Count; i++)
                    {
                        var rs = jn.RouteStops[i];
                        var rsConnection = GetNodeConnection(
                            new JobNode() { RouteStops = new List<RouteStop>() { jn.RouteStops[i - 1] }, },
                            new JobNode() { RouteStops = new List<RouteStop>() { rs } });

                        var nextStopArrivalTime = cumulatingCompletionTime.Add(rsConnection.RouteStatistics.TotalTravelTime);
                        bool isWaitRequired = nextStopArrivalTime <= rs.WindowStart;

                        cumulatingCompletionTime = isWaitRequired
                               ? rs.WindowStart.Add(rs.StopDelay.Value)
                               : nextStopArrivalTime.Add(rs.StopDelay.Value);

                        for (int q=i; q < jn.RouteStops.Count; q++)
                        {
                            var nextStop = jn.RouteStops[q];
                            bool nextStopEarly = cumulatingCompletionTime < nextStop.WindowStart;
                            bool nextStopLate = cumulatingCompletionTime > nextStop.WindowEnd;

                            if (nextStopLate)
                            {
                                isFeasableTimeWindow = false;
                            }
                            else if (nextStopEarly)
                            {
                                // todo - check to see waiting time, driver limits
                            }
                        }
                    }
                }
            }

            TimeSpan nextNodeStartTime = nextNodeArrivalTime + waitTime;
            TimeSpan nextNodeEndTime = nextNodeStartTime + endNode.RouteStatistics.TotalTime;

            RouteStatistics localRouteStatistics = new RouteStatistics() {TotalWaitTime = waitTime};
            RouteStatistics cumulativeRouteStatistics = currentRouteStatistics + connection.RouteStatistics + endNode.RouteStatistics + localRouteStatistics;

            var result = new NodeTiming()
            {
                Node = endNode,
                DepartureTime = currentNodeEndTime,
                ArrivalTime = nextNodeArrivalTime,
                StartExecutionTime = nextNodeStartTime,
                EndExecutionTime = cumulatingCompletionTime,
                IsFeasableTimeWindow = isFeasableTimeWindow,
                CumulativeRouteStatistics = cumulativeRouteStatistics
            };

            return result;
        }
Exemple #26
0
 /// <summary>
 /// Returns the objective measure that we are minimizing
 /// </summary>
 /// <param name="routeStatistics"></param>
 /// <returns></returns>
 public double GetObjectiveMeasure(RouteStatistics routeStatistics)
 {
     //var priorityValue = Math.Pow(1, (double)routeStatistics.PriorityValue * 10000);
     //return (double)routeStatistics.TotalTravelDistance / priorityValue;
     return((double)routeStatistics.TotalTravelDistance);
 }
        public double GetObjectiveMeasure(RouteStatistics statistics)
        {
            var result = statistics.TotalTime.TotalSeconds + (1000000 * statistics.UnassignedJobs);

            return(result);
        }