Beispiel #1
0
        public void MapModelToDomain(Plan planModel, Domain.Planning.Plan plan)
        {
            // create map so we have reference to same route stop
            var routeStopMap = new Dictionary <RouteStop, Domain.Orders.RouteStop>();

            foreach (var driverPlanModel in planModel.DriverPlans)
            {
                PlanDriver planDriver = null;

                try
                {
                    if (driverPlanModel.Id > 0)
                    {
                        planDriver = plan.DriverPlans.FirstOrDefault(f => f.Id == driverPlanModel.Id);
                    }

                    if (planDriver == null)
                    {
                        planDriver = new PlanDriver
                        {
                            DriverId = driverPlanModel.Driver.Id
                        };

                        plan.DriverPlans.Add(planDriver);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    continue;
                }
                // RouteSegmentMetrics persistance disabled - transaction overhead exceeds realtime computation delay

                // Metrics
                planDriver.RouteSegmentMetrics.Clear();
                int routeSegmentStatIndex = 0;
                foreach (var routeSegmentStatModel in driverPlanModel.RouteSegmentStatistics)
                {
                    var startStop = GetOrCreateDomainRouteStop(routeStopMap, routeSegmentStatModel.StartStop);
                    var endStop   = GetOrCreateDomainRouteStop(routeStopMap, routeSegmentStatModel.EndStop);

                    int?jobId = null;
                    if (startStop.JobId.HasValue && startStop.JobId > 0)
                    {
                        jobId = startStop.JobId;
                    }
                    if (endStop.JobId.HasValue && endStop.JobId > 0)
                    {
                        jobId = endStop.JobId;  // prefer the job id of the end stop
                    }

                    var routeSegmentMetric = new RouteSegmentMetric()
                    {
                        JobId               = jobId,
                        StartStopId         = startStop.LocationId,
                        EndStopId           = endStop.LocationId,
                        StartStop           = startStop,
                        EndStop             = endStop,
                        PlanDriver          = planDriver,
                        StartTime           = routeSegmentStatModel.StartTime.Ticks,
                        TotalExecutionTime  = routeSegmentStatModel.Statistics.TotalExecutionTime.Ticks,
                        TotalTravelDistance = routeSegmentStatModel.Statistics.TotalTravelDistance,
                        TotalTravelTime     = routeSegmentStatModel.Statistics.TotalTravelTime.Ticks,
                        TotalIdleTime       = routeSegmentStatModel.Statistics.TotalIdleTime.Ticks,
                        TotalQueueTime      = routeSegmentStatModel.Statistics.TotalQueueTime.Ticks,
                        TruckState          = (TruckState)routeSegmentStatModel.TruckState,
                        SortOrder           = routeSegmentStatIndex++,
                    };

                    planDriver.RouteSegmentMetrics.Add(routeSegmentMetric);
                }

                // Update job plans
                int jobIndex = 0;
                foreach (var jobPlanModel in driverPlanModel.JobPlans)
                {
                    var planDriverJob = planDriver.JobPlans.FirstOrDefault(jp => jp.JobId == jobPlanModel.Job.Id);

                    if (planDriverJob == null)
                    {
                        planDriverJob = new PlanDriverJob()
                        {
                            JobId         = jobPlanModel.Job.Id,
                            SortOrder     = jobIndex,
                            DepartureTime = jobPlanModel.DepartureTime
                        };

                        planDriver.JobPlans.Add(planDriverJob);
                    }
                    else
                    {
                        if (planDriverJob.SortOrder != jobIndex)
                        {
                            planDriverJob.SortOrder = jobIndex;
                        }
                    }

                    jobIndex++;
                }

                // remove extra job plans
                var jobPlansToRemove = planDriver.JobPlans.Where(jp => driverPlanModel.JobPlans.All(f => f.Id != jp.Id)).ToList();
                foreach (var jp in jobPlansToRemove)
                {
                    planDriver.JobPlans.Remove(jp);
                }
            }

            foreach (var unassignedJob in planModel.UnassignedJobs)
            {
                var job = _jobService.GetById(unassignedJob.Id);
                plan.UnassignedJobs.Add(job);
            }
        }
Beispiel #2
0
        public PlanGenerationResult GeneratePlan(PlanConfig planConfig)
        {
            if (planConfig == null)
            {
                throw new ArgumentNullException("planConfig");
            }

            PlanGenerationResult result;

            try
            {
                var runNumber = _planService.Select().Count(f => f.PlanConfig.Id == planConfig.Id);

                // select placeholder driver
                var placeholderDriverEntity = _driverService.Select().FirstOrDefault(f => f.IsPlaceholderDriver);

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

                var optimizerSettings = _settingsConfigurationProvider.Settings;

                // Prefetch and stuff
                foreach (var planGeneratorInitializer in _planGeneratorInitializers)
                {
                    planGeneratorInitializer.Initialize(planConfig);
                }

                // Domain Model > Optimization Model
                var planConfigModel = _mapperService.MapDomainToModel(planConfig);

                // set placeholder driver earliest start time
                placeholderDriver.EarliestStartTime = planConfig.JobGroup.ShiftStartTime.HasValue
                    ? planConfig.JobGroup.ShiftStartTime.Value.Ticks
                    : 0;

                // Run Optimization
                var planModel = _planGenerator.GeneratePlan(planConfigModel, placeholderDriver, optimizerSettings);

                var driverIds           = planModel.DriverPlans.Select(p => p.Driver.Id).ToList();
                var driversWithoutPlans = planConfigModel.Drivers.Where(p => !driverIds.Contains(p.Id));
                foreach (var d in driversWithoutPlans)
                {
                    planModel.DriverPlans.Add(new PlanDriver()
                    {
                        Driver   = d,
                        JobPlans = new List <PlanDriverJob>(),
                        RouteSegmentStatistics = new List <RouteSegmentStatistics>()
                    });
                }

                if (planModel.UnassignedJobs.Any())
                {
                    var unassignablePlan = new PlanDriver()
                    {
                        Driver   = placeholderDriver,
                        JobPlans = new List <PlanDriverJob>(),
                        RouteSegmentStatistics = new List <RouteSegmentStatistics>()
                    };

                    foreach (var j in planModel.UnassignedJobs)
                    {
                        unassignablePlan.JobPlans.Add(
                            new PlanDriverJob()
                        {
                            Job        = j,
                            RouteStops = j.RouteStops.ToList()
                        });
                    }

                    planModel.DriverPlans.Add(unassignablePlan);
                }

                // Optimization Model > Domain Model
                var plan  = CreateDomainPlan(planConfig, planModel, runNumber, false);
                var plan2 = CreateDomainPlan(planConfig, planModel, runNumber, true);

                result = new PlanGenerationResult()
                {
                    Success = true,
                    Plan    = plan
                };
            }
            catch (Exception ex)
            {
                result = new PlanGenerationResult()
                {
                    Success = false,
                    Errors  = new string[] { ex.Message }
                };

                throw;
            }

            return(result);
        }