private List <LvCombination> GetLvCombinations(IProgress <double> progressPercentage, IProgress <TimeSpan> progressTimeLeft, ulong combinationCount) { var timeEstimator = new TimeLeftEstimator(); var getCombinationsStopwatch = new Stopwatch(); getCombinationsStopwatch.Start(); ulong loopCount = 0; //Getting all lv combinations and updating user on progress of the operation var combinations = new LvCombinationProcessor(Groups.Select(g => g.Size).ToList(), Students.ToList(), MaxCombinationCount).LvCombinations .Select(c => { _cancellationSource?.Token.ThrowIfCancellationRequested(); loopCount++; //Progress is updated every 100 combinations if (loopCount % 100 == 0) { getCombinationsStopwatch.Stop(); progressPercentage?.Report((double)loopCount / combinationCount); timeEstimator.AddTime(new TimeSpan(getCombinationsStopwatch.ElapsedTicks)); progressTimeLeft?.Report(timeEstimator.GetTimeLeft((long)combinationCount - (long)loopCount) / 100); getCombinationsStopwatch.Restart(); } return(c); }) .ToList(); return(combinations); }
private LvCombination GetBestLvCombination(List <LvCombination> combinations, int currentLvIndex, IProgress <double> progressPercentage, IProgress <TimeSpan> progressTimeLeft) { LvCombination bestCombination = null; bool firstCombination = true; int bestCombinationMaxSittingCount = 0; int bestCombinationStudentSittingDiff = 0; int bestCombinationMinMaxSum = 0; int bestCombinationMinSittingCount = 0; int bestCombinationMinAndMaxSittingCountCount = 0; int bestCombinationGroupRepetitionCount = 0; int loopCount = 0; var timeEstimator = new TimeLeftEstimator(); var combinationsLoopStopwatch = new Stopwatch(); combinationsLoopStopwatch.Start(); foreach (var combination in combinations) { _cancellationSource?.Token.ThrowIfCancellationRequested(); UpdateStudentHistory(combination, true); var studentSittingHistoryValues = GetStudentSittingHistoryValues().ToList(); bool isBestCombination = firstCombination || IsBestCombination(combination, studentSittingHistoryValues, bestCombinationMaxSittingCount, bestCombinationMinSittingCount, bestCombinationStudentSittingDiff, bestCombinationMinMaxSum, bestCombinationMinAndMaxSittingCountCount, bestCombinationGroupRepetitionCount); //Updating variables if this is the best combination so far if (isBestCombination) { //Variables are being populated using new data since some of the variables in this foreach loop might not have been updated (since that depends on what criteria the best combination was selected) bestCombination = combination; if (studentSittingHistoryValues.Count != 0) { bestCombinationMaxSittingCount = studentSittingHistoryValues.Max(); bestCombinationMinSittingCount = studentSittingHistoryValues.Min(); bestCombinationStudentSittingDiff = GetStudentSittingDiff(combination); bestCombinationMinMaxSum = GetMinMaxValues(combination).Sum(); bestCombinationGroupRepetitionCount = GetGroupRepetitionCount(combination); bestCombinationMinAndMaxSittingCountCount = GetMinAndMaxSittingCountCount(studentSittingHistoryValues); firstCombination = false; } } UpdateStudentHistory(combination, false); loopCount++; if (loopCount % 1000 == 0 || loopCount == combinations.Count) { combinationsLoopStopwatch.Stop(); timeEstimator?.AddTime(new TimeSpan(combinationsLoopStopwatch.ElapsedTicks)); var timeLeft = timeEstimator.GetTimeLeft((combinations.Count - loopCount) / 1000 + (_lvCount - currentLvIndex - 1) * combinations.Count / 1000); progressTimeLeft?.Report(timeLeft); progressPercentage?.Report((double)((currentLvIndex + (double)loopCount / combinations.Count) / _lvCount)); combinationsLoopStopwatch.Restart(); } } return(bestCombination); }