Esempio n. 1
0
        public override Solution Run()
        {
            Log($"Assign a path for each train ... ", Utils.Logging.LogEventArgs.MessageType.Info, false);
            if (CurrentSolution.AssignPaths())
            {
                Log($"done.", Utils.Logging.LogEventArgs.MessageType.Success);
            }
            else
            {
                Log($"failed.", Utils.Logging.LogEventArgs.MessageType.Error);
            }

            // Only one iteration for this solver
            {
                Log(HorizontalLine);
                Log($"Loop on trains and assign entry-exit times ... ");
                var usedResources = new UsedResourceCollection();
                ScheduleTrains(CurrentProblem, CurrentSolution.TrainRunsDic.Values.OrderBy(tr => tr.Train.MinEntryEarliest), usedResources);

                var validation = CurrentSolution.Validate();
                if (CurrentSolution.IsAdmissible) // Only consider admissible solution
                {
                    Log($"Compute objective function ... ");
                    CurrentSolution.ComputeObjectiveFunction();
                    CompareWithBest(CurrentSolution);
                }
                else
                {
                    Log(validation);
                }
            }

            return(BestSolution);
        }
Esempio n. 2
0
        public override Solution Run()
        {
            do
            {
                // Assign path randomly
                CurrentSolution.AssignRandomPaths();

                // Simple Schedule
                BasicSchedule(CurrentSolution.TrainRuns.OrderBy(tr => tr.Train.MinEntryEarliest));

                // Detect conflicts
                var conflicts = CurrentSolution.GetConflicts();
                foreach (var c in conflicts)
                {
                    CurrentSolution.TrainRunsDic[c.Key].IsScheduled = false;
                }

                // Apply simple algorithm for trains with no conflicts
                var usedResources = new UsedResourceCollection();
                DummySolver.ScheduleTrains(CurrentProblem, CurrentSolution.TrainRuns.Where(tr => tr.IsScheduled).OrderBy(tr => tr.Train.MinEntryEarliest), usedResources);

                // Schedule conflicted trains
                DummySolver.ScheduleTrains(CurrentProblem, CurrentSolution.TrainRuns.Where(tr => !tr.IsScheduled).OrderBy(tr => tr.Train.MinEntryEarliest), usedResources);

                var validation = CurrentSolution.Validate();
                if (CurrentSolution.IsAdmissible) // Only consider admissible solution
                {
                    Log($"Compute objective function ... ");
                    CurrentSolution.ComputeObjectiveFunction();
                    CompareWithBest(CurrentSolution);
                }
                else
                {
                    Log(validation);
                }
            } while (++Iteration < MaxIteration && !BestSolution.IsOptimal);

            return(BestSolution);
        }
Esempio n. 3
0
        public static int ScheduleTrains(ProblemInstance problem, IEnumerable <TrainRun> trainRuns)
        {
            var nbConflicts   = 0;
            var usedResources = new UsedResourceCollection();

            foreach (var trainRun in trainRuns)
            {
                // ----------------------------------------------------
                //Log($"Delay train {trainRun.ServiceIntentionId} start ? ", Utils.Logging.LogEventArgs.MessageType.Info, false);
                var delay             = TimeSpan.Zero;
                var initialRunSection = trainRun.TrainRunSections[0];
                var initialSection    = problem.TryGetRouteSection(initialRunSection.Key);
                foreach (var resId in initialSection.ResourceIds)
                {
                    var resource = problem.TryGetResource(resId);
                    if (resource != null)
                    {
                        foreach (var usage in usedResources.UsageByOtherThan(resId, trainRun.ServiceIntentionId))
                        {
                            if (Math.Intersect(initialRunSection.EntryTime, initialRunSection.ExitTime + resource.ReleaseTime, usage.Item3, usage.Item4))
                            {
                                delay = Math.Max(delay, usage.Item4 - initialRunSection.EntryTime);
                            }
                        }
                    }
                }

                // Postpone train departure
                if (delay > TimeSpan.Zero)
                {
                    ++nbConflicts;
                    //Log($"Yes. Delay is {delay}");
                    initialRunSection.EntryTime += delay;
                    trainRun.ApplyDelay(delay);
                }

                //Log($"Check other sections for delays ... ");
                for (int k = 1; k < trainRun.TrainRunSections.Count; ++k)
                {
                    var runSection = trainRun.TrainRunSections[k];
                    var section    = problem.TryGetRouteSection(runSection.Key);

                    // Check resource occupation for next section
                    delay = TimeSpan.Zero;

                    foreach (var resId in section.ResourceIds)
                    {
                        var resource = problem.TryGetResource(resId);
                        if (resource != null)
                        {
                            foreach (var usage in usedResources.UsageByOtherThan(resId, trainRun.ServiceIntentionId))
                            {
                                if (Math.Intersect(runSection.EntryTime, runSection.ExitTime + resource.ReleaseTime, usage.Item3, usage.Item4))
                                {
                                    delay = Math.Max(delay, usage.Item4 - runSection.EntryTime);
                                }
                            }
                        }
                    }

                    if (delay > TimeSpan.Zero)
                    {
                        ++nbConflicts;
                        //Log($"Delay exit of train {trainRun.ServiceIntentionId}, from section {k-1} by {delay}");
                        trainRun.ApplyDelay(delay, k - 1);
                    }
                }

                // ----------------------------------------------------
                //Log($"Add current train resource occupation ... ");
                foreach (var runSection in trainRun.TrainRunSections)
                {
                    var section = problem.TryGetRouteSection(runSection.Key);

                    foreach (var resId in section.ResourceIds)
                    {
                        var resource = problem.TryGetResource(resId);
                        if (resource != null)
                        {
                            usedResources.Add(resId, trainRun.ServiceIntentionId, runSection.SequenceNumber,
                                              runSection.EntryTime, runSection.ExitTime + resource.ReleaseTime);
                        }
                    }
                }
            }

            return(nbConflicts);
        }
Esempio n. 4
0
        public static void ScheduleTrains(ProblemInstance problem, IEnumerable <TrainRun> trainRuns, UsedResourceCollection usedResources)
        {
            foreach (var trainRun in trainRuns)
            {
                // Schedule train accordingly
                for (int k = 0; k < trainRun.TrainRunSections.Count; ++k)
                {
                    var thisRunSection = trainRun.TrainRunSections[k];
                    var nextRunSection = (k < trainRun.TrainRunSections.Count - 1)
                  ? trainRun.TrainRunSections[k + 1]
                  : null;

                    var thisSection = problem.TryGetRouteSection(thisRunSection.Key);
                    var nextSection = problem.TryGetRouteSection(nextRunSection?.Key);

                    // ------------------------------------------------
                    // Is there a min entry/exit time
                    var thisRequirement = trainRun.Train.GetRequirement(thisSection.SectionMarker);
                    var nextRequirement = trainRun.Train.GetRequirement(nextSection?.SectionMarker);

                    // ------------------------------------------------
                    // Start time is always last exit time unless this is the first section
                    if (k > 0)
                    {
                        thisRunSection.EntryTime = trainRun.TrainRunSections[k - 1].ExitTime;
                    }
                    else
                    {
                        thisRunSection.EntryTime = Math.Max(thisRunSection.EntryTime, thisRequirement.minEntryTime);

                        // Check resource occupation
                        if (nextRunSection != null)
                        {
                            foreach (var resId in thisSection.ResourceIds)
                            {
                                foreach (var usage in usedResources.UsageByOtherThan(resId, trainRun.ServiceIntentionId))
                                {
                                    thisRunSection.EntryTime = Math.Max(thisRunSection.EntryTime, usage.Item4);
                                }
                            }
                        }
                    }

                    // ------------------------------------------------
                    // Set exit time, taking into acount resource occupation of next section
                    thisRunSection.ExitTime = Math.Max(thisRequirement.minExitTime,
                                                       thisRunSection.EntryTime + thisSection.MinimumRunningTime +
                                                       thisRequirement.minStoppingTime);

                    // Consider minEntryTime for next section
                    thisRunSection.ExitTime = Math.Max(thisRunSection.ExitTime, nextRequirement.minEntryTime);

                    // Check resource occupation
                    if (nextRunSection != null)
                    {
                        foreach (var resId in nextSection.ResourceIds)
                        {
                            foreach (var usage in usedResources.UsageByOtherThan(resId, trainRun.ServiceIntentionId))
                            {
                                thisRunSection.ExitTime = Math.Max(thisRunSection.ExitTime, usage.Item4);
                            }
                        }
                    }

                    // ------------------------------------------------
                    // Add current resource occupation
                    foreach (var resId in thisSection.ResourceIds)
                    {
                        var resource = problem.TryGetResource(resId);
                        if (resource != null)
                        {
                            usedResources.Add(resId, trainRun.ServiceIntentionId, thisRunSection.SequenceNumber,
                                              thisRunSection.EntryTime, thisRunSection.ExitTime + resource.ReleaseTime);
                        }
                    }
                }
            }
        }