Hi All,

I am trying to create a GA to solve timetabling for exams, so far I have created a array of exams e.g. [2,3,5,4] means exam 2 is held at time slot 1 and exam 3 is at time slot 2.

//This is the testChromosome.ChromosomeArray is the sample code.

I have also created student data which hold exams a student takes for example [1,3,5,4] this means student takes exams 1,3,5,4.

//This is testStudent in the sample code.

I want my code to add a punishment to the testChromosome each time a students exams are in consecutive time slots. e.g. the example above will be punished for 3, 5 next to each other and 5,4 next to each other. The Chromosome also gets punished if the students exam is not timetabled. The code I have wrote seems to work ok, but sometime I get a extra 5 or 10 punishment especially when exams are timetabled twice e.g testChromosome = [1,2,2].

I think it is a simple fix I just can't seem to see it.

//-----------------------------Sample Code-------------------------------

public void consecutiveExams()
        {
            foreach (Student testStudent in        testStudentData.SPopulation)//-- For each student in the SPopulation.
            {
                for (int i = 0; i < testStudent.StudentsNumberOfExams; i++) //-- for each exam within the test student
                {
                    int testexam1 = testStudent.ExamStudentTakes[i]; //-- set testexam1 to equal the ith element of exams students takes.
                    if (testChromosome.ChromosomeArray.Contains(testexam1))
                    {
                        for (int j = 0; j < testChromosome.ChromosomeArray.Count(); j++) //-- for loop to find the location of the test exam in chromosome.
                        {
                            if (testChromosome.ChromosomeArray.ElementAt(j) == testexam1) //-- if the jth element in the chromosomeArray is equal to testexam return true.
                            {
                                for (int k = 0; k < testStudent.StudentsNumberOfExams; k++) //-- for each element in teststudent if the j-1 and j+1 chromosomeArray 
                                //elements are within the students exam array then the chromosome gets punished by 5.                            
                                {
                                    if (testChromosome.ChromosomeArray.ElementAtOrDefault((j + 1)) == testStudent.ExamStudentTakes[k] && ((j + 1) < testChromosome.ChromosomeArray.Count()))
                                    {
                                        punishment += 5; //--Punishment 5 for each consecutive exams.
                                    }
                                    if (testChromosome.ChromosomeArray.ElementAtOrDefault((j - 1)) == testStudent.ExamStudentTakes[k] && ((j - 1) >= 0))
                                    {
                                        punishment += 5; //--Punishment 5 for each consecutive exams.
                                    }

                                }

                            }
                        }
                    }
                    else
                    {
                        //punishment += 100; //Chromosome gets punished 100 if the students exam is not time within the timetable.
                    }
                }
            }
        }

Kind Regards

FlippA

Is it intentional to have the same exam scheduled twice?
Using your example [1,2,2], and assuming that the student is taking exam 2:

When j = 1 then element in the chromosomeArray is equal to testexam; So you then test j+1 and j-1 against ALL the exams in the students list of exams (including exam 2). It finds 2 at j+1 and adds 5 punishment.
Next, j is incremented and j = 2. Here it finds the second instance of exam 2 and registers a match. j - 1 is the previous instance of exam 2 which matches with an exam in the students list so the punishment is added here as well.
This is where your extra punishments are coming from.

Dear Ryshad,

I understand that each punishment will get counted twice due to the method it travels through the for loops, I have counted each consecutive exam as a punishment of 5+5=10, but I still seem to get extra 5/10 added on the punishment and I can't see where from it.

e.g. testChromosome = [1,2,2,5] and testStudent = [1,2]
punishment = 40 but it seems to get 45 ?

Kind Regards

FlippA

Can you post complete code? I ran your code sample, replacing testStudent.ExamStudentTakes with an array of {1,2} and testChromosome.ChromosomeArray with {1,2,2,5} (see below) and it returns a punishment of 20 which is what i would have expected. It finds 1 followed by 2, 2 preceeded by 1 and followed by 2, and 2 preceeded by 2. Four adjacencies = 4 * 5 = 20.

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(consecutiveExams().ToString());

            Console.ReadKey();

        }

        public static int consecutiveExams()
        {
            int[] schedule = { 1, 2, 2, 5 };
            int[] student = { 1, 2 };
            int punishment = 0;

            for (int i = 0; i < 2; i++) //-- for each exam within the test student
            {
                int testexam1 = student[i]; //-- set testexam1 to equal the ith element of exams students takes.
                if (schedule.Contains(testexam1))
                {
                    for (int j = 0; j < schedule.Count(); j++) //-- for loop to find the location of the test exam in chromosome.
                    {
                        if (schedule.ElementAt(j) == testexam1) //-- if the jth element in the chromosomeArray is equal to testexam return true.
                        {
                            for (int k = 0; k < 2; k++) //-- for each element in teststudent if the j-1 and j+1 chromosomeArray 
                            //elements are within the students exam array then the chromosome gets punished by 5.                            
                            {
                                if (schedule.ElementAtOrDefault((j + 1)) == student[k] && ((j + 1) <schedule.Count()))
                                {
                                    punishment += 5; //--Punishment 5 for each consecutive exams.
                                }
                                if (schedule.ElementAtOrDefault((j - 1)) == student[k] && ((j - 1) >= 0))
                                {
                                    punishment += 5; //--Punishment 5 for each consecutive exams.
                                }

                            }

                        }
                    }
                }
                else
                {
                    //punishment += 100; //Chromosome gets punished 100 if the students exam is not time within the timetable.
                }
            }
            return punishment;
        }

    }

AH HA! I just noticed one thing i changed without realising.
I ran a single student through it. You are running more than one student without resetting punishment after each student.
Cant believe i misse3d that lol. Try adding punishment = 0; either at the very start or very end of the foreach (Student testStudent in testStudentData.SPopulation) loop (but inside the loop).

Hi Ryshad.

I have attached the project to this reply, the problem I have is hard to explain as the Chromosome and Students are created randomly and sometime it seems to work and over time the punishment is wrong due to the consecutive exams function. I hope the code is commented ok and kinda makes sense as I have quite new to coding so it might be a bit all over the place.
If you could think of any other good tips when it comes to coding as you read my code that would be helpful too.

Kind Regards FlippA

AH HA! I just noticed one thing i changed without realising.
I ran a single student through it. You are running more than one student without resetting punishment after each student.
Cant believe i misse3d that lol. Try adding punishment = 0; either at the very start or very end of the foreach (Student testStudent in testStudentData.SPopulation) loop (but inside the loop).

you didnt mention it so im guessing it wasnt the problem, but is it intentional that the punishment be a total for all students? Or are you trying to get a punishment for each student seperately?

I would like the algorithm to add up the punishment for all students, and create a total for each Chromosome.

Yes I am running on the beta VS10 which is free to download if you want to try it, it is very good I would say. If not what would be the best way of of saving the project to be compatible I can save it as ANSI Project File, or Unicode Project File.

Kind Regards

FlippA

Its not a problem, i can open the files, just not the solution file. I'll be getting VS2010 via BizSpark as soon as they release it. I can't really risk bugs in the beta at work and dont have time to play with it at home :p

I have had a quick play with your program and i havent seen any problems : / Everything seems to run smoothly. It adds 10 to the punishment any time two exams are adjacent.
Can you remember what values you put in when you got the odd results? All of mine have been multiples of 10 so far.

Hi Ryshad,

I have been looking through my code and it seems to be work ok now for some strange reason, which has confused me greatly thank you very much for all your help.

Kind Regards

FlippA


Its not a problem, i can open the files, just not the solution file. I'll be getting VS2010 via BizSpark as soon as they release it. I can't really risk bugs in the beta at work and dont have time to play with it at home :p

I have had a quick play with your program and i havent seen any problems : / Everything seems to run smoothly. It adds 10 to the punishment any time two exams are adjacent.
Can you remember what values you put in when you got the odd results? All of mine have been multiples of 10 so far.

This question has already been answered. Start a new discussion instead.