} // scheduleEventFromList private void bookSlots(Slot s, Gene g) { if (g.getEvent().getWeekly() && s.getWeek() == "B") { s = getCorrespondingSlot(s); } for (int i = 0; i < g.getEvent().getDuration(); i++) { int slotIndex = Program.slots.IndexOf(s); slotIndex += i; s = Program.slots[slotIndex]; chromosome.Add(new Gene(s, g.getEvent(), g.getRoom(), g.getCannotChange())); slotIndex = Program.slots.IndexOf(s); slotIndex++; if (slotIndex < Program.slots.Count) { s = Program.slots[slotIndex]; } if (g.getEvent().getWeekly()) { chromosome.Add(new Gene(s, g.getEvent(), g.getRoom(), g.getCannotChange())); } } }
} // selection public void crossover() { int numberOfGenerations = 0; setAveFitAndStdDev(); while (numberOfGenerations < NUMGENERATIONS) { List <Chromosome> parents = selection(); List <Chromosome> newPopulation = new List <Chromosome>(); List <Gene> parent1; List <Gene> parent2; Console.WriteLine("Generation " + numberOfGenerations + " average fitness = " + averagePopulationFitness); while (newPopulation.Count < POPSIZE) { parent1 = parents[random.Next(parents.Count)].getGenes(); parent2 = parents[random.Next(parents.Count)].getGenes(); Chromosome child = new Chromosome(); /* schedule any fixed events first */ List <Gene> fixedEvents = (from g in parent1 where g.getCannotChange() == true select g).ToList(); foreach (Gene g in fixedEvents) { child.add(g.getSlot(), g.getEvent(), g.getRoom(), g.getCannotChange()); } /* schedule any lunch events next */ int[] days = { 1, 2, 4, 5 }; foreach (int day in days) { List <Gene> lunchEvents = (from g in parent1 where g.getEvent().getCourse() == "Lunch" && g.getSlot().getDay() == day select g).ToList(); lunchEvents.AddRange(from g in parent2 where g.getEvent().getCourse() == "Lunch" && g.getSlot().getDay() == day select g); foreach (string grp in Program.groups) { List <Gene> slotsForGroup = (from g in lunchEvents where g.getEvent().getGroups().Contains(grp) select g).ToList(); Gene selectedLunchSlot = slotsForGroup[0]; /* Might have to put a check in here to ensure that not all of the groups * (or at least a majority) have lunch at the same time */ if (slotsForGroup.Count > 1) { // check that there aren't any clashes (this might occur for groups with external events bool slotFound = false; int i = 0; while ((i < slotsForGroup.Count) && (!slotFound)) { if (!child.doClashesExist(slotsForGroup[i].getSlot(), slotsForGroup[i].getEvent(), slotsForGroup[i].getRoom())) { slotFound = true; selectedLunchSlot = slotsForGroup[i]; } i++; } } if (!child.hasLunchBeenScheduled(selectedLunchSlot.getSlot(), selectedLunchSlot.getEvent())) { child.add(Program.slots[Program.slots.IndexOf(selectedLunchSlot.getSlot())], selectedLunchSlot.getEvent(), selectedLunchSlot.getRoom(), selectedLunchSlot.getCannotChange()); child.add(Program.slots[Program.slots.IndexOf(child.getCorrespondingSlot(selectedLunchSlot.getSlot()))], selectedLunchSlot.getEvent(), selectedLunchSlot.getRoom(), selectedLunchSlot.getCannotChange()); } } } /* choose a random point from which to start going through the timetable */ Slot startSlot = Program.slots[random.Next(Program.slots.Count)]; int startPoint = Program.slots.IndexOf(startSlot); for (int i = startPoint; i < Program.slots.Count; i++) { Slot s = Program.slots[i]; List <Gene> p1GenesWeekly = (from g in parent1 where (g.getSlot() == s) select g).ToList(); List <Gene> p2GenesWeekly = (from g in parent2 where (g.getSlot() == s) select g).ToList(); scheduleLists(s, p1GenesWeekly, p2GenesWeekly, child); } for (int i = 0; i < startPoint; i++) { Slot s = Program.slots[i]; List <Gene> p1GenesWeekly = (from g in parent1 where (g.getSlot() == s) select g).ToList(); List <Gene> p2GenesWeekly = (from g in parent2 where (g.getSlot() == s) select g).ToList(); scheduleLists(s, p1GenesWeekly, p2GenesWeekly, child); } if (random.NextDouble() < MUTATION) { child.mutate(); } newPopulation.Add(child); } population = newPopulation; numberOfGenerations++; } sortPopulation(); Console.WriteLine("\n\n" + population[0]); } // crossover
private void bookSlots(Slot s, Gene g) { if (g.getEvent().getWeekly() && s.getWeek() == "B") s = getCorrespondingSlot(s); for (int i = 0; i < g.getEvent().getDuration(); i++) { int slotIndex = Program.slots.IndexOf(s); slotIndex += i; s = Program.slots[slotIndex]; chromosome.Add(new Gene(s, g.getEvent(), g.getRoom(), g.getCannotChange())); slotIndex = Program.slots.IndexOf(s); slotIndex++; if (slotIndex < Program.slots.Count) s = Program.slots[slotIndex]; if (g.getEvent().getWeekly()) chromosome.Add(new Gene(s, g.getEvent(), g.getRoom(), g.getCannotChange())); } }