public void TimetableGenerationTest() { String configurationFile = basePath + "TimetableDataExtended.xml"; TimetableData ttData = TimetableConfigIO.ImportTimetableConfig(configurationFile); Assert.IsNotNull(ttData, "Data could not be loaded."); TimetableGenerator generator = new TimetableGenerator(ttData); generator.IndividualCreated += new Action<int>(generator_IndividualCreated); generator.GenerationTick += new Action<TimetableGenerator.HistoryEntry>(generator_GenerationTick); DateTime start = DateTime.Now; generator.CreatePopulation(25, 10); TestRequirements(ttData, generator); System.Diagnostics.Debug.WriteLine("Population created after " + (DateTime.Now - start).TotalSeconds + " seconds."); generator.PerformEvolution(1000); TestRequirements(ttData, generator); System.Diagnostics.Debug.WriteLine("Evolution finished after " + (DateTime.Now - start).TotalSeconds + " seconds."); TimetableExportCSV.ExportAll(generator.Population[0], ttData, basePath + "outputtest.csv"); Assert.IsTrue(true); TimetablePlanner.TimetableGenerator.HistoryEntry.PrintHistory(generator.EvolutionHistory); }
private static void TestRequirements(TimetableData ttData, TimetableGenerator generator) { //Inspect every result population for (int pIndex = 0; pIndex < generator.Population.Length; pIndex++) { //Result must contain all defined courses Assert.AreEqual(0, GetCourseDiff(ttData, generator.Population[pIndex]), "Not the expected number of courses found for individual " + pIndex + "!"); for (int lIndex = 0; lIndex < ttData.Lecturers.Length; lIndex++) { if (!ttData.Lecturers[lIndex].IsDummy) { //Every lecturer must have the defined number of courses int expectedCourseCount = GetExpectedCourseCountForLecturer(ttData.Lecturers[lIndex], ttData); int foundCourseCount = GetCourseCountForLecturer(generator.Population[pIndex], lIndex); Assert.AreEqual(expectedCourseCount, foundCourseCount, "Not the expected number of courses found for lecturer " + lIndex + "!"); //Free days for research for lecturers int freeDaysForLecturer = GetFreeDaysForLecturer(generator.Population[pIndex], lIndex, ttData); Assert.IsTrue(ttData.Lecturers[lIndex].NeededNumberOfResearchDays <= freeDaysForLecturer, "Not enough free days for research for lecturer " + lIndex); } } for (int cIndex = 0; cIndex < ttData.Courses.Length; cIndex++) { //Every course must occupy the specified room (course -> room -> course) and must be a room (room != -1) Assert.IsTrue(CourseHasRoom(cIndex, generator.Population[pIndex].Courses, generator.Population[pIndex].Rooms, ttData), "Course " + cIndex + " has no room!"); int ctr = CountRoomsForCourse(generator, pIndex, cIndex); Assert.AreEqual(ttData.Courses[cIndex].NumberOfBlocks, ctr, "Not enough rooms specified for course " + cIndex); } for (int gIndex = 0; gIndex < ttData.Groups.Length; gIndex++) { //Number of courses for each group must be as defined int expectedCourseCount = GetExpectedCourseCountForGroup(ttData.Groups[gIndex], ttData); int foundCourseCount = GetCourseCountForGroup(gIndex, generator.Population[pIndex]); Assert.AreEqual(expectedCourseCount, foundCourseCount, "Not the expected number of courses for group " + gIndex + "!"); } for (int b = 0; b < ttData.Blocks.Length; b++) { //A defined exception block must not be occupied foreach (var exceptionDay in ttData.Blocks[b].Exceptions) { for (int course = 0; course < generator.Population[pIndex].Courses.GetLength(0); course++) { Assert.AreEqual(-1, generator.Population[pIndex].Courses[course, (int)exceptionDay - 1, b], "Course found for blockexception on day " + exceptionDay + ", block " + b + " !"); } } } } }
private void generator_GenerationTick(TimetableGenerator.HistoryEntry generationData) { System.Diagnostics.Debug.WriteLine("Generation " + generationData.Index + " finished with best fitness of " + generationData.BestFitness + "."); }
private static int CountRoomsForCourse(TimetableGenerator generator, int pIndex, int cIndex) { int ctr = 0; for (int d = 0; d < generator.Population[pIndex].Courses.GetLength(1); d++) { for (int b = 0; b < generator.Population[pIndex].Courses.GetLength(2); b++) { if (generator.Population[pIndex].Courses[cIndex, d, b] != -1) ctr++; } } return ctr; }
private void generator_GenerationTick(TimetableGenerator.HistoryEntry historyEntry) { ProgressbarValue = 50 + (int)((double)historyEntry.Index * ((double)ProgressbarMax / (double)_numberOfGenerations) / 2); }
private void RunGeneration() { SaveFileDialog svDiag = new SaveFileDialog(); svDiag.FileName = "Export.csv"; svDiag.Filter = "CSV-Files (*.csv)|*.csv"; svDiag.InitialDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase); if (svDiag.ShowDialog() != true) return; TimetableData ttData = GetTimetableData(); TimetableGenerator generator = new TimetableGenerator(ttData); generator.GenerationTick += new Action<TimetableGenerator.HistoryEntry>(generator_GenerationTick); generator.IndividualCreated += new Action<int>(generator_IndividualCreated); generator.CreatePopulation(_populationSize, 10); generator.PerformEvolution(_numberOfGenerations); ProgressbarValue = 0; TimetableExportCSV.ExportAll(generator.Population[0], ttData, svDiag.FileName); System.Diagnostics.Process.Start(svDiag.FileName); }