public List<TimeLine> getOnlyPertinentTimeFrame(TimeLine[] ArraytOfFreeSpots, TimeLine myTimeLine) { /* * Name: Jerome Biotidara * Description: Function only takes a TImeLine and Array Of TimeLine FreeSpots. It returns a List Of TimeLine In whcih each elements exist within the range of TimeLine */ List<TimeLine> PertinentTimeLine = new List<TimeLine>(); List<TimeLine> OutLiers = new List<TimeLine>(); foreach (TimeLine MyFreeTimeLine in ArraytOfFreeSpots) { if (myTimeLine.IsTimeLineWithin(MyFreeTimeLine)) { PertinentTimeLine.Add(MyFreeTimeLine); } else { OutLiers.Add(MyFreeTimeLine); } } foreach (TimeLine Outlier in OutLiers)//this can be embedded in the preceeding foreach loop above in the else branch { if (myTimeLine.IsDateTimeWithin(Outlier.Start)) { PertinentTimeLine.Add(new TimeLine(Outlier.Start, myTimeLine.End)); } else { if (myTimeLine.IsDateTimeWithin(Outlier.End)) { PertinentTimeLine.Add(new TimeLine(myTimeLine.Start, Outlier.End)); } else { if (Outlier.IsTimeLineWithin(myTimeLine)) { PertinentTimeLine.Add(Outlier); } } } } return PertinentTimeLine; //return new List<TimeLine>(); }
virtual public TimeLine PinToEnd(TimeLine MyTimeLine, List<SubCalendarEvent> MySubCalendarEventList) { /* *Name: Jerome Biotidara *Description: This funciton is only called when the Timeline can fit the total timeline ovcupied by the Subcalendarevent. essentially it tries to pin itself to the last available spot */ TimeSpan SubCalendarTimeSpan = new TimeSpan(); foreach (SubCalendarEvent MySubCalendarEvent in MySubCalendarEventList) { SubCalendarTimeSpan.Add(MySubCalendarEvent.ActiveSlot.BusyTimeSpan);// you might be able to combine the implementing for lopp with this in order to avoid several loops } if (SubCalendarTimeSpan > MyTimeLine.TimelineSpan) { throw new Exception("Oh oh check PinSubEventsToEnd Subcalendar is longer than timeline"); } if (!MyTimeLine.IsDateTimeWithin(Start)) { throw new Exception("Oh oh Calendar event isn't within Timeline range. Check PinSubEventsToEnd :("); } DateTime ReferenceTime = new DateTime(); if (End > MyTimeLine.End) { ReferenceTime = MyTimeLine.End; } else { ReferenceTime = End; } List<BusyTimeLine> MyActiveSlot = new List<BusyTimeLine>(); foreach (SubCalendarEvent MySubCalendarEvent in MySubCalendarEventList) { MySubCalendarEvent.PinToEndAndIncludeInTimeLine(MyTimeLine, this);//hack you need to handle cases where you cant shift subcalevent } return MyTimeLine; }
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; }