public ClumpSubCalendarEvent(List<SubCalendarEvent> Appendables, TimeLine BoundaryTimeLine) { Appendables=Appendables.OrderBy(obj => obj.getCalendarEventRange.End).ToList(); SubCalendarEvent RelativeSubEvent = Appendables[0]; Appendables.Remove(RelativeSubEvent); ClumpSubCalendarEvent myThis = new ClumpSubCalendarEvent(RelativeSubEvent, Appendables, BoundaryTimeLine.CreateCopy()); SubCalEventsOverLapWithBase = myThis.SubCalEventsOverLapWithBase; //List<SubCalendarEvent> NonOverLapping; BaseEvent= myThis.BaseEvent; this.BoundaryTimeLine =myThis.BoundaryTimeLine; //List<SubCalendarEvent> BaseClump; //List<ClumpSubCalendarEvent> NonOverLapping_Clump; BreakOffClump= myThis.BreakOffClump; ClumpedResults= myThis.ClumpedResults; BaseReferenceStartTime = myThis.BaseReferenceStartTime; }
List<mTuple<bool, SubCalendarEvent>> reAlignSubCalEvents(TimeLine BoundaryTimeLine, List<mTuple<bool, SubCalendarEvent>> ListOfEvents) { DateTime ReferenceTime = BoundaryTimeLine.Start; TimeLine Boundary_Cpy = BoundaryTimeLine.CreateCopy(); List<mTuple<bool, SubCalendarEvent>> myClashers = new System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>(); foreach (mTuple<bool, SubCalendarEvent> eachmTuple in ListOfEvents) { if (!eachmTuple.Item2.PinSubEventsToStart(Boundary_Cpy)) { myClashers.Add(eachmTuple); //throw new Exception("error in your shift algorithm"); } else { Boundary_Cpy = new TimeLine(eachmTuple.Item2.End, BoundaryTimeLine.End); }; } ThisWillClash.Add(myClashers); return ListOfEvents; }
List<mTuple<bool, SubCalendarEvent>> stitchRestrictedSubCalendarEvent(List<mTuple<bool, SubCalendarEvent>> Arg1, TimeLine RestrictingTimeLine) { /* * Description: function tries to stitich Restricted SubCalEvents. It starts with the most restricted within timeline as the first node. This first node pins itself to the right It stitches the tree towards the right of the node. Makes a recursive call to stitchRestrictedSubCalendarEvent. pin the returned List and itself to the right hand side then tries to stitck the left hand side */ List<mTuple<bool, SubCalendarEvent>> retValue = Arg1.ToList(); TimeSpan SumOfAllSubCalEvent = Utility.SumOfActiveDuration(Utility.mTupleToSubCalEvents(Arg1)); if (RestrictingTimeLine.TimelineSpan <= SumOfAllSubCalEvent) { ; } List<mTuple<bool, SubCalendarEvent>> CopyOfAllList = Arg1.ToList(); if (retValue.Count < 1)//if arg1 is empty return the list { return retValue; } List<SubCalendarEvent> AllSubCalEvents = Utility.mTupleToSubCalEvents(Arg1); List<mTuple<TimeLine, SubCalendarEvent>> AvaialableTimeSpan = new List<mTuple<TimeLine, SubCalendarEvent>>(); int indexOfSmallest = -2222; int i=0; TimeLine InterferringTimeLine = RestrictingTimeLine.CreateCopy(); TimeSpan SmallestAssignedTimeSpan = new TimeSpan(3650, 0, 0, 0);//sets the smallest TimeSpan To 10 years DateTime SmallestDateTime = new DateTime(3000, 12, 31); /*if (SmallestAssignedTimeSpan < ZeroTimeSpan) { SmallestAssignedTimeSpan= }*/ foreach (SubCalendarEvent eachSubCalendarEvent in AllSubCalEvents)//gets the feasible timeLine foreach SubCalendarEvent { InterferringTimeLine = RestrictingTimeLine.InterferringTimeLine(eachSubCalendarEvent.getCalendarEventRange); if ((InterferringTimeLine != null)&&(InterferringTimeLine.TimelineSpan>=eachSubCalendarEvent.ActiveDuration)) { AvaialableTimeSpan.Add(new mTuple<TimeLine, SubCalendarEvent>(InterferringTimeLine, eachSubCalendarEvent)); TimeSpan CurrentRealignedTimeSpan = InterferringTimeLine.TimelineSpan - eachSubCalendarEvent.ActiveDuration; if (CurrentRealignedTimeSpan <= ZeroTimeSpan) { ; } if ((CurrentRealignedTimeSpan <= SmallestAssignedTimeSpan))//Checks if the remaining timeSpan is less than currently smallest fittable remaining space { if (AllSubCalEvents[i].getCalendarEventRange.End < SmallestDateTime) { indexOfSmallest = i; SmallestAssignedTimeSpan = CurrentRealignedTimeSpan; SmallestDateTime=AllSubCalEvents[indexOfSmallest].getCalendarEventRange.End; } } } i++; } //Build Strict Towards right of the tree if (AvaialableTimeSpan.Count > 0) { int InitialSmallest = indexOfSmallest; indexOfSmallest = AvaialableTimeSpan.Select(obj => obj.Item2).ToList().IndexOf(AllSubCalEvents[indexOfSmallest]); AvaialableTimeSpan[indexOfSmallest].Item2.PinSubEventsToStart(RestrictingTimeLine); mTuple<bool, SubCalendarEvent> PivotNode = CopyOfAllList.Where(obj => (obj.Item2 == AvaialableTimeSpan[indexOfSmallest].Item2)).ToList()[0]; DateTime StartTimeOfRightTree = PivotNode.Item2.End; DateTime EndTimeOfRightTree = RestrictingTimeLine.End; TimeLine RightTimeLine = new TimeLine(StartTimeOfRightTree, EndTimeOfRightTree); CopyOfAllList.Remove(PivotNode); Tuple<SubCalendarEvent, SubCalendarEvent> BoundaryElement = new Tuple<SubCalendarEvent,SubCalendarEvent>(null,PivotNode.Item2); Dictionary<TimeSpan, Dictionary<string, mTuple<bool, SubCalendarEvent>>> PossibleEntries_Cpy= new Dictionary<TimeSpan,Dictionary<string,mTuple<bool,SubCalendarEvent>>>(); foreach(mTuple<bool, SubCalendarEvent> eachmtuple in CopyOfAllList) { if(PossibleEntries_Cpy.ContainsKey(eachmtuple.Item2.RangeSpan)) { PossibleEntries_Cpy[eachmtuple.Item2.RangeSpan].Add(eachmtuple.Item2.ID,eachmtuple); } else { PossibleEntries_Cpy.Add(eachmtuple.Item2.RangeSpan, new Dictionary<string,mTuple<bool,SubCalendarEvent>>()); PossibleEntries_Cpy[eachmtuple.Item2.RangeSpan].Add(eachmtuple.Item2.ID,eachmtuple); } } TimeLine RangeForSnugElements = new TimeLine(RestrictingTimeLine.Start, PivotNode.Item2.Start); List<SubCalendarEvent> OptimizedForLeft = OptimizeArrangeOfSubCalEvent(RangeForSnugElements, BoundaryElement, new List<mTuple<int, TimeSpanWithStringID>>(), PossibleEntries_Cpy, 0); //OptimizedForLeft = new List<SubCalendarEvent>(); CopyOfAllList.RemoveAll(obj => OptimizedForLeft.Contains(obj.Item2)); List<mTuple<bool, SubCalendarEvent>> rightTreeResult = stitchRestrictedSubCalendarEvent(CopyOfAllList, RightTimeLine); if (rightTreeResult.Contains(PivotNode)) { ; } List<mTuple<bool, SubCalendarEvent>> snugFitForLeftTree = Utility.SubCalEventsTomTuple(OptimizedForLeft, true); rightTreeResult.Insert(0, PivotNode); snugFitForLeftTree.AddRange(rightTreeResult); rightTreeResult = snugFitForLeftTree; List<SubCalendarEvent> JustSubCalevents = Utility.mTupleToSubCalEvents(rightTreeResult).ToList(); if (!Utility.PinSubEventsToEnd(JustSubCalevents, RestrictingTimeLine)) { ; }; //Build Strict Towards Left of the tree DateTime StartTimeOfleftTree = RestrictingTimeLine.Start; DateTime EndTimeOfLeftTree = rightTreeResult[0].Item2.Start; TimeLine LeftTimeLine = new TimeLine(StartTimeOfleftTree, EndTimeOfLeftTree); JustSubCalevents = Utility.mTupleToSubCalEvents(rightTreeResult).ToList(); CopyOfAllList.RemoveAll(obj => JustSubCalevents.Contains(obj.Item2)); //CopyOfAllList.RemoveAll(obj => rightTreeResult.Contains(obj)); List<mTuple<bool, SubCalendarEvent>> LeftTreeResult = stitchRestrictedSubCalendarEvent(CopyOfAllList, LeftTimeLine); retValue = LeftTreeResult.Concat(rightTreeResult).ToList(); if (!Utility.PinSubEventsToEnd(Utility.mTupleToSubCalEvents(retValue), RestrictingTimeLine)) { ; }; } else //if there are no feasible TimeLine that are withing RestrictingTimeLine that can also contain a subcalevent { return new List<mTuple<bool, SubCalendarEvent>>(); } return retValue; }
List<mTuple<bool, SubCalendarEvent>> stitchUnRestrictedSubCalendarEvent(TimeLine FreeBoundary, List<mTuple<bool, SubCalendarEvent>> restrictedSnugFitAvailable, Dictionary<TimeSpan, Dictionary<string, mTuple<bool, SubCalendarEvent>>> PossibleEntries, Dictionary<TimeSpan, mTuple<int, TimeSpanWithStringID>> CompatibleWithList,double Occupancy) { TimeLine[] AllFreeSpots = FreeBoundary.getAllFreeSlots(); int TotalEventsForThisTImeLine = 0; foreach (KeyValuePair<TimeSpan, mTuple<int, TimeSpanWithStringID>> eachKeyValuePair in CompatibleWithList) { TotalEventsForThisTImeLine += eachKeyValuePair.Value.Item1; } CompatibleWithList.Clear(); DateTime EarliestReferenceTIme = FreeBoundary.Start; List<mTuple<bool, SubCalendarEvent>> FrontPartials = new System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>(); List<mTuple<bool, SubCalendarEvent>> EndPartials = new System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>(); Dictionary<DateTime, List<mTuple<bool, SubCalendarEvent>>> FrontPartials_Dict = new System.Collections.Generic.Dictionary<DateTime, System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>>(); Dictionary<DateTime, List<mTuple<bool, SubCalendarEvent>>> EndPartials_Dict = new System.Collections.Generic.Dictionary<DateTime, System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>>(); Dictionary<TimeSpan, Dictionary<string, mTuple<bool, SubCalendarEvent>>> PossibleEntries_Cpy = new Dictionary<TimeSpan, Dictionary<string, mTuple<bool, SubCalendarEvent>>>(); Dictionary<string, Dictionary<string, SubCalendarEvent>> CalendarIDAndNonPartialSubCalEvents = new Dictionary<string, Dictionary<string, SubCalendarEvent>>();//List of non partials for current Reference StartTime To End of FreeBoundary. Its gets updated with Partials once the earliest reference time passes the partial event start time foreach (KeyValuePair<TimeSpan, Dictionary<string, mTuple<bool, SubCalendarEvent>>> eachKeyValuePair in PossibleEntries)//populates PossibleEntries_Cpy. I need a copy to maintain all references to PossibleEntries { Dictionary<string, mTuple<bool, SubCalendarEvent>> NewDictEntry = new Dictionary<string, mTuple<bool, SubCalendarEvent>>(); foreach (KeyValuePair<string, mTuple<bool, SubCalendarEvent>> KeyValuePair0 in eachKeyValuePair.Value) { mTuple<bool, SubCalendarEvent> MyEvent = KeyValuePair0.Value; if (MyEvent.Item2.ID == "469_471") { ; } bool isInrestrictedSnugFitAvailable = false; if (CompatibleWithList.ContainsKey(eachKeyValuePair.Key)) { ++CompatibleWithList[eachKeyValuePair.Key].Item1; } else { CompatibleWithList.Add(eachKeyValuePair.Key, new mTuple<int, TimeSpanWithStringID>(1, new TimeSpanWithStringID(KeyValuePair0.Value.Item2.ActiveDuration, KeyValuePair0.Value.Item2.ActiveDuration.Ticks.ToString()))); } foreach (mTuple<bool, SubCalendarEvent> eachMtuple in restrictedSnugFitAvailable)//checks if event is in restricted list { if (eachMtuple.Item2.ID == MyEvent.Item2.ID) { isInrestrictedSnugFitAvailable = true; break; } } if (!isInrestrictedSnugFitAvailable) { NewDictEntry.Add(KeyValuePair0.Value.Item2.ID, KeyValuePair0.Value); if (FreeBoundary.IsDateTimeWithin(KeyValuePair0.Value.Item2.getCalendarEventRange.Start)) { FrontPartials.Add(KeyValuePair0.Value); } else { if (FreeBoundary.IsDateTimeWithin(KeyValuePair0.Value.Item2.getCalendarEventRange.End)) { EndPartials.Add(KeyValuePair0.Value); } else { string CalLevel0ID=KeyValuePair0.Value.Item2.SubEvent_ID.getLevelID(0); if (CalendarIDAndNonPartialSubCalEvents.ContainsKey(CalLevel0ID)) { CalendarIDAndNonPartialSubCalEvents[CalLevel0ID].Add(KeyValuePair0.Value.Item2.ID, KeyValuePair0.Value.Item2); } else { //CalendarIDAndNonPartialSubCalEvents.Add(CalLevel0ID, new List<SubCalendarEvent>() { KeyValuePair0.Value.Item2 }); CalendarIDAndNonPartialSubCalEvents.Add(CalLevel0ID, new Dictionary<string, SubCalendarEvent>()); CalendarIDAndNonPartialSubCalEvents[CalLevel0ID].Add(KeyValuePair0.Value.Item2.ID, KeyValuePair0.Value.Item2); } } } } } if (NewDictEntry.Count > 0) { PossibleEntries_Cpy.Add(eachKeyValuePair.Key, NewDictEntry); } } FrontPartials = FrontPartials.OrderBy(obj => obj.Item2.getCalendarEventRange.Start).ToList(); EndPartials = EndPartials.OrderBy(obj => obj.Item2.getCalendarEventRange.End).ToList(); foreach (mTuple<bool, SubCalendarEvent> eachmTuple in FrontPartials)//populates FrontPartials_Dict in ordered manner since FrontPartials is ordered { if (FrontPartials_Dict.ContainsKey(eachmTuple.Item2.getCalendarEventRange.Start)) { FrontPartials_Dict[eachmTuple.Item2.getCalendarEventRange.Start].Add(eachmTuple); } else { FrontPartials_Dict.Add(eachmTuple.Item2.getCalendarEventRange.Start, new System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>() { eachmTuple }); } } foreach (mTuple<bool, SubCalendarEvent> eachmTuple in EndPartials)//populates EndPartials_Dict in ordered manner since EndPartials is ordered { if (EndPartials_Dict.ContainsKey(eachmTuple.Item2.getCalendarEventRange.Start)) { EndPartials_Dict[eachmTuple.Item2.getCalendarEventRange.Start].Add(eachmTuple); } else { EndPartials_Dict.Add(eachmTuple.Item2.getCalendarEventRange.Start, new System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>() { eachmTuple }); } } List<SubCalendarEvent> CompleteArranegement = new System.Collections.Generic.List<SubCalendarEvent>(); int StartingReferneceIndex = 0; /*foreach (mTuple<bool, SubCalendarEvent> eachmTuple in restrictedSnugFitAvailable)//removes the restricted from CompatibleWithList { --CompatibleWithList[eachmTuple.Item2.ActiveDuration.Ticks.ToString()].Item1; //PossibleEntries_Cpy[eachmTuple.Item2.ActiveDuration.Ticks.ToString()].Remove(eachmTuple.Item2.ID); }*/ List<DateTime> ListOfFrontPartialsStartTime = FrontPartials_Dict.Keys.ToList(); int i = 0; int j = 0; int FrontPartialCounter = 0; if (restrictedSnugFitAvailable.Count < 1) { ; } Tuple<DateTime, List<SubCalendarEvent>> TimeLineUpdated = null; SubCalendarEvent BorderElementBeginning = null; SubCalendarEvent BorderElementEnd = null; SubCalendarEvent LastSubCalElementForEarlierReferenceTime = null; for (; i < restrictedSnugFitAvailable.Count; i++) { //bool isFreeSpotBeforeRigid = AllFreeSpots[i].End <= restrictedSnugFitAvailable[i].Item2.Start; TimeLineUpdated = null; if (CompleteArranegement.Count == 46) { ; } if (i ==2) { ; } restrictedSnugFitAvailable[i].Item2.PinSubEventsToStart(new TimeLine(EarliestReferenceTIme, restrictedSnugFitAvailable[i].Item2.getCalendarEventRange.End)); List<BusyTimeLine> RestrictedBusySlots = new System.Collections.Generic.List<BusyTimeLine>(); FreeBoundary = new TimeLine(FreeBoundary.Start, FreeBoundary.End); foreach (mTuple<bool, SubCalendarEvent> eachmTuple in restrictedSnugFitAvailable) { eachmTuple.Item1 = true; RestrictedBusySlots.Add(eachmTuple.Item2.ActiveSlot); string timeSpanString = eachmTuple.Item2.ActiveDuration.Ticks.ToString(); string SubEventID = eachmTuple.Item2.ID; } FreeBoundary.AddBusySlots(RestrictedBusySlots.ToArray()); List<SubCalendarEvent> LowestCostArrangement = new System.Collections.Generic.List<SubCalendarEvent>(); TimeLine PertinentFreeSpot = null; TimeLine FreeSpotUpdated = null; j = i + 1; if (ListOfFrontPartialsStartTime.Count > 0)//fits any sub calEvent in preceeding restricting free spot { DateTime RestrictedStopper = restrictedSnugFitAvailable[i].Item2.Start; bool breakForLoop = false; bool PreserveRestrictedIndex = false; for (; FrontPartialCounter < ListOfFrontPartialsStartTime.Count; FrontPartialCounter++) { TimeLineUpdated = null; DateTime PertinentFreeSpotStart = EarliestReferenceTIme; DateTime PertinentFreeSpotEnd; if (CompleteArranegement.Count == 46) { ; } if ((ListOfFrontPartialsStartTime[FrontPartialCounter] < RestrictedStopper)) { PertinentFreeSpotEnd = ListOfFrontPartialsStartTime[FrontPartialCounter]; //FrontPartials_Dict.Remove(ListOfFrontPartialsStartTime[FrontPartialCounter]); ListOfFrontPartialsStartTime.RemoveAt(FrontPartialCounter); --FrontPartialCounter; PreserveRestrictedIndex = true; } else { PertinentFreeSpotEnd = RestrictedStopper; if (breakForLoop) {//populates with final boundary for each restricted PertinentFreeSpot = new TimeLine(PertinentFreeSpotStart, PertinentFreeSpotEnd); BorderElementBeginning = CompleteArranegement.Count>0?CompleteArranegement[CompleteArranegement.Count-1]:null;//Checks if Complete arrangement has partially being filled. Sets Last elements as boundary Element BorderElementEnd = restrictedSnugFitAvailable[i].Item2;//uses restricted value as boundary element LowestCostArrangement = OptimizeArrangeOfSubCalEvent(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy,Occupancy); DateTime EarliestTimeForBetterEarlierReferenceTime = PertinentFreeSpot.Start; LastSubCalElementForEarlierReferenceTime = ((CompleteArranegement.Count < 1) || (CompleteArranegement == null) ? null : CompleteArranegement[CompleteArranegement.Count - 1]); FreeSpotUpdated = PertinentFreeSpot.CreateCopy(); if (LowestCostArrangement.Count > 0) { if (!(LowestCostArrangement[0].getCalendarEventRange.Start == PertinentFreeSpot.Start))//Pin SubEvents To Start {//if the first element is not a partial Sub Cal Event element FreeSpotUpdated = new TimeLine(EarliestReferenceTIme, PertinentFreeSpot.End); Utility.PinSubEventsToStart(LowestCostArrangement, FreeSpotUpdated); } else { FreeSpotUpdated = PertinentFreeSpot.CreateCopy();// new TimeLine(LowestCostArrangement[0].getCalendarEventRange.Start, PertinentFreeSpot.End); Utility.PinSubEventsToStart(LowestCostArrangement, PertinentFreeSpot); } EarliestReferenceTIme = PertinentFreeSpot.End;// LowestCostArrangement[LowestCostArrangement.Count - 1].End; SubCalendarEvent LastSubCalEvent = LowestCostArrangement[LowestCostArrangement.Count - 1]; EarliestTimeForBetterEarlierReferenceTime = LastSubCalEvent.End; LastSubCalElementForEarlierReferenceTime = LastSubCalEvent; } TimeLineUpdated = null; TimeLineUpdated = ObtainBetterEarlierReferenceTime(LowestCostArrangement, CalendarIDAndNonPartialSubCalEvents, RestrictedStopper - EarliestTimeForBetterEarlierReferenceTime, EarliestReferenceTIme, new TimeLine(FreeSpotUpdated.Start, FreeBoundary.End), LastSubCalElementForEarlierReferenceTime); if (TimeLineUpdated != null) { LowestCostArrangement = TimeLineUpdated.Item2; EarliestReferenceTIme = TimeLineUpdated.Item1; } foreach (SubCalendarEvent eachSubCalendarEvent in LowestCostArrangement) { --CompatibleWithList[eachSubCalendarEvent.ActiveDuration].Item1; PossibleEntries_Cpy[eachSubCalendarEvent.ActiveDuration].Remove(eachSubCalendarEvent.ID); string SubCalString = eachSubCalendarEvent.SubEvent_ID.getLevelID(0); if (CalendarIDAndNonPartialSubCalEvents.ContainsKey(SubCalString)) { CalendarIDAndNonPartialSubCalEvents[SubCalString].Remove(eachSubCalendarEvent.ID); if (CalendarIDAndNonPartialSubCalEvents[SubCalString].Count < 1) { CalendarIDAndNonPartialSubCalEvents.Remove(SubCalString); } } if (PossibleEntries_Cpy[eachSubCalendarEvent.ActiveDuration].Count < 1) { PossibleEntries_Cpy.Remove(eachSubCalendarEvent.ActiveDuration); } } LowestCostArrangement = CompleteArranegement.Concat(LowestCostArrangement).ToList(); LowestCostArrangement = PlaceSubCalEventInLowestCostPosition(FreeBoundary, restrictedSnugFitAvailable[i].Item2, LowestCostArrangement); Utility.PinSubEventsToStart(LowestCostArrangement, FreeBoundary); CompleteArranegement = LowestCostArrangement; EarliestReferenceTIme = LowestCostArrangement[LowestCostArrangement.Count - 1].End; PreserveRestrictedIndex = false; break; } --FrontPartialCounter; if (j < restrictedSnugFitAvailable.Count) { RestrictedStopper = restrictedSnugFitAvailable[i].Item2.getCalendarEventRange.End > restrictedSnugFitAvailable[j].Item2.Start ? restrictedSnugFitAvailable[j].Item2.Start : restrictedSnugFitAvailable[i].Item2.getCalendarEventRange.End; } else { RestrictedStopper = restrictedSnugFitAvailable[i].Item2.getCalendarEventRange.End > FreeBoundary.End ? FreeBoundary.End : restrictedSnugFitAvailable[i].Item2.getCalendarEventRange.End; } RestrictedStopper -= restrictedSnugFitAvailable[i].Item2.ActiveDuration; breakForLoop = true; } PertinentFreeSpot = new TimeLine(PertinentFreeSpotStart, PertinentFreeSpotEnd); BorderElementBeginning = CompleteArranegement.Count > 0 ? CompleteArranegement[CompleteArranegement.Count - 1] : null;//Checks if Complete arrangement has partially being filled. Sets Last elements as boundary Element BorderElementEnd = restrictedSnugFitAvailable[i].Item2;//uses restricted value as boundary element LowestCostArrangement = OptimizeArrangeOfSubCalEvent(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, Occupancy); DateTime LatestDaterforEarlierReferenceTime = PertinentFreeSpot.Start; LastSubCalElementForEarlierReferenceTime = ((CompleteArranegement.Count < 1) || (CompleteArranegement == null) ? null : CompleteArranegement[CompleteArranegement.Count - 1]);//updates the last element as either null or the last element in the current Complete arrangement FreeSpotUpdated = PertinentFreeSpot.CreateCopy(); if (LowestCostArrangement.Count > 0) { if (!(LowestCostArrangement[0].getCalendarEventRange.Start == PertinentFreeSpot.Start))//Pin SubEvents To Start {//if the first element is not a partial Sub Cal Event element FreeSpotUpdated = new TimeLine(EarliestReferenceTIme, PertinentFreeSpot.End); Utility.PinSubEventsToStart(LowestCostArrangement, FreeSpotUpdated); } else { //FreeSpotUpdated = new TimeLine(LowestCostArrangement[0].getCalendarEventRange.Start, PertinentFreeSpot.End); FreeSpotUpdated = PertinentFreeSpot.CreateCopy(); Utility.PinSubEventsToStart(LowestCostArrangement, PertinentFreeSpot); } EarliestReferenceTIme = PertinentFreeSpot.End; ///Comeback to this /// SubCalendarEvent LastSubCalEvent = LowestCostArrangement[LowestCostArrangement.Count - 1]; LatestDaterforEarlierReferenceTime = LastSubCalEvent.End; LastSubCalElementForEarlierReferenceTime = LastSubCalEvent; } TimeLineUpdated = ObtainBetterEarlierReferenceTime(LowestCostArrangement, CalendarIDAndNonPartialSubCalEvents, RestrictedStopper - LatestDaterforEarlierReferenceTime, EarliestReferenceTIme, new TimeLine(FreeSpotUpdated.Start, FreeBoundary.End), LastSubCalElementForEarlierReferenceTime); //errorline if (TimeLineUpdated != null) { LowestCostArrangement = TimeLineUpdated.Item2; EarliestReferenceTIme = TimeLineUpdated.Item1; } foreach (SubCalendarEvent eachSubCalendarEvent in LowestCostArrangement) { --CompatibleWithList[eachSubCalendarEvent.ActiveDuration].Item1; PossibleEntries_Cpy[eachSubCalendarEvent.ActiveDuration].Remove(eachSubCalendarEvent.ID); string SubCalString = eachSubCalendarEvent.SubEvent_ID.getLevelID(0); if (CalendarIDAndNonPartialSubCalEvents.ContainsKey(SubCalString)) { CalendarIDAndNonPartialSubCalEvents[SubCalString].Remove(eachSubCalendarEvent.ID); if (CalendarIDAndNonPartialSubCalEvents[SubCalString].Count < 1) { CalendarIDAndNonPartialSubCalEvents.Remove(SubCalString); } } if (PossibleEntries_Cpy[eachSubCalendarEvent.ActiveDuration].Count < 1) { PossibleEntries_Cpy.Remove(eachSubCalendarEvent.ActiveDuration); } } CompleteArranegement.AddRange(LowestCostArrangement); int DateTimeCounter = 0; for (; DateTimeCounter < FrontPartials_Dict.Keys.Count; DateTimeCounter++)//updates CalendarIDAndNonPartialSubCalEvents if frontpartial Startime has been passed. Alls updates FrontPartials_Dict { DateTime eachDateTIme = FrontPartials_Dict.Keys.ToList()[DateTimeCounter]; if (EarliestReferenceTIme >= eachDateTIme) { List<mTuple<bool, SubCalendarEvent>> mTUpleSubCalEvents = FrontPartials_Dict[eachDateTIme]; foreach (mTuple<bool, SubCalendarEvent> eachmTUple in mTUpleSubCalEvents) { string CalLevel0ID = eachmTUple.Item2.SubEvent_ID.getLevelID(0); if (!CompleteArranegement.Contains(eachmTUple.Item2)) { if (CalendarIDAndNonPartialSubCalEvents.ContainsKey(CalLevel0ID)) { CalendarIDAndNonPartialSubCalEvents[CalLevel0ID].Add(eachmTUple.Item2.ID, eachmTUple.Item2); } else { //CalendarIDAndNonPartialSubCalEvents.Add(CalLevel0ID, new List<SubCalendarEvent>() { KeyValuePair0.Value.Item2 }); CalendarIDAndNonPartialSubCalEvents.Add(CalLevel0ID, new Dictionary<string, SubCalendarEvent>()); CalendarIDAndNonPartialSubCalEvents[CalLevel0ID].Add(eachmTUple.Item2.ID, eachmTUple.Item2); } } } FrontPartials_Dict.Remove(eachDateTIme); } } } if (PreserveRestrictedIndex)//verifies if we took the path of restricted or front partial element. The latter needs a preservation of the current restricted Subcalevent index index { --i; } } else {//No FrontPartials DateTime ReferenceEndTime = restrictedSnugFitAvailable[i].Item2.Start; PertinentFreeSpot = new TimeLine(EarliestReferenceTIme, ReferenceEndTime); BorderElementBeginning = CompleteArranegement.Count > 0 ? CompleteArranegement[CompleteArranegement.Count - 1] : null;//Checks if Complete arrangement has partially being filled. Sets Last elements as boundary Element BorderElementEnd = restrictedSnugFitAvailable[i].Item2;//uses restricted value as boundary element LowestCostArrangement = OptimizeArrangeOfSubCalEvent(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy,Occupancy); if (LowestCostArrangement.Count > 0) { if (!(LowestCostArrangement[0].getCalendarEventRange.Start == PertinentFreeSpot.Start))//Pin SubEvents To Start {//if the first element is not a partial Sub Cal Event element FreeSpotUpdated = new TimeLine(EarliestReferenceTIme, PertinentFreeSpot.End); Utility.PinSubEventsToStart(LowestCostArrangement, FreeSpotUpdated); } else { FreeSpotUpdated = new TimeLine(LowestCostArrangement[0].getCalendarEventRange.Start, PertinentFreeSpot.End); Utility.PinSubEventsToStart(LowestCostArrangement, PertinentFreeSpot); } EarliestReferenceTIme = FreeSpotUpdated.End;// LowestCostArrangement[LowestCostArrangement.Count - 1].End; } foreach (SubCalendarEvent eachSubCalendarEvent in LowestCostArrangement) { --CompatibleWithList[eachSubCalendarEvent.ActiveDuration].Item1; PossibleEntries_Cpy[eachSubCalendarEvent.ActiveDuration].Remove(eachSubCalendarEvent.ID); string SubCalString = eachSubCalendarEvent.SubEvent_ID.getLevelID(0); if (CalendarIDAndNonPartialSubCalEvents.ContainsKey(SubCalString)) { CalendarIDAndNonPartialSubCalEvents[SubCalString].Remove(eachSubCalendarEvent.ID); if (CalendarIDAndNonPartialSubCalEvents[SubCalString].Count < 1) { CalendarIDAndNonPartialSubCalEvents.Remove(SubCalString); } } if (PossibleEntries_Cpy[eachSubCalendarEvent.ActiveDuration].Count < 1) { PossibleEntries_Cpy.Remove(eachSubCalendarEvent.ActiveDuration); } } List<SubCalendarEvent> AdditionalCOstArrangement = new System.Collections.Generic.List<SubCalendarEvent>(); if (j < restrictedSnugFitAvailable.Count) { DateTime StartDateTimeAfterFitting = PertinentFreeSpot.End;//this is the barring end time of the preceding boundary search DateTime RelativeEndTime = restrictedSnugFitAvailable[i].Item2.getCalendarEventRange.End > restrictedSnugFitAvailable[j].Item2.Start ? restrictedSnugFitAvailable[j].Item2.Start : restrictedSnugFitAvailable[i].Item2.getCalendarEventRange.End; RelativeEndTime -= restrictedSnugFitAvailable[i].Item2.ActiveDuration; TimeLine CurrentlyFittedTimeLine = new TimeLine(StartDateTimeAfterFitting, RelativeEndTime); BorderElementBeginning = CompleteArranegement.Count > 0 ? CompleteArranegement[CompleteArranegement.Count - 1] : null;//Checks if Complete arrangement has partially being filled. Sets Last elements as boundary Element BorderElementEnd = restrictedSnugFitAvailable[i].Item2;//uses restricted value as boundary element AdditionalCOstArrangement = OptimizeArrangeOfSubCalEvent(CurrentlyFittedTimeLine, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, Occupancy); if (AdditionalCOstArrangement.Count > 0) {//Additional get populated if (!(AdditionalCOstArrangement[0].getCalendarEventRange.Start == CurrentlyFittedTimeLine.Start))//Pin SubEvents To Start {//if the first element is not a partial Sub Cal Event element FreeSpotUpdated = new TimeLine(EarliestReferenceTIme, CurrentlyFittedTimeLine.End); Utility.PinSubEventsToStart(AdditionalCOstArrangement, FreeSpotUpdated); } else { FreeSpotUpdated = new TimeLine(AdditionalCOstArrangement[0].getCalendarEventRange.Start, CurrentlyFittedTimeLine.End); Utility.PinSubEventsToStart(AdditionalCOstArrangement, FreeSpotUpdated); } foreach (SubCalendarEvent eachSubCalendarEvent in AdditionalCOstArrangement) { --CompatibleWithList[eachSubCalendarEvent.ActiveDuration].Item1; PossibleEntries_Cpy[eachSubCalendarEvent.ActiveDuration].Remove(eachSubCalendarEvent.ID); string SubCalString = eachSubCalendarEvent.SubEvent_ID.getLevelID(0); if (CalendarIDAndNonPartialSubCalEvents.ContainsKey(SubCalString)) { CalendarIDAndNonPartialSubCalEvents[SubCalString].Remove(eachSubCalendarEvent.ID); if (CalendarIDAndNonPartialSubCalEvents[SubCalString].Count < 1) { CalendarIDAndNonPartialSubCalEvents.Remove(SubCalString); } } if (PossibleEntries_Cpy[eachSubCalendarEvent.ActiveDuration].Count < 1) { PossibleEntries_Cpy.Remove(eachSubCalendarEvent.ActiveDuration); } } RelativeEndTime = AdditionalCOstArrangement[AdditionalCOstArrangement.Count - 1].End; RelativeEndTime += restrictedSnugFitAvailable[i].Item2.ActiveDuration; ; FreeSpotUpdated = new TimeLine(FreeSpotUpdated.Start, RelativeEndTime); AdditionalCOstArrangement = PlaceSubCalEventInLowestCostPosition(FreeSpotUpdated, restrictedSnugFitAvailable[i].Item2, AdditionalCOstArrangement); } else {//if there is no other Restricted in list RelativeEndTime += restrictedSnugFitAvailable[i].Item2.ActiveDuration; CurrentlyFittedTimeLine = new TimeLine(CurrentlyFittedTimeLine.Start, RelativeEndTime); AdditionalCOstArrangement = PlaceSubCalEventInLowestCostPosition(CurrentlyFittedTimeLine, restrictedSnugFitAvailable[i].Item2, AdditionalCOstArrangement); } } else { DateTime RelativeEndTime = restrictedSnugFitAvailable[i].Item2.getCalendarEventRange.End > FreeBoundary.End ? FreeBoundary.End : restrictedSnugFitAvailable[i].Item2.getCalendarEventRange.End; TimeLine CurrentlyFittedTimeLine = new TimeLine(EarliestReferenceTIme, RelativeEndTime); AdditionalCOstArrangement = PlaceSubCalEventInLowestCostPosition(CurrentlyFittedTimeLine, restrictedSnugFitAvailable[i].Item2, AdditionalCOstArrangement); } List<SubCalendarEvent> var2 = new System.Collections.Generic.List<SubCalendarEvent>();//List is a addition of LowestCostArrangement and AdditionalCOstArrangement var2 = LowestCostArrangement.Concat(AdditionalCOstArrangement).ToList(); CompleteArranegement.AddRange(LowestCostArrangement); CompleteArranegement.AddRange(AdditionalCOstArrangement); if (CompleteArranegement.Count > 0) { EarliestReferenceTIme = CompleteArranegement[CompleteArranegement.Count - 1].End; } } } { //Handles THe Last Free Space outside of rigids TimeLine FreeSpotOutSideRigids = new TimeLine(EarliestReferenceTIme, FreeBoundary.End); TimeLine PertinentFreeSpot = new TimeLine(EarliestReferenceTIme, FreeBoundary.End); ; TimeLine FreeSpotUpdated; List<SubCalendarEvent> LowestCostArrangement; if (ListOfFrontPartialsStartTime.Count > 0) { for (FrontPartialCounter = 0; FrontPartialCounter < ListOfFrontPartialsStartTime.Count; FrontPartialCounter++) { DateTime PertinentFreeSpotStart = EarliestReferenceTIme; DateTime PertinentFreeSpotEnd; PertinentFreeSpotEnd = ListOfFrontPartialsStartTime[FrontPartialCounter]; //FrontPartials_Dict.Remove(ListOfFrontPartialsStartTime[FrontPartialCounter]); ListOfFrontPartialsStartTime.RemoveAt(FrontPartialCounter); --FrontPartialCounter; PertinentFreeSpot = new TimeLine(PertinentFreeSpotStart, PertinentFreeSpotEnd); FreeSpotUpdated = PertinentFreeSpot.CreateCopy(); BorderElementBeginning = CompleteArranegement.Count > 0 ? CompleteArranegement[CompleteArranegement.Count - 1] : null;//Checks if Complete arrangement has partially being filled. Sets Last elements as boundary Element BorderElementEnd = null; LowestCostArrangement = OptimizeArrangeOfSubCalEvent(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, Occupancy); DateTime LatestTimeForBetterEarlierReferenceTime = PertinentFreeSpot.Start; LastSubCalElementForEarlierReferenceTime = ((CompleteArranegement.Count < 1) || (CompleteArranegement == null) ? null : CompleteArranegement[CompleteArranegement.Count - 1]); if (LowestCostArrangement.Count > 0) { if ((LowestCostArrangement[0].getCalendarEventRange.Start != PertinentFreeSpot.Start))//Pin SubEvents To Start {//if the first element is not a partial Sub Cal Event element FreeSpotUpdated = new TimeLine(EarliestReferenceTIme, PertinentFreeSpot.End); Utility.PinSubEventsToStart(LowestCostArrangement, FreeSpotUpdated); } else { FreeSpotUpdated = PertinentFreeSpot.CreateCopy();// new TimeLine(LowestCostArrangement[0].getCalendarEventRange.Start, PertinentFreeSpot.End); Utility.PinSubEventsToStart(LowestCostArrangement, FreeSpotUpdated); } EarliestReferenceTIme = PertinentFreeSpot.End;// LowestCostArrangement[LowestCostArrangement.Count - 1].End; SubCalendarEvent LastSubCalEvent = LowestCostArrangement[LowestCostArrangement.Count - 1]; LatestTimeForBetterEarlierReferenceTime = LastSubCalEvent.End; LastSubCalElementForEarlierReferenceTime = LastSubCalEvent; /* Dictionary<string, double> AllValidNodes = CalendarEvent.DistanceToAllNodes(LastSubCalEvent.SubEvent_ID.getLevelID(0)); SubCalendarEvent AppendableEVent; foreach (string eachstring in AllValidNodes.Keys) { if (CalendarIDAndNonPartialSubCalEvents.ContainsKey(eachstring)) { AppendableEVent = CalendarIDAndNonPartialSubCalEvents[eachstring].ToList()[0].Value;//Assumes Theres Always an element if ((AppendableEVent.ActiveDuration <= (FreeBoundary.End - LastSubCalEvent.End)) && (!LowestCostArrangement.Contains(AppendableEVent))) { LowestCostArrangement.Add(AppendableEVent); CalendarIDAndNonPartialSubCalEvents[eachstring].Remove(AppendableEVent.ID); if (CalendarIDAndNonPartialSubCalEvents[eachstring].Count < 1)//checks if List is empty. Deletes keyValuepair if list is empty { CalendarIDAndNonPartialSubCalEvents.Remove(eachstring); } FreeSpotUpdated = new TimeLine(FreeSpotUpdated.Start, FreeBoundary.End); Utility.PinSubEventsToStart(LowestCostArrangement, FreeSpotUpdated); EarliestReferenceTIme = AppendableEVent.End; break; } } }*/ } TimeLineUpdated = null; TimeLineUpdated = ObtainBetterEarlierReferenceTime(LowestCostArrangement, CalendarIDAndNonPartialSubCalEvents, FreeBoundary.End - LatestTimeForBetterEarlierReferenceTime, EarliestReferenceTIme, new TimeLine(FreeSpotUpdated.Start, FreeBoundary.End), LastSubCalElementForEarlierReferenceTime); if (TimeLineUpdated != null) { LowestCostArrangement = TimeLineUpdated.Item2; EarliestReferenceTIme = TimeLineUpdated.Item1; } foreach (SubCalendarEvent eachSubCalendarEvent in LowestCostArrangement) { --CompatibleWithList[eachSubCalendarEvent.ActiveDuration].Item1; PossibleEntries_Cpy[eachSubCalendarEvent.ActiveDuration].Remove(eachSubCalendarEvent.ID); string SubCalString = eachSubCalendarEvent.SubEvent_ID.getLevelID(0); if (CalendarIDAndNonPartialSubCalEvents.ContainsKey(SubCalString)) { CalendarIDAndNonPartialSubCalEvents[SubCalString].Remove(eachSubCalendarEvent.ID); if (CalendarIDAndNonPartialSubCalEvents[SubCalString].Count < 1) { CalendarIDAndNonPartialSubCalEvents.Remove(SubCalString); } } if (PossibleEntries_Cpy[eachSubCalendarEvent.ActiveDuration].Count < 1) { PossibleEntries_Cpy.Remove(eachSubCalendarEvent.ActiveDuration); } } CompleteArranegement.AddRange(LowestCostArrangement); } } DateTime ReferenceEndTime = FreeBoundary.End; PertinentFreeSpot = new TimeLine(EarliestReferenceTIme, ReferenceEndTime); /*LowestCostArrangement = OptimizeArrangeOfSubCalEvent(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(null, null), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy); if (LowestCostArrangement.Count > 0) { if (!(LowestCostArrangement[0].getCalendarEventRange.Start == PertinentFreeSpot.Start))//Pin SubEvents To Start {//if the first element is not a partial Sub Cal Event element FreeSpotUpdated = new TimeLine(EarliestReferenceTIme, PertinentFreeSpot.End); Utility.PinSubEventsToStart(LowestCostArrangement, FreeSpotUpdated); } else { FreeSpotUpdated = PertinentFreeSpot.CreateCopy();// new TimeLine(LowestCostArrangement[0].getCalendarEventRange.Start, PertinentFreeSpot.End); Utility.PinSubEventsToStart(LowestCostArrangement, FreeSpotUpdated); } EarliestReferenceTIme = FreeSpotUpdated.End;// LowestCostArrangement[LowestCostArrangement.Count - 1].End; }*/ BorderElementBeginning = CompleteArranegement.Count > 0 ? CompleteArranegement[CompleteArranegement.Count - 1] : null;//Checks if Complete arrangement has partially being filled. Sets Last elements as boundary Element BorderElementEnd = null; LowestCostArrangement = OptimizeArrangeOfSubCalEvent(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, Occupancy); LastSubCalElementForEarlierReferenceTime = ((CompleteArranegement.Count < 1) || (CompleteArranegement == null) ? null : CompleteArranegement[CompleteArranegement.Count - 1]); DateTime LimitForBetterEarlierReferencTime = EarliestReferenceTIme; FreeSpotUpdated = PertinentFreeSpot.CreateCopy(); if (LowestCostArrangement.Count > 0) { if ((LowestCostArrangement[0].getCalendarEventRange.Start != PertinentFreeSpot.Start))//Pin SubEvents To Start {//if the first element is not a partial Sub Cal Event element FreeSpotUpdated = new TimeLine(EarliestReferenceTIme, PertinentFreeSpot.End); Utility.PinSubEventsToStart(LowestCostArrangement, FreeSpotUpdated); } else { FreeSpotUpdated = PertinentFreeSpot.CreateCopy();// new TimeLine(LowestCostArrangement[0].getCalendarEventRange.Start, PertinentFreeSpot.End); Utility.PinSubEventsToStart(LowestCostArrangement, PertinentFreeSpot); } EarliestReferenceTIme = PertinentFreeSpot.End;// LowestCostArrangement[LowestCostArrangement.Count - 1].End; SubCalendarEvent LastSubCalEvent = LowestCostArrangement[LowestCostArrangement.Count - 1]; LimitForBetterEarlierReferencTime=LastSubCalEvent.End; LastSubCalElementForEarlierReferenceTime = LastSubCalEvent; /* Dictionary<string, double> AllValidNodes = CalendarEvent.DistanceToAllNodes(LastSubCalEvent.SubEvent_ID.getLevelID(0)); SubCalendarEvent AppendableEVent; foreach (string eachstring in AllValidNodes.Keys) { if (CalendarIDAndNonPartialSubCalEvents.ContainsKey(eachstring)) { AppendableEVent = CalendarIDAndNonPartialSubCalEvents[eachstring].ToList()[0].Value;//Assumes Theres Always an element if ((AppendableEVent.ActiveDuration <= (FreeBoundary.End - LastSubCalEvent.End)) && (!LowestCostArrangement.Contains(AppendableEVent))) { LowestCostArrangement.Add(AppendableEVent); CalendarIDAndNonPartialSubCalEvents[eachstring].Remove(AppendableEVent.ID); if (CalendarIDAndNonPartialSubCalEvents[eachstring].Count < 1)//checks if List is empty. Deletes keyValuepair if list is empty { CalendarIDAndNonPartialSubCalEvents.Remove(eachstring); } FreeSpotUpdated = new TimeLine(FreeSpotUpdated.Start, FreeBoundary.End); Utility.PinSubEventsToStart(LowestCostArrangement, FreeSpotUpdated); EarliestReferenceTIme = AppendableEVent.End; break; } } }*/ } TimeLineUpdated = null; TimeLineUpdated = ObtainBetterEarlierReferenceTime(LowestCostArrangement, CalendarIDAndNonPartialSubCalEvents, FreeBoundary.End - LimitForBetterEarlierReferencTime, EarliestReferenceTIme, new TimeLine(FreeSpotUpdated.Start, FreeBoundary.End), LastSubCalElementForEarlierReferenceTime); if (TimeLineUpdated != null) { LowestCostArrangement = TimeLineUpdated.Item2; EarliestReferenceTIme = TimeLineUpdated.Item1; } foreach (SubCalendarEvent eachSubCalendarEvent in LowestCostArrangement) { --CompatibleWithList[eachSubCalendarEvent.ActiveDuration].Item1; PossibleEntries_Cpy[eachSubCalendarEvent.ActiveDuration].Remove(eachSubCalendarEvent.ID); string SubCalString = eachSubCalendarEvent.SubEvent_ID.getLevelID(0); if(CalendarIDAndNonPartialSubCalEvents.ContainsKey(SubCalString)) { CalendarIDAndNonPartialSubCalEvents[SubCalString].Remove(eachSubCalendarEvent.ID); if (CalendarIDAndNonPartialSubCalEvents[SubCalString].Count < 1) { CalendarIDAndNonPartialSubCalEvents.Remove(SubCalString); } } if (PossibleEntries_Cpy[eachSubCalendarEvent.ActiveDuration].Count < 1) { PossibleEntries_Cpy.Remove(eachSubCalendarEvent.ActiveDuration); } } CompleteArranegement.AddRange(LowestCostArrangement); } List<mTuple<bool, SubCalendarEvent>> retValue = new System.Collections.Generic.List<mTuple<bool, SubCalendarEvent>>(); foreach (SubCalendarEvent eachSubCalendarEvent in CompleteArranegement) { PossibleEntries[eachSubCalendarEvent.ActiveDuration][eachSubCalendarEvent.ID].Item1 = true; retValue.Add(PossibleEntries[eachSubCalendarEvent.ActiveDuration][eachSubCalendarEvent.ID]); } //List<List<SubCalendarEvent>> unrestrictedValidCombinations = generateCombinationForDifferentEntries(CompatibleWithList, PossibleEntries); retValue = reAlignSubCalEvents(FreeBoundary, retValue); if (TotalEventsForThisTImeLine != retValue.Count) { ; } return retValue; }
KeyValuePair<CalendarEvent, TimeLine> ReArrangeTimeLineWithinWithinCalendaEventRange(CalendarEvent MyCalendarEvent, List<CalendarEvent> NoneCommitedCalendarEventsEvents)// this looks at the timeline of the calendar event and then tries to rearrange all subevents within the range to suit final output. Such that there will be sufficient time space for each subevent { /* Name{: Jerome Biotidara * this function is responsible for making sure there is some dynamic allotment of time to the subeevents. It takes a calendarevent, checks the alloted time frame and tries to move subevents within the time frame to satisfy the final goal. */ int i = 0; if (MyCalendarEvent.RepetitionStatus == false)//Artificially generates random subevents for the calendar event { SubCalendarEvent[] TempSubCalendarEventsForMyCalendarEvent = new SubCalendarEvent[MyCalendarEvent.NumberOfSplit]; for (i = 0; i < TempSubCalendarEventsForMyCalendarEvent.Length; i++)//populates the subevents for the calendar event { TimeSpan MyActiveTimeSpanPerSplit = TimeSpan.FromTicks((long)((MyCalendarEvent.ActiveDuration.Ticks / MyCalendarEvent.NumberOfSplit) )); TempSubCalendarEventsForMyCalendarEvent[i] = new SubCalendarEvent(MyActiveTimeSpanPerSplit, (MyCalendarEvent.End - MyActiveTimeSpanPerSplit), MyCalendarEvent.End, new TimeSpan(), MyCalendarEvent.ID, MyCalendarEvent.Rigid, MyCalendarEvent.myLocation, MyCalendarEvent.RangeTimeLine); TempSubCalendarEventsForMyCalendarEvent[i] = new SubCalendarEvent(TempSubCalendarEventsForMyCalendarEvent[i].ID, TempSubCalendarEventsForMyCalendarEvent[i].Start, TempSubCalendarEventsForMyCalendarEvent[i].End, new BusyTimeLine(TempSubCalendarEventsForMyCalendarEvent[i].ID, TempSubCalendarEventsForMyCalendarEvent[i].Start, TempSubCalendarEventsForMyCalendarEvent[i].End), MyCalendarEvent.Rigid, MyCalendarEvent.myLocation, MyCalendarEvent.RangeTimeLine); MyCalendarEvent.AllEvents[i] = TempSubCalendarEventsForMyCalendarEvent[i]; } } else { throw new Exception("invalid calendar event detected in ReArrangeTimeLineWithinWithinCalendaEventRange. Repat not allowed"); } TimeLine RangeForScheduleUpdate; DateTime EarliestStartTime; DateTime LatestEndTime; Tuple<IEnumerable<SubCalendarEvent>, DateTime> refinedStartTimeAndInterferringEvents; NoneCommitedCalendarEventsEvents.Add(MyCalendarEvent); SubCalendarEvent[] ArrayOfInterferringSubEvents = getInterferringSubEvents(MyCalendarEvent, NoneCommitedCalendarEventsEvents);//It gets all the subevents within the time frame List<SubCalendarEvent> collectionOfInterferringSubCalEvents; EarliestStartTime = ArrayOfInterferringSubEvents.OrderBy(obj => obj.getCalendarEventRange.Start).ToList()[0].getCalendarEventRange.Start; LatestEndTime = ArrayOfInterferringSubEvents.OrderBy(obj => obj.getCalendarEventRange.End).ToList()[ArrayOfInterferringSubEvents.Length - 1].getCalendarEventRange.End; EarliestStartTime = EarliestStartTime < Now ? Now : EarliestStartTime; refinedStartTimeAndInterferringEvents = getStartTimeWhenCurrentTimeClashesWithSubcalevent(ArrayOfInterferringSubEvents, EarliestStartTime); EarliestStartTime = refinedStartTimeAndInterferringEvents.Item2; ArrayOfInterferringSubEvents = refinedStartTimeAndInterferringEvents.Item1.ToArray(); RangeForScheduleUpdate = new TimeLine(EarliestStartTime, LatestEndTime); collectionOfInterferringSubCalEvents = getInterferringSubEvents(RangeForScheduleUpdate, NoneCommitedCalendarEventsEvents).ToList(); //collectionOfInterferringSubCalEvents.Add(MyCalendarEvent.AllEvents[0]);//artificially adds the new rigid event ArrayOfInterferringSubEvents = collectionOfInterferringSubCalEvents.ToArray(); Tuple<TimeLine,IEnumerable<SubCalendarEvent>> allInterferringSubCalEventsAndTimeLine = getAllInterferringEventsAndTimeLineInCurrentEvaluation(ArrayOfInterferringSubEvents, NoneCommitedCalendarEventsEvents, RangeForScheduleUpdate); ArrayOfInterferringSubEvents = allInterferringSubCalEventsAndTimeLine.Item2.ToArray(); RangeForScheduleUpdate=allInterferringSubCalEventsAndTimeLine.Item1; TimeSpan SumOfAllEventsTimeSpan = Utility.SumOfActiveDuration(ArrayOfInterferringSubEvents); /* ArrayOfInterferringSubEvents.OrderBy(obj => obj.End);//SortSubCalendarEvents(ArrayOfInterferringSubEvents.ToList(), false).ToArray(); List<IDefinedRange>[] MyEdgeElements = getEdgeElements(RangeForScheduleUpdate, ArrayOfInterferringSubEvents); EarliestStartTime = MyEdgeElements[0].Count > 0 ? MyEdgeElements[0].OrderBy(obj => obj.Start).ToList()[0].Start : RangeForScheduleUpdate.Start; LatestEndTime = MyEdgeElements[1].Count > 0 ? MyEdgeElements[1].OrderBy(obj => obj.End).ToList()[MyEdgeElements[1].Count - 1].End : RangeForScheduleUpdate.End; EarliestStartTime = EarliestStartTime < Now ? Now : EarliestStartTime; refinedStartTimeAndInterferringEvents = getStartTimeWhenCurrentTimeClashesWithSubcalevent(ArrayOfInterferringSubEvents, EarliestStartTime); EarliestStartTime = refinedStartTimeAndInterferringEvents.Item2; ArrayOfInterferringSubEvents = refinedStartTimeAndInterferringEvents.Item1.ToArray(); RangeForScheduleUpdate = new TimeLine(EarliestStartTime, LatestEndTime); TimeSpan SumOfAllEventsTimeSpan = Utility.SumOfActiveDuration(ArrayOfInterferringSubEvents.ToList());//sum all events while (SumOfAllEventsTimeSpan >= RangeForScheduleUpdate.TimelineSpan)//loops untill the sum all the interferring events can possibly fit within the timeline. Essentially possibly fittable { EarliestStartTime = ArrayOfInterferringSubEvents.OrderBy(obj => obj.getCalendarEventRange.Start).ToList()[0].getCalendarEventRange.Start;//attempts to get subcalevent with a calendarevent with earliest start time LatestEndTime = ArrayOfInterferringSubEvents.OrderBy(obj => obj.getCalendarEventRange.End).ToList()[ArrayOfInterferringSubEvents.Length - 1].getCalendarEventRange.End;//attempts to get subcalevent with a calendarevent with latest Endtime EarliestStartTime = EarliestStartTime < Now ? Now : EarliestStartTime; refinedStartTimeAndInterferringEvents = getStartTimeWhenCurrentTimeClashesWithSubcalevent(ArrayOfInterferringSubEvents, EarliestStartTime); EarliestStartTime = refinedStartTimeAndInterferringEvents.Item2; ArrayOfInterferringSubEvents = refinedStartTimeAndInterferringEvents.Item1.ToArray(); RangeForScheduleUpdate = new TimeLine(EarliestStartTime, LatestEndTime);//updates range of scan collectionOfInterferringSubCalEvents = getInterferringSubEvents(RangeForScheduleUpdate, NoneCommitedCalendarEventsEvents).ToList();//updates interferring events list ArrayOfInterferringSubEvents = collectionOfInterferringSubCalEvents.ToArray(); ArrayOfInterferringSubEvents.OrderBy(obj => obj.End); MyEdgeElements = getEdgeElements(RangeForScheduleUpdate, ArrayOfInterferringSubEvents); EarliestStartTime = MyEdgeElements[0].Count > 0 ? MyEdgeElements[0].OrderBy(obj => obj.Start).ToList()[0].Start : RangeForScheduleUpdate.Start; LatestEndTime = MyEdgeElements[1].Count > 0 ? MyEdgeElements[1].OrderBy(obj => obj.End).ToList()[MyEdgeElements[1].Count - 1].End : RangeForScheduleUpdate.End; EarliestStartTime = EarliestStartTime < Now ? Now : EarliestStartTime; refinedStartTimeAndInterferringEvents = getStartTimeWhenCurrentTimeClashesWithSubcalevent(ArrayOfInterferringSubEvents, EarliestStartTime); EarliestStartTime = refinedStartTimeAndInterferringEvents.Item2; ArrayOfInterferringSubEvents = refinedStartTimeAndInterferringEvents.Item1.ToArray(); RangeForScheduleUpdate = new TimeLine(EarliestStartTime, LatestEndTime); TimeSpan newSumOfAllTimeSpans = Utility.SumOfActiveDuration(ArrayOfInterferringSubEvents.ToList()); if (newSumOfAllTimeSpans == SumOfAllEventsTimeSpan) { throw new Exception("You have events that cannot fit our time frame"); } else { SumOfAllEventsTimeSpan = newSumOfAllTimeSpans; } }*/ Dictionary<CalendarEvent, List<SubCalendarEvent>> DictionaryWithBothCalendarEventIDAndListOfInterferringSubEvents = new Dictionary<CalendarEvent, List<SubCalendarEvent>>(); List<SubCalendarEvent> RigidSubCalendarEvents = new List<SubCalendarEvent>(0); List<BusyTimeLine> RigidSubCalendarEventsBusyTimeLine = new List<BusyTimeLine>(0); RigidSubCalendarEvents = ArrayOfInterferringSubEvents.Where(obj => obj.Rigid).ToList(); RigidSubCalendarEventsBusyTimeLine = RigidSubCalendarEvents.Select(obj => obj.ActiveSlot).ToList(); double OccupancyOfTimeLineSPan = (double)SumOfAllEventsTimeSpan.Ticks / (double)RangeForScheduleUpdate.TimelineSpan.Ticks; ArrayOfInterferringSubEvents = Utility.NotInList(ArrayOfInterferringSubEvents.ToList(), RigidSubCalendarEvents).ToArray();//remove rigid elements //List<CalendarEvent>[]SubEventsTimeCategories= CategorizeSubEventsTimeLine /* * SubEventsTimeCategories has 4 list of containing lists. * 1st is a List with Elements Starting before The Mycalendaervent timeline and ends after the busytimeline * 2nd is a list with elements starting before the mycalendarvent timeline but ending before the myevent timeline * 3rd is a list with elements starting after the Mycalendar event start time but ending after the Myevent timeline * 4th is a list with elements starting after the MyCalendar event start time and ends before the Myevent timeline * */ DictionaryWithBothCalendarEventIDAndListOfInterferringSubEvents = generateDictionaryWithBothCalendarEventIDAndListOfInterferringSubEvents(ArrayOfInterferringSubEvents.ToList(), NoneCommitedCalendarEventsEvents);//generates a dictionary of a Calendar Event and the interferring events in the respective Calendar event //DictionaryWithBothCalendarEventIDAndListOfInterferringSubEvents.Add(MyCalendarEvent, MyCalendarEvent.AllEvents.ToList());//artificially adds enew calendar event to dictionary List<CalendarEvent> SortedInterFerringCalendarEvents_Deadline = DictionaryWithBothCalendarEventIDAndListOfInterferringSubEvents.Keys.ToList(); SortedInterFerringCalendarEvents_Deadline = SortedInterFerringCalendarEvents_Deadline.OrderBy(obj => obj.End).ToList(); TimeLine ReferenceTimeLine = RangeForScheduleUpdate.CreateCopy(); ReferenceTimeLine.AddBusySlots(RigidSubCalendarEventsBusyTimeLine.ToArray());//Adds all the rigid elements TimeLine[] ArrayOfFreeSpots = getOnlyPertinentTimeFrame(getAllFreeSpots_NoCompleteSchedule(ReferenceTimeLine), ReferenceTimeLine).ToArray(); ArrayOfFreeSpots = getOnlyPertinentTimeFrame(ArrayOfFreeSpots, ReferenceTimeLine).ToArray(); Dictionary<TimeLine, List<CalendarEvent>> DictTimeLineAndListOfCalendarevent = new System.Collections.Generic.Dictionary<TimeLine, System.Collections.Generic.List<CalendarEvent>>(); List<List<List<SubCalendarEvent>>> SnugListOfPossibleSubCalendarEventsClumps = BuildAllPossibleSnugLists(SortedInterFerringCalendarEvents_Deadline, MyCalendarEvent, DictionaryWithBothCalendarEventIDAndListOfInterferringSubEvents, ReferenceTimeLine, OccupancyOfTimeLineSPan); //Remember Jerome, I need to implement a functionality that permutates through the various options of pin to start option. So take for example two different event timeline that are pertinent to a free spot however one has a dead line preceeding the other, there will be a pin to start for two scenarios, one for each calendar event in which either of them gets pinned first. List<SubCalendarEvent>SerializedResult=SnugListOfPossibleSubCalendarEventsClumps[0].SelectMany(obj => obj).ToList(); int TotalUpdatedSchedule= SerializedResult.Count+RigidSubCalendarEvents.Count; if (TotalUpdatedSchedule != collectionOfInterferringSubCalEvents.Count) { MyCalendarEvent.UpdateError(new CustomErrors(true, "There is a clash in event")); } NoneCommitedCalendarEventsEvents.Remove(MyCalendarEvent); return EvaluateEachSnugPossibiliyOfSnugPossibility(SnugListOfPossibleSubCalendarEventsClumps, ReferenceTimeLine, MyCalendarEvent); ;//this will not be the final output. I'll need some class that stores the current output of both rearrange busytimelines and deleted timelines }
KeyValuePair<CalendarEvent, TimeLine> ReArrangeClashingEventsofRigid(CalendarEvent MyCalendarEvent, List<CalendarEvent> NoneCommitedCalendarEventsEvents)// this looks at the timeline of the calendar event and then tries to rearrange all subevents within the range to suit final output. Such that there will be sufficient time space for each subevent { /* Name{: Jerome Biotidara * this function is responsible for making sure there is some dynamic allotment of time to the subeevents. It takes a calendarevent of a a rigid event. It attempts to rearrange elements around this event. It detects any clashing events and tries to rearrange any non rigid clashing events */ TimeLine RangeForScheduleUpdate; DateTime EarliestStartTime; DateTime LatestEndTime; //AllEventDictionary.Add(MyCalendarEvent.ID, MyCalendarEvent); NoneCommitedCalendarEventsEvents.Add(MyCalendarEvent); SubCalendarEvent[] ArrayOfInterferringSubEvents = getInterferringSubEvents(MyCalendarEvent, NoneCommitedCalendarEventsEvents);//It gets all the subevents within the time frame Tuple<IEnumerable<SubCalendarEvent>, DateTime> refinedStartTimeAndInterferringEvents; List<SubCalendarEvent> collectionOfInterferringSubCalEvents; if (ArrayOfInterferringSubEvents.Length > 0) { EarliestStartTime = ArrayOfInterferringSubEvents.OrderBy(obj => obj.getCalendarEventRange.Start).ToList()[0].getCalendarEventRange.Start; LatestEndTime = ArrayOfInterferringSubEvents.OrderBy(obj => obj.getCalendarEventRange.End).ToList()[ArrayOfInterferringSubEvents.Length - 1].getCalendarEventRange.End; EarliestStartTime = EarliestStartTime < Now ? Now : EarliestStartTime; refinedStartTimeAndInterferringEvents = getStartTimeWhenCurrentTimeClashesWithSubcalevent(ArrayOfInterferringSubEvents, EarliestStartTime); EarliestStartTime = refinedStartTimeAndInterferringEvents.Item2; ArrayOfInterferringSubEvents = refinedStartTimeAndInterferringEvents.Item1.ToArray(); RangeForScheduleUpdate = new TimeLine(EarliestStartTime, LatestEndTime); collectionOfInterferringSubCalEvents = getInterferringSubEvents(RangeForScheduleUpdate, NoneCommitedCalendarEventsEvents).ToList(); //collectionOfInterferringSubCalEvents.Add(MyCalendarEvent.AllEvents[0]);//artificially adds the new rigid event ArrayOfInterferringSubEvents = collectionOfInterferringSubCalEvents.ToArray(); } else { NoneCommitedCalendarEventsEvents.Remove(MyCalendarEvent);//removes my cal event return new KeyValuePair<CalendarEvent, TimeLine>(null,null); } RangeForScheduleUpdate = new TimeLine(EarliestStartTime, LatestEndTime); Tuple<TimeLine, IEnumerable<SubCalendarEvent>> allInterferringSubCalEventsAndTimeLine = getAllInterferringEventsAndTimeLineInCurrentEvaluation(ArrayOfInterferringSubEvents, NoneCommitedCalendarEventsEvents, RangeForScheduleUpdate); ArrayOfInterferringSubEvents = allInterferringSubCalEventsAndTimeLine.Item2.ToArray(); RangeForScheduleUpdate = allInterferringSubCalEventsAndTimeLine.Item1; TimeSpan SumOfAllEventsTimeSpan = Utility.SumOfActiveDuration(ArrayOfInterferringSubEvents); int i = 0; /* ArrayOfInterferringSubEvents.OrderBy(obj => obj.End);//SortSubCalendarEvents(ArrayOfInterferringSubEvents.ToList(), false).ToArray(); List<IDefinedRange>[] MyEdgeElements = getEdgeElements(RangeForScheduleUpdate, ArrayOfInterferringSubEvents); EarliestStartTime = MyEdgeElements[0].Count > 0 ? MyEdgeElements[0].OrderBy(obj => obj.Start).ToList()[0].Start : RangeForScheduleUpdate.Start; LatestEndTime = MyEdgeElements[1].Count > 0 ? MyEdgeElements[1].OrderBy(obj => obj.End).ToList()[MyEdgeElements[1].Count - 1].End : RangeForScheduleUpdate.End; EarliestStartTime = EarliestStartTime < Now ? Now : EarliestStartTime; refinedStartTimeAndInterferringEvents = getStartTimeWhenCurrentTimeClashesWithSubcalevent(ArrayOfInterferringSubEvents, EarliestStartTime); EarliestStartTime = refinedStartTimeAndInterferringEvents.Item2; ArrayOfInterferringSubEvents = refinedStartTimeAndInterferringEvents.Item1.ToArray(); RangeForScheduleUpdate = new TimeLine(EarliestStartTime, LatestEndTime); TimeSpan SumOfAllEventsTimeSpan = Utility.SumOfActiveDuration(ArrayOfInterferringSubEvents.ToList()); while (SumOfAllEventsTimeSpan >= RangeForScheduleUpdate.TimelineSpan)//loops untill the sum all the interferring events can possibly fit within the timeline. Essentially possibly fittable { EarliestStartTime = ArrayOfInterferringSubEvents.OrderBy(obj => obj.getCalendarEventRange.Start).ToList()[0].getCalendarEventRange.Start;//attempts to get subcalevent with a calendarevent with earliest start time LatestEndTime = ArrayOfInterferringSubEvents.OrderBy(obj => obj.getCalendarEventRange.End).ToList()[ArrayOfInterferringSubEvents.Length - 1].getCalendarEventRange.End;//attempts to get subcalevent with a calendarevent with latest Endtime EarliestStartTime = EarliestStartTime < Now ? Now : EarliestStartTime; refinedStartTimeAndInterferringEvents = getStartTimeWhenCurrentTimeClashesWithSubcalevent(ArrayOfInterferringSubEvents, EarliestStartTime); EarliestStartTime = refinedStartTimeAndInterferringEvents.Item2; ArrayOfInterferringSubEvents = refinedStartTimeAndInterferringEvents.Item1.ToArray(); RangeForScheduleUpdate = new TimeLine(EarliestStartTime, LatestEndTime);//updates range of scan collectionOfInterferringSubCalEvents = getInterferringSubEvents(RangeForScheduleUpdate, NoneCommitedCalendarEventsEvents).ToList();//updates interferring events list ArrayOfInterferringSubEvents = collectionOfInterferringSubCalEvents.ToArray(); ArrayOfInterferringSubEvents.OrderBy(obj => obj.End); MyEdgeElements = getEdgeElements(RangeForScheduleUpdate, ArrayOfInterferringSubEvents); EarliestStartTime = MyEdgeElements[0].Count > 0 ? MyEdgeElements[0].OrderBy(obj => obj.Start).ToList()[0].Start : RangeForScheduleUpdate.Start; LatestEndTime = MyEdgeElements[1].Count > 0 ? MyEdgeElements[1].OrderBy(obj => obj.End).ToList()[MyEdgeElements[1].Count - 1].End : RangeForScheduleUpdate.End; EarliestStartTime = EarliestStartTime < Now ? Now : EarliestStartTime; refinedStartTimeAndInterferringEvents = getStartTimeWhenCurrentTimeClashesWithSubcalevent(ArrayOfInterferringSubEvents, EarliestStartTime); EarliestStartTime = refinedStartTimeAndInterferringEvents.Item2; ArrayOfInterferringSubEvents = refinedStartTimeAndInterferringEvents.Item1.ToArray(); RangeForScheduleUpdate = new TimeLine(EarliestStartTime, LatestEndTime); SumOfAllEventsTimeSpan = Utility.SumOfActiveDuration(ArrayOfInterferringSubEvents.ToList()); }*/ Dictionary<CalendarEvent, List<SubCalendarEvent>> DictionaryWithBothCalendarEventIDAndListOfInterferringSubEvents = new Dictionary<CalendarEvent, List<SubCalendarEvent>>(); List<SubCalendarEvent> RigidSubCalendarEvents = new List<SubCalendarEvent>(0); RigidSubCalendarEvents = ArrayOfInterferringSubEvents.Where(obj => obj.Rigid).ToList(); List<BusyTimeLine> RigidSubCalendarEventsBusyTimeLine = new List<BusyTimeLine>(0); RigidSubCalendarEventsBusyTimeLine = RigidSubCalendarEvents.Select(obj => obj.ActiveSlot).ToList(); i = 0; double OccupancyOfTimeLineSPan = (double)SumOfAllEventsTimeSpan.Ticks / (double)RangeForScheduleUpdate.TimelineSpan.Ticks; ArrayOfInterferringSubEvents = Utility.NotInList(ArrayOfInterferringSubEvents.ToList(), RigidSubCalendarEvents).ToArray();//removes rigid elements DictionaryWithBothCalendarEventIDAndListOfInterferringSubEvents = generateDictionaryWithBothCalendarEventIDAndListOfInterferringSubEvents(ArrayOfInterferringSubEvents.ToList(), NoneCommitedCalendarEventsEvents); List<CalendarEvent> SortedInterFerringCalendarEvents_Deadline = DictionaryWithBothCalendarEventIDAndListOfInterferringSubEvents.Keys.ToList(); SortedInterFerringCalendarEvents_Deadline = SortedInterFerringCalendarEvents_Deadline.OrderBy(obj => obj.End).ToList(); TimeLine ReferenceTimeLine = RangeForScheduleUpdate.CreateCopy(); ReferenceTimeLine.AddBusySlots(RigidSubCalendarEventsBusyTimeLine.ToArray());//Adds all the rigid elements TimeLine[] ArrayOfFreeSpots = getOnlyPertinentTimeFrame(getAllFreeSpots_NoCompleteSchedule(ReferenceTimeLine), ReferenceTimeLine).ToArray(); ArrayOfFreeSpots = getOnlyPertinentTimeFrame(ArrayOfFreeSpots, ReferenceTimeLine).ToArray(); Dictionary<TimeLine, List<CalendarEvent>> DictTimeLineAndListOfCalendarevent = new System.Collections.Generic.Dictionary<TimeLine, System.Collections.Generic.List<CalendarEvent>>(); List<List<List<SubCalendarEvent>>> SnugListOfPossibleSubCalendarEventsClumps = BuildAllPossibleSnugLists(SortedInterFerringCalendarEvents_Deadline, MyCalendarEvent, DictionaryWithBothCalendarEventIDAndListOfInterferringSubEvents, ReferenceTimeLine,OccupancyOfTimeLineSPan); //Remember Jerome, I need to implement a functionality that permutates through the various options of pin to start option. So take for example two different event timeline that are pertinent to a free spot however one has a dead line preceeding the other, there will be a pin to start for two scenarios, one for each calendar event in which either of them gets pinned first. NoneCommitedCalendarEventsEvents.Remove(MyCalendarEvent); return EvaluateEachSnugPossibiliyOfSnugPossibility(SnugListOfPossibleSubCalendarEventsClumps, ReferenceTimeLine, MyCalendarEvent); }
KeyValuePair<CalendarEvent, TimeLine> EvaluateEachSnugPossibiliyOfSnugPossibility(List<List<List<SubCalendarEvent>>> SnugPossibilityPermutation, TimeLine ReferenceTimeLine, CalendarEvent ReferenceCalendarEvent) { TimeLine CopyOfReferenceTimeLine; List<TimeLine> SnugPossibilityTimeLine = new System.Collections.Generic.List<TimeLine>(); Dictionary<BusyTimeLine, SubCalendarEvent> MyBusyTimeLineToSubCalendarEventDict = new System.Collections.Generic.Dictionary<BusyTimeLine, SubCalendarEvent>(); foreach (List<List<SubCalendarEvent>> SnugPermutation in SnugPossibilityPermutation)//goes each permutation of snug possibility generated { CopyOfReferenceTimeLine = ReferenceTimeLine.CreateCopy(); //SnugPossibilityTimeLine.Add(CopyOfReferenceTimeLine); List<TimeLine> ListOfFreeSpots=getOnlyPertinentTimeFrame(getAllFreeSpots_NoCompleteSchedule(CopyOfReferenceTimeLine), CopyOfReferenceTimeLine); List<SubCalendarEvent> ReassignedSubEvents = new System.Collections.Generic.List<SubCalendarEvent>(); for (int i=0; i<ListOfFreeSpots.Count;i++) { DateTime RelativeStartTime = ListOfFreeSpots[i].Start; foreach (SubCalendarEvent MySubCalendarEvent in SnugPermutation[i]) { SubCalendarEvent CopyOfMySubCalendarEvent = MySubCalendarEvent.createCopy(); TimeSpan MySubCalendarDuration = (CopyOfMySubCalendarEvent.End - CopyOfMySubCalendarEvent.Start); DateTime RelativeEndtime = RelativeStartTime + MySubCalendarDuration; CopyOfMySubCalendarEvent.ReassignTime(RelativeStartTime, RelativeEndtime); CopyOfMySubCalendarEvent.ActiveSlot = new BusyTimeLine(CopyOfMySubCalendarEvent.ID, RelativeStartTime, RelativeEndtime);//Note this is a hack to resolve the reassignment of time since we dont know currently know the distiction between BusyTimeLine and SubCalendarEvent(TimeLine) TimeLine MyTimeLine=CopyOfMySubCalendarEvent.EventTimeLine; CopyOfReferenceTimeLine.MergeTimeLines(MyTimeLine); RelativeStartTime = CopyOfMySubCalendarEvent.End; MyBusyTimeLineToSubCalendarEventDict.Add(CopyOfMySubCalendarEvent.ActiveSlot, CopyOfMySubCalendarEvent); } } SnugPossibilityTimeLine.Add(CopyOfReferenceTimeLine); } Dictionary<CalendarEvent, TimeLine> CalendarEvent_EvaluationIndexDict = new System.Collections.Generic.Dictionary<CalendarEvent, TimeLine>(); Dictionary<string, double> DictionaryGraph = new System.Collections.Generic.Dictionary<string, double>(); foreach (TimeLine MyTimeLine in SnugPossibilityTimeLine) { CalendarEvent MyEventCopy=ReferenceCalendarEvent.createCopy(); foreach (BusyTimeLine MyBusyPeriod in MyTimeLine.OccupiedSlots) { EventID MyEventID = new EventID(MyBusyPeriod.TimeLineID); string ParentCalendarEventID = MyEventID.getLevelID(0); if (MyEventCopy.ID == ParentCalendarEventID) { SubCalendarEvent MySubCalendarEvent=MyBusyTimeLineToSubCalendarEventDict[MyBusyPeriod]; for (int i = 0; i < MyEventCopy.AllEvents.Length; i++) { if (MyEventCopy.AllEvents[i].ID == MySubCalendarEvent.ID) { MyEventCopy.AllEvents[i] = MySubCalendarEvent; break; } } } } //MyEventCopy=EvaluateTotalTimeLineAndAssignValidTimeSpotsWithReferenceTimeLine(MyEventCopy, MyTimeLine); CalendarEvent_EvaluationIndexDict.Add(MyEventCopy, MyTimeLine); } double HighestValue=0; KeyValuePair<CalendarEvent, TimeLine> FinalSuggestion = new System.Collections.Generic.KeyValuePair<CalendarEvent,TimeLine>(); TimeLine TimeLineUpdated = null; Dictionary<string, double> LocationVector = new System.Collections.Generic.Dictionary<string,double>(); LocationVector.Add("sameElement", 10000000000); foreach (KeyValuePair<CalendarEvent, TimeLine> MyCalendarEvent_TimeLine in CalendarEvent_EvaluationIndexDict) { int RandomIndex = EvaluateRandomNetIndex(MyCalendarEvent_TimeLine.Value); RandomIndex = 0; LocationVector=BuildDictionaryDistanceEdge(MyCalendarEvent_TimeLine.Value, MyCalendarEvent_TimeLine.Key, LocationVector); double ClumpIndex = EvaluateClumpingIndex(MyCalendarEvent_TimeLine.Value, LocationVector); ClumpIndex = 1 / ClumpIndex; double EvaluationSum = ClumpIndex + RandomIndex; if (EvaluationSum < 0) { EvaluationSum *= -1; } if ( EvaluationSum > HighestValue) { HighestValue = EvaluationSum; FinalSuggestion = MyCalendarEvent_TimeLine; } } if (FinalSuggestion.Equals(new KeyValuePair<CalendarEvent,TimeLine>())) { MessageBox.Show("Oh oh J, you'll need to look outside this range...Think of moving other events out of white box space"); } return FinalSuggestion; }
List<SubCalendarEvent> resolveInTo24HourSlots(List<SubCalendarEvent> currentListOfSubCalendarElements, TimeLine limitingTimeLine, mTuple<SubCalendarEvent,SubCalendarEvent>edgeElements=null) { //function takes a full freespot and tries to spread it out into 24 hour sections //this is done by intially sending every subcalevenet towards the end of the Timeline after which it takes 24hour chunks and attempts to List<SubCalendarEvent> currentListOfSubCalendarElements_cpy = currentListOfSubCalendarElements.ToList(); Utility.PinSubEventsToStart(currentListOfSubCalendarElements_cpy, limitingTimeLine); TimeLine limitingTimeLine_cpy = limitingTimeLine.CreateCopy(); limitingTimeLine.AddBusySlots(currentListOfSubCalendarElements_cpy.Select(obj => obj.ActiveSlot)); List<TimeLineWithEdgeElements> AllFreeSpots = limitingTimeLine_cpy.getAllFreeSlotsWithEdges().ToList(); AllFreeSpots=AllFreeSpots.Where(obj => obj.TimelineSpan.Ticks > 0).OrderBy(obj=>obj.End).ToList(); for (int i = AllFreeSpots.Count() - 1; AllFreeSpots.Count() > 0; ) { TimeLine eachTimeLine = AllFreeSpots[i]; List<SubCalendarEvent> reassignedElements = TossEndWards(currentListOfSubCalendarElements, eachTimeLine);//tries to toss any subcalendarevent towards the end reassignedElements=reassignedElements.OrderBy(obj => obj.End).ToList(); Utility.PinSubEventsToEnd(reassignedElements, eachTimeLine); SubCalendarEvent lastElement;// = reassignedElements.Last(); currentListOfSubCalendarElements.RemoveAll(obj => reassignedElements.Contains(obj)); if (reassignedElements.Count > 0) { lastElement = reassignedElements.First(); limitingTimeLine = new TimeLine(limitingTimeLine.Start, lastElement.Start); } else { currentListOfSubCalendarElements.OrderBy(obj => obj.End); if (currentListOfSubCalendarElements.Count > 0)//hack alert you need to coscious of coliision scenario { lastElement = currentListOfSubCalendarElements.Last(); lastElement.PinToEnd(limitingTimeLine); currentListOfSubCalendarElements.Remove(lastElement); limitingTimeLine = new TimeLine(limitingTimeLine.Start, lastElement.Start); } else { break; } } Utility.PinSubEventsToStart(currentListOfSubCalendarElements, limitingTimeLine); limitingTimeLine.AddBusySlots(currentListOfSubCalendarElements.Select(obj => obj.ActiveSlot)); AllFreeSpots = limitingTimeLine.getAllFreeSlotsWithEdges().ToList(); i = AllFreeSpots.Count() - 1; } TimeSpan TotalDuration = Utility.SumOfActiveDuration(currentListOfSubCalendarElements_cpy); double Occupancy = (double)TotalDuration.Ticks / (double)limitingTimeLine_cpy.TimelineSpan.Ticks; List<SubCalendarEvent> currentListOfSubCalendarElements_cpy_ref = currentListOfSubCalendarElements_cpy.ToList(); Dictionary<string, mTuple<SubCalendarEvent, BusyTimeLine>> currentListOfSubCalendarElements_cpy_ref_Dict = currentListOfSubCalendarElements_cpy_ref.ToDictionary(obj => obj.ID, obj => new mTuple<SubCalendarEvent, BusyTimeLine>(obj, obj.ActiveSlot.CreateCopy())); TimeLine limitingTimeLine_cpy_cpy_ref = limitingTimeLine_cpy.CreateCopy(); List<SubCalendarEvent> FullyUpdated = new List<SubCalendarEvent>(); while(true) { Tuple<List<SubCalendarEvent>, TimeLine> CollectionUpdated = every24Interval(currentListOfSubCalendarElements_cpy_ref, limitingTimeLine_cpy_cpy_ref, Occupancy, currentListOfSubCalendarElements_cpy_ref_Dict); TimeSpan currTotalDuration = Utility.SumOfActiveDuration(CollectionUpdated.Item1); double currOccupancy =-8898; if(CollectionUpdated.Item2.TimelineSpan.Ticks>0) { currOccupancy = (double)currTotalDuration.Ticks / (double)CollectionUpdated.Item2.TimelineSpan.Ticks; } if (currOccupancy > Occupancy) { ; } FullyUpdated.AddRange(CollectionUpdated.Item1); limitingTimeLine_cpy_cpy_ref = new TimeLine(CollectionUpdated.Item2.End, limitingTimeLine_cpy_cpy_ref.End); currentListOfSubCalendarElements_cpy_ref.RemoveAll(obj => FullyUpdated.Contains(obj)); if ((currentListOfSubCalendarElements_cpy_ref.Count < 1) || (limitingTimeLine_cpy_cpy_ref.TimelineSpan.Ticks <= 0)) { break; } } currentListOfSubCalendarElements_cpy = currentListOfSubCalendarElements_cpy.OrderBy(obj => obj.End).ToList(); List<SubCalendarEvent> retValue = currentListOfSubCalendarElements_cpy; return retValue; }