public void createInitialPopulation() { while (population.Count < POPSIZE) { Chromosome newChromosome = new Chromosome(); /* add any fixed events first */ foreach (Gene g in Program.fixedEvents) newChromosome.add(g.getSlot(), g.getEvent(), g.getRoom(), g.getCannotChange()); newChromosome.scheduleLunch(); /* schedule each of the events then add the chromosome to the population */ foreach (Event e in Program.events) newChromosome.scheduleEvent(e); population.Add(newChromosome); } }
private void scheduleLists(Slot s, List<Gene> p1, List<Gene> p2, Chromosome child) { List<Gene> combinedList = new List<Gene>(); combinedList.AddRange(p1.Intersect(p2)); foreach (Gene g in combinedList) { if (p1.Contains(g)) p1.Remove(g); if (p2.Contains(g)) p2.Contains(g); } combinedList.AddRange(p1); combinedList.AddRange(p2); combinedList.RemoveAll(delegate(Gene g) { return g.getCannotChange() == true || g.getEvent().getCourse() == "Lunch"; }); combinedList.Reverse(); for (int i = combinedList.Count; i > 0; i--) { bool success = child.scheduleEventFromList(s, combinedList[i - 1]); if (!success) child.unscheduableEvents.Add(combinedList[i - 1].getEvent()); combinedList.Remove(combinedList[i - 1]); } child.scheduleUnscheduableEvents(s); }
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]); }
public List<Chromosome> selection() { List<Chromosome> parents = new List<Chromosome>(); setAveFitAndStdDev(); /* the chance the fittest chromosome of the two selected has of being * included in the new population*/ double selectionLimit = 0.75; while (parents.Count < POPSIZE) { /* choose two random chromosomes and determine which is the fittest */ Chromosome chromosome1 = population[random.Next(population.Count)]; Chromosome chromosome2 = population[random.Next(population.Count)]; Chromosome fittestChromosome = new Chromosome(); Chromosome leastFitChromosome = new Chromosome(); if (chromosome1.chromosomeFitness() < chromosome2.chromosomeFitness()) { fittestChromosome = chromosome1; leastFitChromosome = chromosome2; } else { fittestChromosome = chromosome2; leastFitChromosome = chromosome1; } /* if a random number is less than the selectionLimit then add the fittest * chromosome to the population. otherwise add the least fittest */ if (random.NextDouble() < selectionLimit) parents.Add(fittestChromosome); else parents.Add(leastFitChromosome); } return parents; }
} // 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++; } // output 100th gen fitness to file StreamWriter SW; SW = File.AppendText("C:\\Users\\Stu\\Desktop\\Constant analysis\\Mutation " + MUTATION + ".txt"); SW.WriteLine(averagePopulationFitness); SW.Close(); //Console.WriteLine("Text Appended Successfully"); sortPopulation(); //Console.WriteLine("\n\n" + population[0]); } // crossover