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