public Population(LinkedList<EZPathFollowing.PathPart> path, Genome genome, double rating, bool mutated, bool selected) { m_path = path; m_genome = genome; m_rating = rating; m_selected = selected; m_mutated = mutated; }
public static void genomeToPath(Genome pathGenome) { // Initialize Path List //LinkedList<EZPathFollowing.PathPart> output = new LinkedList<EZPathFollowing.PathPart>(); // Resets the global path Variables.resetPath(); // Resets the gloabl genome Variables.resetGenome(); // Initialize Variables double length; // Length is a number n from 0 to 7. 0.5 + n * 0.5 is the length of a Pathpart double angle; // Angle a is a number from 0 to 7, 10 + a * 5 is the angle in DEGREE bool driveRight; double direction = (360 - Variables.configuration_start.Theta[0]) * Math.PI / 180; EZPathFollowing.Point2D start = Variables.start; // Iterate over all 20 GenomeParts for (int i = 0; i < 20; i++) { // Length is saved in Bits 1,2 and 3 and is required for both PathParts length = GenomePart.getDouble(pathGenome.genome.Get(i * 8 + 1), pathGenome.genome.Get(i * 8 + 2), pathGenome.genome.Get(i * 8 + 3)); length = 0.5 + length * 0.5; // Bit 0 says whether its a curve or line if (pathGenome.genome.Get(i * 8) == false) { // The first Pathpart needs a start and direction if (i == 0) { Variables.path.AddLast(EZPathFollowing.PathPrimitives.line(length, direction, start)); } else { Variables.path.AddLast(EZPathFollowing.PathPrimitives.line(length)); } } else { // Angle and driveRight are only necessary for curves (Bit 0 = true) angle = GenomePart.getDouble(pathGenome.genome.Get(i * 8 + 4), pathGenome.genome.Get(i * 8 + 5), pathGenome.genome.Get(i * 8 + 6)); angle = (10 + angle * 5) * Math.PI / 180; driveRight = pathGenome.genome.Get(i * 8 + 7); // Again, first PathPart needs a start and direction if (i == 0) { Variables.path.AddLast(EZPathFollowing.PathPrimitives.curve(length, direction, angle, driveRight, start)); } else { Variables.path.AddLast(EZPathFollowing.PathPrimitives.curve(length, angle, driveRight)); } } } }
public Population(LinkedList<EZPathFollowing.PathPart> path, Genome genome, double rating, bool mutated, bool selected, double distances, double collisions) { m_path = path; m_genome = genome; m_rating = rating; m_selected = selected; m_mutated = mutated; m_collisions = collisions; m_distances = distances; }
private void button_genomeToPath_Click(object sender, EventArgs e) { Genome genome = new Genome(); char[] text = this.textBox1.Text.ToCharArray(); for (int i = 0; i < 160; i++) { if (text[i] == '1') genome.Genome1.Set(i, true); } Genome.genomeToPath(genome); this.glControl1.Refresh(); }
public Population(LinkedList<EZPathFollowing.PathPart> path, Genome genome, double rating) { m_path = path; m_genome = genome; m_rating = rating; }
public static void resetGenome() { genome = new Genome(); }
// This function uses genomePart Uniform Crossover. It works like a crossover function but uses a significantly shorter mask genome // because it always chooses an entire 8bit block public void eightBitCrossover() { // Size of current new generation is 40% of old generation (before crossover) int selectionSize = Convert.ToInt32(0.4 * populationSize); int r; Genome parent1 = new Genome(); Genome parent2 = new Genome(); bool[] mask; Genome child1 = new Genome(); Genome child2 = new Genome(); // Iterates from selection Size (current maximum of the new population) to population size, the wanted maximum. That means 60% come from crossover for (int i = selectionSize; i < populationSize; i++) { // Randomly selects first parent r = Variables.getRandomInt(0, selectionSize); parent1 = oldPopulation[r].Genome; // Randomly selects second parent r = Variables.getRandomInt(0, selectionSize); parent2 = oldPopulation[r].Genome; // Crates a random mask genome in form of a char[]. char[] is much faster than bool[], genome or bitarray and for our purpose the format doesn't matter mask = GenomePart.getRandomGenome(); for (int j = 0; j < 20; j++) { // Checks the mask if (mask[j]) { // If mask == 1 then the i'th 8bit block will be selected from parent1 for child1 and from parent2 for child2 // k = j*8 since every position in the mask genome covers 8 positions in the actual genome for (int k = j * 8; k < j * 8 + 8; k++) { child1.Genome1.Set(k, parent1.Genome1.Get(k)); child2.Genome1.Set(k, parent2.Genome1.Get(k)); } } else { // If mask == 0 then the i'th 8bit block will be selected from parent1 for child2 and from parent2 for child1 // k = j*8 since every position in the mask genome covers 8 positions in the actual genome for (int k = j * 8; k < j * 8 + 8; k++) { child1.Genome1.Set(k, parent2.Genome1.Get(k)); child2.Genome1.Set(k, parent1.Genome1.Get(k)); } } } Genome.genomeToPath(child1); population[i] = new Population(Variables.path, child1, 0, false, false); // Counts up since we are adding 2 children per iteration, not just one i++; // If we are not yet at maximum (which could happen due to double->int conversion) we add the second child too if (i < populationSize) { Genome.genomeToPath(child2); population[i] = new Population(Variables.path, child2, 0, false, false); } } }
// This function uses two fixed points for two-point crossover. For better performance these two points may be made random and/or adjusted over time // For example, in higher generations they could be moved further to the back public void twoFixedPointCrossover() { int selectionSize = Convert.ToInt32(0.4 * populationSize); Genome parent1 = new Genome(); Genome parent2 = new Genome(); Genome child1 = new Genome(); Genome child2 = new Genome(); int r; int fixpoint1 = 4; int fixpoint2 = 15; for (int i = selectionSize; i < populationSize; i++) { // Randomly selects first parent r = Variables.getRandomInt(0, selectionSize); parent1 = oldPopulation[r].Genome; // Randomly selects second parent r = Variables.getRandomInt(0, selectionSize); parent2 = oldPopulation[r].Genome; for (int j = 0; j < 20; j++) { // Case 1: fixpoint 1 to fixpoint 2, fixpoints exclusive if (j > fixpoint1 && j < fixpoint2) { // Iterates over the eight-bit-blocks and adds all bits to the respective parent for (int k = j * 8; k < j * 8 + 8; k++) { child1.Genome1.Set(k, parent1.Genome1.Get(k)); child2.Genome1.Set(k, parent2.Genome1.Get(k)); } } // Case 2: Before fixpoint 1 and after fixpoint 2, fixpoints inclusive else { // Iterates over the eight-bit-blocks and adds all bits to the respective parent for (int k = j * 8; k < j * 8 + 8; k++) { child1.Genome1.Set(k, parent2.Genome1.Get(k)); child2.Genome1.Set(k, parent1.Genome1.Get(k)); } } } Genome.genomeToPath(child1); population[i] = new Population(Variables.path, child1, 0, false, false); // Counts up since we are adding 2 children per iteration, not just one i++; // If we are not yet at maximum (which could happen due to double->int conversion) we add the second child too if (i < populationSize) { Genome.genomeToPath(child2); population[i] = new Population(Variables.path, child2, 0, false, false); } } }
// This function uses single-bit Uniform Crossover. public void singleBitCrossover() { // Size of current new generation is 40% of old generation (before crossover) int selectionSize = Convert.ToInt32(0.4 * populationSize); int r; Genome parent1 = new Genome(); Genome parent2 = new Genome(); Genome mask = new Genome(); Genome child1 = new Genome(); Genome child2 = new Genome(); // Iterates from selection Size (current maximum of the new population) to population size, the wanted maximum. That means 60% come from crossover for (int i = selectionSize; i < populationSize; i ++) { // Randomly selects first parent r = Variables.getRandomInt(0,selectionSize); parent1 = oldPopulation[r].Genome; // Randomly selects second parent r = Variables.getRandomInt(0, selectionSize); parent2 = oldPopulation[r].Genome; // Crates a random mask genome. This function sucks. mask = new Genome(true); // Generates children for (int j = 0; j < 160; j++) { if (mask.Genome1.Get(j)) { // If mask(i) is 1 then child1 gets the value at that point from parent1, child2 from parent2 child1.Genome1.Set(j, parent1.Genome1.Get(j)); child2.Genome1.Set(j, parent2.Genome1.Get(j)); } else { // If mask(i) is 0 then child1 gets the value at that point from parent2, child2 from parent1 child1.Genome1.Set(j, parent2.Genome1.Get(j)); child2.Genome1.Set(j, parent1.Genome1.Get(j)); } } // Adds the genome and its corresponding path to the population at position i. Also sets Selected to false. Genome.genomeToPath(child1); population[i] = new Population(Variables.path, child1, 0, false, false); // Counts up since we are adding 2 children per iteration, not just one i++; // If we are not yet at maximum (which could happen due to double->int conversion) we add the second child too if (i < populationSize) { Genome.genomeToPath(child2); population[i] = new Population(Variables.path, child2, 0, false, false); } } }