/// <summary> /// Find out the earliest time that all subjects can run. Take into account that some subjects might be banned /// </summary> public void RefreshEarliestTimes() { Stopwatch timer1 = new Stopwatch(); timer1.Restart(); // Prepare to analyze everything Queue <Subject> subjectQueue = new Queue <Subject>(); // TODO: uniqueQueue foreach (Subject subject in MasterList.AllSubjects) { subjectQueue.Enqueue(subject); } // TODO: prioritize subjects if they're a leaf // Iterate through the queue while (subjectQueue.Any()) { Subject current = subjectQueue.Dequeue(); // Find the earliest time that both the prerequisites and the corequisites can be completed in Time timePrerequisites = current.Prerequisites.EarliestCompletionTime(this).Next(); Time timeCorequisites = current.Corequisites.EarliestCompletionTime(this); // Pick the later of those times Time evaluatedTime = timeCorequisites.IsEarlierThan(timePrerequisites) ? timePrerequisites : timeCorequisites; // If this subject has been listed as a banned subject by the plan, return an Impossible time if (BannedContents.ContainsKey(current)) { evaluatedTime = Time.Impossible; } // Make sure the time aligns with the subject's semesters while (evaluatedTime.year <= current.earliestYear - 2020 || // TODO: get rid of magic number next year !current.Semesters.Any(semester => semester.session == evaluatedTime.session) || GetMaxCreditPoints(evaluatedTime) < current.CreditPoints()) { evaluatedTime = evaluatedTime.Next(); // Prevent the subject from being later than Impossible (otherwise this leads to infinite loops) if (Time.Impossible.IsEarlierThan(evaluatedTime)) { evaluatedTime = Time.Impossible; break; } } // Check if the value changed if (!EarliestCompletionTimes.TryGetValue(current, out Time initialEarliestValue)) { initialEarliestValue = Time.Early; } EarliestCompletionTimes[current] = evaluatedTime; if (initialEarliestValue.CompareTo(evaluatedTime) != 0) { // If the value changed, re-analyze every subject that depends on this subject foreach (Subject parent in current.Parents) { subjectQueue.Enqueue(parent); } } } timer1.Stop(); Debug.WriteLine("Getting times: " + timer1.ElapsedMilliseconds + "ms"); }
public Plan(Plan other) { AssignedTimes = new Dictionary <Subject, Time>(other.AssignedTimes); Decisions.AddRange(other.Decisions); SelectedSubjects = new List <Subject>(other.SelectedSubjects); SelectedCourses = new List <Course>(other.SelectedCourses); foreach (var BannedContent in other.BannedContents) { BannedContents.Add(BannedContent.Key, new List <Content>(BannedContent.Value)); } EarliestCompletionTimes = new Dictionary <Subject, Time>(other.EarliestCompletionTimes); SubjectsWithForcedTimes = new HashSet <Subject>(other.SubjectsWithForcedTimes); MaxCreditPoints = new Dictionary <Time, int>(other.MaxCreditPoints); ContentRelations = new HashSet <Edge>(other.ContentRelations); }