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);
        }