List<mTuple<bool, SubCalendarEvent>> stitchUnRestrictedSubCalendarEvent_NonAggressive(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)//stops restricted elements from being used in caslculation { 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<mTuple<bool, SubCalendarEvent>> restOfrestrictedSnugFitAvailable = new List<mTuple<bool, SubCalendarEvent>>(); IEnumerable<SubCalendarEvent> selectedRestrictedElements; 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; Tuple<DateTime, List<SubCalendarEvent>> TimeLineUpdated = null; SubCalendarEvent BorderElementBeginning = null; SubCalendarEvent BorderElementEnd = null; SubCalendarEvent LastSubCalElementForEarlierReferenceTime = null; int a = restrictedSnugFitAvailable.Count; int previ = i; Utility.PinSubEventsToEnd(restrictedSnugFitAvailable.Select(obj => obj.Item2).ToList(), FreeBoundary); bool ignorePlaceRestrictedinBestPosition = false; for (; i < restrictedSnugFitAvailable.Count; i++) { //bool isFreeSpotBeforeRigid = AllFreeSpots[i].End <= restrictedSnugFitAvailable[i].Item2.Start; TimeLineUpdated = null; previ = i; //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++)//for loop tries to prioritize the front partial elements as the boundary of the calculation of fittable elements. { TimeLineUpdated = null; DateTime PertinentFreeSpotStart = EarliestReferenceTIme; DateTime PertinentFreeSpotEnd; if ((ListOfFrontPartialsStartTime[FrontPartialCounter] < RestrictedStopper)) { PertinentFreeSpotEnd = ListOfFrontPartialsStartTime[FrontPartialCounter]; ListOfFrontPartialsStartTime.RemoveAt(FrontPartialCounter); --FrontPartialCounter; PreserveRestrictedIndex = true; } else { PertinentFreeSpotEnd = RestrictedStopper; if (breakForLoop) {//this allows for the population or insertion of the restrictedSnugFitAvailable[i]. Within the enclosing for loop the restrictedSnugFitAvailable[i] never gets appended until this point. 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 restOfrestrictedSnugFitAvailable = new List<mTuple<bool, SubCalendarEvent>>(); for (int q = i; q < restrictedSnugFitAvailable.Count; q++) { restOfrestrictedSnugFitAvailable.Add(restrictedSnugFitAvailable[q]); } selectedRestrictedElements = LowestCostArrangement.Intersect(restOfrestrictedSnugFitAvailable.Select(obj => obj.Item2)); if (selectedRestrictedElements.Count() > 0) { if (selectedRestrictedElements.Contains(restrictedSnugFitAvailable[i].Item2)) { ignorePlaceRestrictedinBestPosition = true;//forces the call to PlaceSubCalEventInLowestCostPosition to be ignored. THis is needed if one of the elements in selected restricted elements is the current restrictedSnugFitAvailable } restrictedSnugFitAvailable.RemoveAll(obj => selectedRestrictedElements.Contains(obj.Item2)); } LowestCostArrangement = OptimizeArrangeOfSubCalEvent_NonAggressive(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, restOfrestrictedSnugFitAvailable, Occupancy); //LowestCostArrangement = OptimizeArrangeOfSubCalEvent_NonAggressive(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, restrictedSnugFitAvailable,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) { if (!selectedRestrictedElements.Contains(eachSubCalendarEvent)) { --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(); if (!ignorePlaceRestrictedinBestPosition) { LowestCostArrangement = PlaceSubCalEventInLowestCostPosition(FreeBoundary, restrictedSnugFitAvailable[i].Item2, LowestCostArrangement); } ignorePlaceRestrictedinBestPosition = false; Utility.PinSubEventsToStart(LowestCostArrangement, FreeBoundary); CompleteArranegement = LowestCostArrangement; EarliestReferenceTIme = LowestCostArrangement[LowestCostArrangement.Count - 1].End; PreserveRestrictedIndex = false; break; } /*restOfrestrictedSnugFitAvailable = new List<mTuple<bool, SubCalendarEvent>>(); for (int q = i+1; q < restrictedSnugFitAvailable.Count; q++) { restOfrestrictedSnugFitAvailable.Add(restrictedSnugFitAvailable[q]); }*/ //if (restOfrestrictedSnugFitAvailable.Count > 0) { //Utility.PinSubEventsToEnd(restOfrestrictedSnugFitAvailable.Select(obj=>obj.Item2).ToList(), FreeBoundary); --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 restOfrestrictedSnugFitAvailable = new List<mTuple<bool, SubCalendarEvent>>(); for (int q = i; q < restrictedSnugFitAvailable.Count; q++) { restOfrestrictedSnugFitAvailable.Add(restrictedSnugFitAvailable[q]); } LowestCostArrangement = OptimizeArrangeOfSubCalEvent_NonAggressive(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, restOfrestrictedSnugFitAvailable, Occupancy); selectedRestrictedElements = LowestCostArrangement.Intersect(restOfrestrictedSnugFitAvailable.Select(obj => obj.Item2)); if (selectedRestrictedElements.Count() > 0) { } LowestCostArrangement = OptimizeArrangeOfSubCalEvent_NonAggressive(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, restrictedSnugFitAvailable, 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 restOfrestrictedSnugFitAvailable = new List<mTuple<bool, SubCalendarEvent>>(); for (int q = i; q < restrictedSnugFitAvailable.Count; q++) { restOfrestrictedSnugFitAvailable.Add(restrictedSnugFitAvailable[q]); } LowestCostArrangement = OptimizeArrangeOfSubCalEvent_NonAggressive(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, restOfrestrictedSnugFitAvailable, Occupancy); selectedRestrictedElements = LowestCostArrangement.Intersect(restOfrestrictedSnugFitAvailable.Select(obj => obj.Item2)); if (selectedRestrictedElements.Count() > 0) { ; } 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>(); DateTime RelativeEndTime; if (j < restrictedSnugFitAvailable.Count) { //DateTime StartDateTimeAfterFitting = PertinentFreeSpot.End; DateTime StartDateTimeAfterFitting = EarliestReferenceTIme;//this is the barring end time of the preceding boundary search. Earliest would have been updated if there was some event detected. 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 restOfrestrictedSnugFitAvailable = new List<mTuple<bool, SubCalendarEvent>>(); for (int q = i; q < restrictedSnugFitAvailable.Count; q++) { restOfrestrictedSnugFitAvailable.Add(restrictedSnugFitAvailable[q]); } AdditionalCOstArrangement = OptimizeArrangeOfSubCalEvent_NonAggressive(CurrentlyFittedTimeLine, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, restOfrestrictedSnugFitAvailable, Occupancy); selectedRestrictedElements = AdditionalCOstArrangement.Intersect(restOfrestrictedSnugFitAvailable.Select(obj => obj.Item2)); if (selectedRestrictedElements.Count() > 0) { ; } AdditionalCOstArrangement = OptimizeArrangeOfSubCalEvent_NonAggressive(CurrentlyFittedTimeLine, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, restrictedSnugFitAvailable, 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; ; CurrentlyFittedTimeLine = new TimeLine(FreeSpotUpdated.Start, RelativeEndTime); //AdditionalCOstArrangement = PlaceSubCalEventInLowestCostPosition(CurrentlyFittedTimeLine, 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 { 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); } CompleteArranegement.AddRange(LowestCostArrangement); CompleteArranegement.AddRange(AdditionalCOstArrangement); TimeLine encasingTimeLine = new TimeLine(FreeBoundary.Start, RelativeEndTime); CompleteArranegement = PlaceSubCalEventInLowestCostPosition(encasingTimeLine, restrictedSnugFitAvailable[i].Item2, CompleteArranegement); 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; restOfrestrictedSnugFitAvailable = new List<mTuple<bool, SubCalendarEvent>>(); for (int q = i; q < restrictedSnugFitAvailable.Count; q++) { restOfrestrictedSnugFitAvailable.Add(restrictedSnugFitAvailable[q]); } LowestCostArrangement = OptimizeArrangeOfSubCalEvent_NonAggressive(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, restOfrestrictedSnugFitAvailable, Occupancy); selectedRestrictedElements = LowestCostArrangement.Intersect(restOfrestrictedSnugFitAvailable.Select(obj => obj.Item2)); if (selectedRestrictedElements.Count() > 0) { ; } LowestCostArrangement = OptimizeArrangeOfSubCalEvent_NonAggressive(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, restrictedSnugFitAvailable, 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; restOfrestrictedSnugFitAvailable = new List<mTuple<bool, SubCalendarEvent>>(); for (int q = i; q < restrictedSnugFitAvailable.Count; q++) { restOfrestrictedSnugFitAvailable.Add(restrictedSnugFitAvailable[q]); } LowestCostArrangement = OptimizeArrangeOfSubCalEvent_NonAggressive(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, restOfrestrictedSnugFitAvailable, Occupancy); selectedRestrictedElements = LowestCostArrangement.Intersect(restOfrestrictedSnugFitAvailable.Select(obj => obj.Item2)); if (selectedRestrictedElements.Count() > 0) { ; } LowestCostArrangement = OptimizeArrangeOfSubCalEvent_NonAggressive(PertinentFreeSpot, new Tuple<SubCalendarEvent, SubCalendarEvent>(BorderElementBeginning, BorderElementEnd), CompatibleWithList.Values.ToList(), PossibleEntries_Cpy, restrictedSnugFitAvailable, 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; }