private void SearchLast(FreeSlot freeSlot) { PriorityListSecond = PriorityListSecond .OrderByDescending(u => u.MaximumTime) .ThenByDescending(u => u.MinimumTime) .ToList(); foreach (var undefinedActivity in PriorityListSecond) { if (IsCoverFull(freeSlot, undefinedActivity)) { var newItem = new FlexibleActivityItem(undefinedActivity, freeSlot.Start, freeSlot.End); freeSlot.BestResultLast.ResultList.Add(newItem); break; } else { if (Fit(freeSlot, undefinedActivity)) { var newStart = freeSlot.Start; var newItem = new FlexibleActivityItem(undefinedActivity, newStart, newStart + TimeSpan.FromMinutes(undefinedActivity.MaximumTime)); freeSlot.BestResultLast.ResultList.Add(newItem); freeSlot.Start = newStart + TimeSpan.FromMinutes(undefinedActivity.MaximumTime) + Break; } } } foreach (var result in freeSlot.BestResultLast.ResultList) { PriorityListSecond.Remove(result.UndefinedActivity); } }
private void UpdateBestResultAfterDivide(FreeSlot freeSlot, BestResultForMainSearch result) { BestResultForMainSearch newBestResult = new BestResultForMainSearch(new List <IDefinedActivity>(result.ResultList), Break); if (newBestResult.CoverTime > freeSlot.BestResultFirst.CoverTime) { freeSlot.BestResultFirst = newBestResult; } }
private void UpdateBestResult(FreeSlot freeSlot) { BestResultForMainSearch bestResult = new BestResultForMainSearch(new List <IDefinedActivity>(freeSlot.tmpActivitiesFirst), Break); if (freeSlot.BestResultFirst.CoverTime < bestResult.CoverTime) { freeSlot.BestResultFirst = bestResult; } }
private bool FirstRecursion(List <IDefinedActivity> sourceActivities, FreeSlot freeSlot, bool remove = true) { foreach (var activity in sourceActivities) { if (Fit(activity, freeSlot, freeSlot.tmpActivitiesFirst)) { bool isFixed = InsertItem(activity, freeSlot); UpdateBestResult(freeSlot); if (IsFinished(freeSlot)) { return(true); } if (isFixed) { var dividedTimes = DivideFreeSlotsIntoTwoParts(freeSlot, freeSlot.tmpActivitiesFirst); var tmpBestResult = new BestResultForMainSearch(new List <IDefinedActivity>(), Break); tmpBestResult.ResultList.AddRange(freeSlot.tmpActivitiesFirst); foreach (var time in dividedTimes) { List <IDefinedActivity> saved = freeSlot.tmpActivitiesFirst; FirstRecursion(GetRemainingItemsFix(sourceActivities, freeSlot.tmpActivitiesFirst).ToList(), time, true); tmpBestResult.ResultList.AddRange(time.BestResultFirst.ResultList); freeSlot.tmpActivitiesFirst = saved.Concat(time.BestResultFirst.ResultList).ToList(); } UpdateBestResultAfterDivide(freeSlot, tmpBestResult); } else { var saved = freeSlot.tmpActivitiesFirst; if (FirstRecursion(GetRemainingItems(sourceActivities, freeSlot.tmpActivitiesFirst).ToList(), freeSlot, false)) { return(true); } freeSlot.tmpActivitiesFirst = saved; } if (remove) { freeSlot.tmpActivitiesFirst.Clear(); } else { freeSlot.tmpActivitiesFirst.RemoveAt(freeSlot.tmpActivitiesFirst.Count - 1); } } } return(false); }
private bool InsertItem(IDefinedActivity activity, FreeSlot freeSlot) { var isFixed = activity is FixedActivity; if (isFixed) { freeSlot.tmpActivitiesFirst.Add(activity); } else { activity.Start = freeSlot.Start + GetTimeSpanOfItems(freeSlot.tmpActivitiesFirst); freeSlot.tmpActivitiesFirst.Add(activity); } return(isFixed); }
private bool Fit(IDefinedActivity activity, FreeSlot frame, List <IDefinedActivity> temporaryStorage) { //Check if the FixActivity is insertable because of the ufas are in the tmpStorage var totalTimeSpan = GetTimeSpanOfItems(temporaryStorage); if (activity is FixedActivity) { var fixedActivity = activity as FixedActivity; return(fixedActivity.Start >= frame.Start && fixedActivity.End <= frame.End && fixedActivity.Start.Value.TimeOfDay > totalTimeSpan); } else { UnfixedActivity unfixedActivity = activity as UnfixedActivity; return(frame.RemainingTimeSpan >= unfixedActivity.TimeSpan); } }
private List <FreeSlot> DivideFreeSlotsIntoTwoParts(FreeSlot baseFreeSlots, List <IDefinedActivity> temporaryActivitiesList) { List <FreeSlot> newFreeSlotList = new List <FreeSlot>(); var insertedActivity = temporaryActivitiesList .Where(a => a is FixedActivity) .FirstOrDefault() as FixedActivity; var endOfTemporaryItems = baseFreeSlots.Start + GetTimeSpanOfItems(temporaryActivitiesList); if (endOfTemporaryItems < insertedActivity.Start - Break) //There are a freeTime before the fixedActivity { newFreeSlotList.Add(new FreeSlot(endOfTemporaryItems, insertedActivity.Start.Value - Break, Break)); } if (insertedActivity.End + Break < baseFreeSlots.End) { newFreeSlotList.Add(new FreeSlot(insertedActivity.End + Break, baseFreeSlots.End, Break)); } return(newFreeSlotList); }
private Tree <FreeSlot> SearchFirst(int priority, FreeSlot freeSlot) //Seach the best option for a freeTime section { List <IDefinedActivity> selectedActivities; var tree = new Tree <FreeSlot>(priority, freeSlot); for (int i = 0; i < tree.Count; i++) { selectedActivities = GetItemOnPriorityLevel(priority); //Contains the items which have the highest priority value FirstRecursion(selectedActivities, tree[i].Value); //A specified priority level priority = GetNextPriority(priority); if (priority == -1) { break; } var dividedFreeTimeList = DivideFreeSlot(tree[i].Value, tree[i].Value.BestResultFirst.ResultList.ToList()); tree[i].Leaves.AddRange(dividedFreeTimeList.Select(fs => new Leaf <FreeSlot>(priority, fs))); } return(tree); }
private TimeSpan GetUndefinedActivityTimeSpan(FreeSlot freeSlot) { var sum = freeSlot.BestResultLast.ResultList.Sum(x => x.TimeSpan.TotalMinutes + freeSlot.Break.TotalMinutes); return(TimeSpan.FromMinutes(sum)); }
private bool IsCoverFull(FreeSlot freeSlot, UndefinedActivity undefinedActivity) { return(Fit(freeSlot, undefinedActivity) && freeSlot.RemainingTimeSpan <= TimeSpan.FromMinutes(undefinedActivity.MaximumTime)); }
private bool Fit(FreeSlot freeSlot, UndefinedActivity undefinedActivity) { return(freeSlot.RemainingTimeSpan >= TimeSpan.FromMinutes(undefinedActivity.MinimumTime)); }
private List <FreeSlot> DivideFreeSlot(FreeSlot baseFreeSlot, List <IDefinedActivity> bestResultList, bool first = true) { if (bestResultList.Count == 0) { return new List <FreeSlot>() { new FreeSlot(baseFreeSlot.Start, baseFreeSlot.End, Break, first) } } ; var unfixedActivities = bestResultList.Where(a => a is UnfixedActivity).Select(a => a as UnfixedActivity); var activitiesWithStartValue = bestResultList.Where(a => a is FixedActivity).ToList(); var dictionary = new Dictionary <DateTime, List <UnfixedActivity> >(); foreach (var item in unfixedActivities) { if (!dictionary.ContainsKey(item.Start.GetValueOrDefault())) { dictionary[item.Start.GetValueOrDefault()] = new List <UnfixedActivity>(); } dictionary[item.Start.GetValueOrDefault()].Add(item); } foreach (var key in dictionary.Keys) { var time = key; foreach (var activity in dictionary[key]) { activity.Start = time; activitiesWithStartValue.Add(activity); time = time + activity.TimeSpan + Break; } } activitiesWithStartValue = activitiesWithStartValue.OrderBy(x => x.Start).ToList(); var freeTimeList = new List <FreeSlot>(); DateTime currentTime; if (activitiesWithStartValue.First().Start > baseFreeSlot.Start) { currentTime = baseFreeSlot.Start; } else { currentTime = activitiesWithStartValue.First().Start.GetValueOrDefault() + activitiesWithStartValue.First().TimeSpan + Break; } foreach (var result in activitiesWithStartValue) { if ((result.Start - Break) > currentTime) { freeTimeList.Add(new FreeSlot(currentTime, result.Start.GetValueOrDefault() - Break, Break, first)); } currentTime = result.Start.GetValueOrDefault() + result.TimeSpan + Break; if (currentTime >= baseFreeSlot.End) { break; } } if (currentTime < baseFreeSlot.End) { freeTimeList.Add(new FreeSlot(currentTime, baseFreeSlot.End, Break, first)); } return(freeTimeList); }
private bool IsFinished(FreeSlot freeSlot) { return(freeSlot.BestResultFirst.CoverTime == freeSlot.FullTimeSpan); }