/// <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.EarliestStartTimeSpan; var cumulativeRouteStatistics = new RouteStatistics(); var allNodes = nodeRouteSolution.AllNodes; for (int i = 0; i < allNodes.Count - 1; i++) { var nodeTiming = _routeStatisticsService.GetNodeTiming(allNodes[i], allNodes[i + 1], currentNodeEndTime, cumulativeRouteStatistics); var previousNode = i > 0 ? allNodes[i - 1] : null; if (nodeTiming.IsFeasableTimeWindow) { // is it a feasable route var lastConnection = _nodeService.GetNodeConnection(nodeTiming.Node, driverNode); var lastLeg = _routeStatisticsService.GetRouteStatistics(lastConnection, nodeTiming.EndExecutionTime, previousNode); var finalRouteStatistics = nodeTiming.CumulativeRouteStatistics + lastLeg; if (_routeExitFunction.ExeedsExitCriteria(finalRouteStatistics, driverNode.Driver)) { return(false); } } else { return(false); } currentNodeEndTime = nodeTiming.EndExecutionTime; cumulativeRouteStatistics = nodeTiming.CumulativeRouteStatistics; } return(true); }
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); }