public IEnumerable <(string trainId, int sectionId, DateTime start, DateTime end)> TryAdd(string resId, string trainId, int sequenceNumber, DateTime entry, DateTime exit)
        {
            if (!_container.ContainsKey(resId))
            {
                _container.Add(resId, new Dictionary <string, Dictionary <int, Tuple <DateTime, DateTime> > >());
            }

            if (!_container[resId].ContainsKey(trainId))
            {
                _container[resId].Add(trainId, new Dictionary <int, Tuple <DateTime, DateTime> >());
            }

            // Look for conflicts
            foreach (var collection in _container[resId].Where(kvp => kvp.Key != trainId))
            {
                foreach (var keyVal in collection.Value)
                {
                    if (Math.Intersect(entry, exit, keyVal.Value.Item1, keyVal.Value.Item2))
                    {
                        yield return(collection.Key, keyVal.Key, keyVal.Value.Item1, keyVal.Value.Item2);  // Means this period intersect an existing one
                    }
                }
            }

            _container[resId][trainId][sequenceNumber] = new Tuple <DateTime, DateTime>(entry, exit);
        }
Example #2
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);
        }