// as per http://blog.kulman.sk/generating-all-permutations-of-a-list-how-hard-can-that-be/
        private static IEnumerable <IEnumerable <T> > Permutation <T>(System.Collections.Generic.ICollection <T> input)
        {
            if (input == null || !input.Any())
            {
                yield break;
            }
            if (input.Count() == 1)
            {
                yield return(input);
            }

            foreach (var item in input)
            {
                var next = input.Where(l => !l.Equals(item)).ToList();
                foreach (var perm in Permutation(next))
                {
                    var ret = new System.Collections.Generic.List <T> {
                        item
                    }.Concat(perm);
                    yield return(ret);
                }
            }
        }
        public TramStatistics Start(int turnAroundTime,
                                    int peakFrequency,
                                    int numberOfTrams,
                                    int latenessThreshold = 60,
                                    bool debug            = false,
                                    IEnumerable <InputRow> stationFrequencies = null)
        {
            LatenessThreshold = latenessThreshold;

            Track = new Terrain(peakFrequency, turnAroundTime, SWITCH_DELAY, stationFrequencies);
            DEBUG = debug;

            TurnaroundTime   = turnAroundTime;
            InitialTrams     = numberOfTrams;
            CurrentFrequency = numberOfTrams;

            TramArrived   += HandleArrival;
            TramDeparture += HandleDeparture;

            TramExpectedArrival   += HandleExpectedArrival;
            TramExpectedDeparture += HandleExpectedDeparture;

            // initialize trams to depot
            for (var i = 0; i < InitialTrams; i++)
            {
                Trams.Add(new Tram
                {
                    Id             = i,
                    CurrentStation = Track.GetPRDepot()
                });
            }

            var pr        = Track.GetPR().Timetable;
            var tramDelay = 0;

            foreach (var nextTram in Trams.Where(x => x.CurrentStation == Track.GetPRDepot()))
            {
                EventQueue.Add(new TransportArgs
                {
                    FromStation = Track.GetPRDepot(),
                    ToStation   = Track.NextStation(Track.GetPRDepot()),
                    Tram        = nextTram,
                    Type        = TransportArgsType.ExpectedArrival,
                    TriggerTime = tramDelay
                                  //normally + part is 0 as its from depot
                });
                tramDelay = Track.GetPR().Timetable.GetNextDepartureTime(tramDelay + 1).Value;
            }

            while (!EventQueue.IsEmpty)
            {
                ///next event
                var next = EventQueue.Min();

                //remove from top
                EventQueue.DeleteMin();

                //used for debug info
                if (DEBUG)
                {
                    WriteState(this, string.Concat($"[{next.TriggerTime}]", BuildState()));
                    DebugLine(this, next);
                }

                if (next.Type == TransportArgsType.ExpectedArrival)
                {
                    TramExpectedArrival(this, next);
                }

                if (next.Type == TransportArgsType.ExpectedDeparture)
                {
                    TramExpectedDeparture(this, next);
                }

                if (next.Type == TransportArgsType.Arrival)
                {
                    TramArrived(this, next);
                }

                if (next.Type == TransportArgsType.Departure)
                {
                    TramDeparture(this, next);
                }
            }

            var totalServedInDay = 0;

            // total served is serviced with every tram
            foreach (var tram in Track.Vertices)
            {
                totalServedInDay += tram.TotalPassengersServiced;
            }

            // return output statistics for the output analysis
            return(new TramStatistics()
            {
                TotalPassengersServiced = totalServedInDay,

                Punctuality = TotalPunctuality,

                TotalDelay = TotalDelay,

                HighLatenessTrams = Trams.Count(x => x.WasLate),

                TotalAverageWaitingTime = Track.Vertices
                                          .Where(wait => wait.TotalPassengersServiced != 0)
                                          .Sum(wait => (double)wait.TotalWaitingTime / wait.TotalPassengersServiced),

                MaximumDepartureLateness = MaxDepartureLateness
            });
        }
Exemple #3
0
        /// <summary>
        /// Determines if contents of both lists are equal ignoring their order.
        /// <locDE><para />Ermittelt ob die beiden Listen den gleichen Inhalt haben (ohne Rücksicht auf die Reihenfolge).</locDE>
        /// </summary>
        /// <typeparam name="T">The element type of the lists.<locDE><para />Elementtyp der Listen.</locDE></typeparam>
        /// <param name="list1">The first list.<locDE><para />Erste Liste.</locDE></param>
        /// <param name="list2">The second list.<locDE><para />Zweite Liste.</locDE></param>
        /// <param name="diff">The found difference between the collections (if any).<locDE><para />Gefundene Unterschiede (falls nicht gleich).</locDE></param>
        /// <returns>True if equal.<locDE><para />True falls identisch.</locDE></returns>
        public static bool EqualContentsIgnoreOrder <T>(this System.Collections.Generic.IEnumerable <T> list1, System.Collections.Generic.IEnumerable <T> list2,
                                                        out System.Collections.Generic.ICollection <T> diff)
        {
            var listType            = typeof(System.Collections.Generic.List <>);
            var constructedListType = listType.MakeGenericType(typeof(T));

            diff = Activator.CreateInstance(constructedListType) as System.Collections.Generic.ICollection <T>;

            #region Handle list(s) being null

            if (null == list1 && null == list2)
            {
                return(true);
            }
            if (null == list1 && null != list2)
            {
                foreach (T s in list2)
                {
                    diff.Add(s);
                }
                return(false);
            }
            if (null != list1 && null == list2)
            {
                foreach (T s in list1)
                {
                    diff.Add(s);
                }
                return(false);
            }

            #endregion Handle list(s) being null

            // https://stackoverflow.com/questions/3669970/compare-two-listt-objects-for-equality-ignoring-order

            var cnt = new System.Collections.Generic.Dictionary <T, int>();
            foreach (T s in list1)
            {
                if (cnt.ContainsKey(s))
                {
                    cnt[s]++;
                }
                else
                {
                    cnt.Add(s, 1);
                }
            }
            foreach (T s in list2)
            {
                if (cnt.ContainsKey(s))
                {
                    cnt[s]--;
                }
                else
                {
                    diff.Add(s);
                }
            }
            //diff.Union(cnt.Where(x => x.Value != 0).Select(x => x.Key));
            System.Collections.Generic.IEnumerable <T> cntsNotZero = cnt.Where(x => x.Value != 0).Select(x => x.Key);
            if (null != cntsNotZero)
            {
                foreach (T cntNoZero in cntsNotZero)
                {
                    diff.AddIfNotContains(cntNoZero);
                }
            }
            return(0 == diff.Count());
        }