// 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 }); }
/// <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()); }