Tuple<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>, Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> UpdateCompatibleListOfTimeLine(Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> CurrentCompatibleList, List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> MovedOverSet, TimeLine ReferenceTimeLine, TimeSpanWithStringID LeftOuts, Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> TotalOfMovedVariables) { //Hack alert: You need to create a situation that enforces a restricted event as being assigned first TimeSpan CurrentTotalOfSnugVariables = new TimeSpan(0); Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> retValue_MovedVariables = new Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>(); Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> retValue_CurrentCompatibleList = new Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>(); Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> CurrentCompatibleList_Cpy = SnugArray.CreateCopyOFSnuPossibilities(CurrentCompatibleList); //TimeSpan SumOfLeftOuts= new TimeSpan(0); TimeSpan RemainderTimeSpan = new TimeSpan(0); Dictionary<string, mTuple<int, TimeSpanWithStringID>> MovedOverListUpdate = new System.Collections.Generic.Dictionary<string, mTuple<int, TimeSpanWithStringID>>(); if (LeftOuts.timeSpan > ReferenceTimeLine.TimelineSpan) { return null; } CurrentTotalOfSnugVariables = SnugArray.TotalTimeSpanOfSnugPossibility(CurrentCompatibleList_Cpy); RemainderTimeSpan = ReferenceTimeLine.TimelineSpan - CurrentTotalOfSnugVariables; TimeSpan RemainderOfLeftOverChunk = LeftOuts.timeSpan - RemainderTimeSpan; List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> MovedOverSet_Cpy = new System.Collections.Generic.List<System.Collections.Generic.Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>(); foreach (Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> eachDictionary in MovedOverSet) { MovedOverSet_Cpy.Add(compareMovedOverSetWithTotalPossibleEntries(eachDictionary, TotalOfMovedVariables)); } while (RemainderOfLeftOverChunk.Ticks < 0) { ReferenceTimeLine = new TimeLine(ReferenceTimeLine.Start, ReferenceTimeLine.End - LeftOuts.timeSpan); RemainderOfLeftOverChunk = LeftOuts.timeSpan - RemainderTimeSpan; } SnugArray FitsInChunkOfRemainder_SnugArray = new SnugArray(CurrentCompatibleList_Cpy.Values.ToList(), RemainderOfLeftOverChunk); List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> SnugPossibilities = FitsInChunkOfRemainder_SnugArray.MySnugPossibleEntries; Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> Viable_SnugPossibilities = getPlausibleEntriesFromMovedOverSet(MovedOverSet_Cpy, SnugPossibilities); Dictionary<Dictionary<string, mTuple<int, TimeSpanWithStringID>>, List<Dictionary<string, mTuple<int, TimeSpanWithStringID>>>> LeftAfterRemovalSnugPossibilities = new System.Collections.Generic.Dictionary<System.Collections.Generic.Dictionary<string, mTuple<int, TimeSpanWithStringID>>, System.Collections.Generic.List<System.Collections.Generic.Dictionary<string, mTuple<int, TimeSpanWithStringID>>>>(); Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> BestSnugPossibility = Viable_SnugPossibilities; retValue_MovedVariables = SnugArray.AddToSnugPossibilityList(retValue_MovedVariables, BestSnugPossibility); Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> CurrentCompatibleList_Cpy_updated = SnugArray.RemoveSnugPossibilityFromAnother(CurrentCompatibleList_Cpy, BestSnugPossibility); retValue_CurrentCompatibleList = SnugArray.RemoveSnugPossibilityFromAnother(CurrentCompatibleList, retValue_MovedVariables); //retValue_CurrentCompatibleList = SnugArray.AddToSnugPossibilityList(CurrentCompatibleList, MovedOverListUpdate); Tuple<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>, Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> retValue = new Tuple<Dictionary<TimeSpan,mTuple<int,TimeSpanWithStringID>>,Dictionary<TimeSpan,mTuple<int,TimeSpanWithStringID>>>(retValue_CurrentCompatibleList, retValue_MovedVariables); //item1 is Updated CurrentCompatible List //item2 is Best Snug change to timeLine return retValue; }
public static Dictionary<int, List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>> SortListSnugPossibilities_basedOnNumberOfDiffering(List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> ListOfSnugPossibilities, TimeSpanWithStringID myTimesSpan = null) { Dictionary<int, List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>> retValue = new Dictionary<int, List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>>(); foreach (Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> eachDictionary in ListOfSnugPossibilities) { if (retValue.ContainsKey(eachDictionary.Count)) { retValue[eachDictionary.Count].Add(eachDictionary); } else { retValue.Add(eachDictionary.Count, new List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> { eachDictionary }); } } Parallel.ForEach(retValue.Values, currentList => { currentList=SortListSnugPossibilities_basedOnTimeSpan(currentList); }); return retValue; }
List<mTuple<bool, SubCalendarEvent>> FurtherFillTimeLineWithSubCalEvents(List<mTuple<bool, SubCalendarEvent>> AllReadyAssignedSubCalEvents, TimeLine ReferenceTimeLine, Dictionary<TimeLine, Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> AllCompatibleWithList, TimeLine PreceedingTimeLine, Dictionary<TimeLine, Dictionary<TimeSpan, Dictionary<string, mTuple<bool, SubCalendarEvent>>>> PossibleEntries) { /* * CompatibleWithList has whats left after stitchUnRestrictedSubCalendarEvent has removed all possible fittable Events * Hack Alert: The current implementation does not optimize for restricted values */ List<SubCalendarEvent> AssignedSubCalendarEvents = new System.Collections.Generic.List<SubCalendarEvent>(); foreach (mTuple<bool, SubCalendarEvent> eachmTuple in AllReadyAssignedSubCalEvents) { AssignedSubCalendarEvents.Add(eachmTuple.Item2); } List<TimeSpanWithStringID> LeftOvers = new System.Collections.Generic.List<TimeSpanWithStringID>(); foreach (KeyValuePair<TimeSpan, mTuple<int, TimeSpanWithStringID>> eachKeyValuePair in AllCompatibleWithList[PreceedingTimeLine]) { if (eachKeyValuePair.Value.Item1 > 0) { LeftOvers.Add(eachKeyValuePair.Value.Item2); } } PreceedingTimeLine.Empty(); TimeLine UpdatedTImeLine = Utility.AddSubCaleventsToTimeLine(PreceedingTimeLine, AssignedSubCalendarEvents); PreceedingTimeLine.AddBusySlots(UpdatedTImeLine.OccupiedSlots); List<TimeLine> AllFreeSpots = PreceedingTimeLine.getAllFreeSlots().ToList(); Dictionary<TimeLine, List<mTuple<bool, SubCalendarEvent>>> matchingValidSubcalendarEvents = new System.Collections.Generic.Dictionary<TimeLine, System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>>();//Dictionary contains a match up of the free within already assigned variables and possible fillers Dictionary<TimeLine, Dictionary<string, mTuple<int, TimeSpanWithStringID>>> ForSnugArray = new System.Collections.Generic.Dictionary<TimeLine, System.Collections.Generic.Dictionary<string, mTuple<int, TimeSpanWithStringID>>>(); Dictionary<TimeLine, SnugArray> FreeSpotSnugArrays = new System.Collections.Generic.Dictionary<TimeLine, SnugArray>(); Dictionary<TimeLine, List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>> FreeSpotSnugPossibiilities = new System.Collections.Generic.Dictionary<TimeLine, System.Collections.Generic.List<System.Collections.Generic.Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>>(); //Dictionary<TimeLine, List<TimeSpanWithStringID>> FreeSpotSnugPossibilities = new System.Collections.Generic.Dictionary<TimeLine, SnugArray>(); Dictionary<string, SubCalendarEvent> AllMovableSubCalEvents = new System.Collections.Generic.Dictionary<string, SubCalendarEvent>(); List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> AllMoveOvrSet = new System.Collections.Generic.List<System.Collections.Generic.Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>(); // Dictionary<string, Dictionary<SubCalendarEvent, List<TimeLine>>> SubEventToMatchingTimeLinePossible = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.Dictionary<SubCalendarEvent, System.Collections.Generic.List<TimeLine>>>(); Dictionary<TimeLine, Dictionary<TimeSpan, List<mTuple<bool, SubCalendarEvent>>>> TimeLine_WithMathChingSubCalevents = new Dictionary<TimeLine, Dictionary<TimeSpan, List<mTuple<bool, SubCalendarEvent>>>>();// string in second dictionary is the String of the duration of the SubCalendarEvent Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> TotalPossibleTimeSpanWithStrings = new System.Collections.Generic.Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>(); foreach (TimeLine eachTimeLine in AllFreeSpots) { List<mTuple<bool, SubCalendarEvent>> PossibleFillers = removeSubCalEventsThatCantWorkWithTimeLine(eachTimeLine, PossibleEntries[PreceedingTimeLine].ToList(), true);//hack we need to ensure cases of partial fit ForSnugArray.Add(eachTimeLine, new System.Collections.Generic.Dictionary<string, mTuple<int, TimeSpanWithStringID>>()); TimeLine_WithMathChingSubCalevents.Add(eachTimeLine, new System.Collections.Generic.Dictionary<TimeSpan, System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>>()); foreach (mTuple<bool, SubCalendarEvent> eachmTuple in PossibleFillers) { if (ForSnugArray[eachTimeLine].ContainsKey(eachmTuple.Item2.ActiveDuration.ToString())) { ++ForSnugArray[eachTimeLine][eachmTuple.Item2.ActiveDuration.ToString()].Item1; } else { ForSnugArray[eachTimeLine].Add(eachmTuple.Item2.ActiveDuration.ToString(), new mTuple<int, TimeSpanWithStringID>(1, new TimeSpanWithStringID(eachmTuple.Item2.ActiveDuration, eachmTuple.Item2.ActiveDuration.ToString()))); } if (!AllMovableSubCalEvents.ContainsKey(eachmTuple.Item2.ID))//populates all movable SubCalendarEVents { AllMovableSubCalEvents.Add(eachmTuple.Item2.ID, eachmTuple.Item2); if (TotalPossibleTimeSpanWithStrings.ContainsKey(eachmTuple.Item2.ActiveDuration)) { ++TotalPossibleTimeSpanWithStrings[eachmTuple.Item2.ActiveDuration].Item1; } else { TotalPossibleTimeSpanWithStrings.Add(eachmTuple.Item2.ActiveDuration, new mTuple<int, TimeSpanWithStringID>(1, new TimeSpanWithStringID(eachmTuple.Item2.ActiveDuration, eachmTuple.Item2.ActiveDuration.ToString()))); } } TimeSpan IdTimeSpan = eachmTuple.Item2.ActiveDuration; if (TimeLine_WithMathChingSubCalevents[eachTimeLine].ContainsKey(IdTimeSpan)) { TimeLine_WithMathChingSubCalevents[eachTimeLine][IdTimeSpan].Add(eachmTuple); } else { TimeLine_WithMathChingSubCalevents[eachTimeLine].Add(IdTimeSpan, new System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>() { eachmTuple }); } /*if (SubEventToMatchingTimeLinePossible.ContainsKey(eachmTuple.Item2.ActiveDuration.ToString()))// builds a dictionary of the TimeSpan String ID and a Dictionary of SubCalendar EVents with a List of feasible TimeLine { if (SubEventToMatchingTimeLinePossible[eachmTuple.Item2.ActiveDuration.ToString()].ContainsKey(eachmTuple.Item2)) { SubEventToMatchingTimeLinePossible[eachmTuple.Item2.ActiveDuration.ToString()][eachmTuple.Item2].Add(eachTimeLine); } else { SubEventToMatchingTimeLinePossible[eachmTuple.Item2.ActiveDuration.ToString()].Add(eachmTuple.Item2, new System.Collections.Generic.List<TimeLine>() { eachTimeLine }); } } else { SubEventToMatchingTimeLinePossible.Add(eachmTuple.Item2.ActiveDuration.ToString(), new System.Collections.Generic.Dictionary<SubCalendarEvent, System.Collections.Generic.List<TimeLine>>()); SubEventToMatchingTimeLinePossible[eachmTuple.Item2.ActiveDuration.ToString()].Add(eachmTuple.Item2, new System.Collections.Generic.List<TimeLine>() { eachTimeLine }); }*/ } matchingValidSubcalendarEvents.Add(eachTimeLine, PossibleFillers); } foreach (TimeLine eachTimeLine in AllFreeSpots) { FreeSpotSnugArrays.Add(eachTimeLine, new SnugArray(ForSnugArray[eachTimeLine].Values.ToList(), eachTimeLine.TimelineSpan)); } foreach (TimeLine eachTimeLine in AllFreeSpots) { FreeSpotSnugPossibiilities.Add(eachTimeLine, FreeSpotSnugArrays[eachTimeLine].MySnugPossibleEntries); } foreach (List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> allFreeSpotSnugPossibiilities in FreeSpotSnugPossibiilities.Values) { AllMoveOvrSet.AddRange(allFreeSpotSnugPossibiilities); } TimeSpanWithStringID UnAssignedTimeSpanWithString = new TimeSpanWithStringID(ReferenceTimeLine.TimelineSpan, ReferenceTimeLine.TimelineSpan.ToString()); /*if (LeftOvers.Count > 0) { UnAssignedTimeSpanWithString = LeftOvers[0]; }*/ TimeSpan TotalMovedSofar = new TimeSpan(0); Dictionary<TimeLine, List<mTuple<bool, SubCalendarEvent>>> FreeSpots_MatchedEvents = new System.Collections.Generic.Dictionary<TimeLine, System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>>(); Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> CompatibleListForReferenceTimeLine = AllCompatibleWithList[ReferenceTimeLine]; foreach (TimeLine eachTimeLine in AllFreeSpots) { FreeSpots_MatchedEvents.Add(eachTimeLine, new System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>()); Tuple<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>, Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> UpdatedCompatibleList_BestSnugPossibility = UpdateCompatibleListOfTimeLine(CompatibleListForReferenceTimeLine, FreeSpotSnugPossibiilities[eachTimeLine], ReferenceTimeLine, UnAssignedTimeSpanWithString, TotalPossibleTimeSpanWithStrings); Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> UpdatedCompatibleList = UpdatedCompatibleList_BestSnugPossibility.Item1; Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> BestSnugAvailability = UpdatedCompatibleList_BestSnugPossibility.Item2; TotalMovedSofar += SnugArray.TotalTimeSpanOfSnugPossibility(BestSnugAvailability); Dictionary<TimeSpan, List<mTuple<bool, SubCalendarEvent>>> TimeLineMatchingSubEvents = TimeLine_WithMathChingSubCalevents[eachTimeLine]; foreach (KeyValuePair<TimeSpan, mTuple<int, TimeSpanWithStringID>> eachKeyValuePair in BestSnugAvailability) { if (TimeLineMatchingSubEvents[eachKeyValuePair.Key].Count > 0) { FreeSpots_MatchedEvents[eachTimeLine].Add(TimeLineMatchingSubEvents[eachKeyValuePair.Key][0]); TimeLineMatchingSubEvents[eachKeyValuePair.Key].RemoveAt(0); --TotalPossibleTimeSpanWithStrings[eachKeyValuePair.Key].Item1; if (TotalPossibleTimeSpanWithStrings[eachKeyValuePair.Key].Item1 == 0) { TotalPossibleTimeSpanWithStrings.Remove(eachKeyValuePair.Key); } } else { ; } } //KeyValuePair<string, mTuple<int, TimeSpanWithStringID>> eachKeyValuePair List<TimeSpan> AllKeys = CompatibleListForReferenceTimeLine.Keys.ToList(); foreach (TimeSpan eachTimeSpan in AllKeys)//Updates the Compatible List of the Reference timelin, in order to reflect movement in data { if (UpdatedCompatibleList.ContainsKey(eachTimeSpan))//checks if reference timeLine has updated keys { CompatibleListForReferenceTimeLine[eachTimeSpan] = UpdatedCompatibleList[eachTimeSpan]; } else { CompatibleListForReferenceTimeLine.Remove(eachTimeSpan); } } } TimeSpan FreeSpaceAfterMovement = ReferenceTimeLine.TimelineSpan - SnugArray.TotalTimeSpanOfSnugPossibility(CompatibleListForReferenceTimeLine); if (LeftOvers.Count > 0)//checks if there are move overs from preceeding compatible TimeLine { SnugArray BestFitIntoCurrentTimeLine = new SnugArray(AllCompatibleWithList[PreceedingTimeLine].Values.ToList(), FreeSpaceAfterMovement);//Tries to construct tightest fit on newly created free space in reference timelin....hack alert, it does not prioritize restricted elements List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> SortedData = BestFitIntoCurrentTimeLine.MySnugPossibleEntries;//sort the snug possibility based on mst filling if (SortedData.Count > 0) { Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> selectedDictionary = SortedData[SortedData.Count - 1]; foreach (KeyValuePair<TimeSpan, mTuple<int, TimeSpanWithStringID>> eachKeyValuePair in selectedDictionary) { if (CompatibleListForReferenceTimeLine.ContainsKey(eachKeyValuePair.Key)) { CompatibleListForReferenceTimeLine[eachKeyValuePair.Key].Item1 += eachKeyValuePair.Value.Item1; AllCompatibleWithList[PreceedingTimeLine][eachKeyValuePair.Key].Item1 -= eachKeyValuePair.Value.Item1; } else { CompatibleListForReferenceTimeLine.Add(eachKeyValuePair.Key, eachKeyValuePair.Value); AllCompatibleWithList[PreceedingTimeLine][eachKeyValuePair.Key].Item1 -= eachKeyValuePair.Value.Item1; } if (AllCompatibleWithList[PreceedingTimeLine][eachKeyValuePair.Key].Item1 < 0) { ; } } } } List<mTuple<bool, SubCalendarEvent>> retValue = new System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>(AllReadyAssignedSubCalEvents); foreach (TimeLine eachTimeLine in AllFreeSpots)//Snaps each Subcalevent to the beginning of a free TimeLine { List<SubCalendarEvent> ListOfSubCalEvents = Utility.mTupleToSubCalEvents(FreeSpots_MatchedEvents[eachTimeLine]); if (Utility.PinSubEventsToStart(ListOfSubCalEvents, eachTimeLine)) { retValue.AddRange(FreeSpots_MatchedEvents[eachTimeLine]); } else { ; } } return retValue; }
public static List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> SortListSnugPossibilities_basedOnTimeSpan(List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> ListOfSnugPossibilities, TimeSpanWithStringID myTimesSpan = null) { Dictionary<TimeSpan, List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>> AllData = new Dictionary<TimeSpan, List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>>(); Dictionary<TimeSpan, List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>> AllData_AboveAverage = new Dictionary<TimeSpan, List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>>(); Dictionary<TimeSpan, List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>> PertinentDict; foreach (Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> eachDictionary in ListOfSnugPossibilities) { TimeSpan TotalTime= TotalTimeSpanOfSnugPossibility(eachDictionary); if (myTimesSpan != null) { if (TotalTime >= myTimesSpan.timeSpan) { if (AllData_AboveAverage.ContainsKey(TotalTime)) { AllData_AboveAverage[TotalTime].Add(eachDictionary); } else { AllData_AboveAverage.Add(TotalTime, new List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>() { eachDictionary }); } } } if (AllData.ContainsKey(TotalTime)) { AllData[TotalTime].Add(eachDictionary); } else { AllData.Add(TotalTime, new List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>() { eachDictionary }); } } PertinentDict = AllData_AboveAverage.Count > 0 ? AllData_AboveAverage : AllData; List<TimeSpan> AllKeys; AllKeys = PertinentDict.Keys.ToList(); AllKeys.Sort(); if (AllData_AboveAverage.Count > 0) { IEnumerable<KeyValuePair<TimeSpan, List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>>> dict_asList = AllData_AboveAverage; dict_asList.OrderBy(obj => obj.Value.Count); AllKeys = dict_asList.Select(obj => obj.Key).ToList(); AllKeys.Reverse(); } List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>> retValue = new List<Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>>>(); foreach (TimeSpan eachTimeSpan in AllKeys) { PertinentDict[eachTimeSpan] = PertinentDict[eachTimeSpan].OrderBy(obj => obj.Count).ToList(); retValue.AddRange(AllData[eachTimeSpan]); } return retValue; }