private void CrossoverOneSegment(LGPProgram gp1, LGPProgram gp2) { double prob_r = DistributionModel.GetUniform(); if ((gp1.InstructionCount < mMaxProgramLength) && ((prob_r <= mInsertionProbability || gp1.InstructionCount == mMinProgramLength))) { int i1 = DistributionModel.NextInt(gp1.InstructionCount); int max_segment_length = gp2.InstructionCount < mMaxSegmentLength ? gp2.InstructionCount : mMaxSegmentLength; int ls2 = 1 + DistributionModel.NextInt(max_segment_length); if (gp1.InstructionCount + ls2 > mMaxProgramLength) { ls2 = mMaxProgramLength - gp1.InstructionCount; } int i2 = DistributionModel.NextInt(gp2.InstructionCount - ls2); List <LGPInstruction> instructions1 = gp1.Instructions; List <LGPInstruction> instructions2 = gp2.Instructions; List <LGPInstruction> s = new List <LGPInstruction>(); for (int i = i2; i != (i2 + ls2); ++i) { LGPInstruction instruction = instructions2[i]; LGPInstruction instruction_cloned = instruction.Clone(); instruction_cloned.Program = gp1; s.Add(instruction_cloned); } instructions1.InsertRange(i1, s.AsEnumerable()); } if ((gp1.InstructionCount > mMinProgramLength) && ((prob_r > mInsertionProbability) || gp1.InstructionCount == mMaxProgramLength)) { int max_segment_length = (gp2.InstructionCount < mMaxSegmentLength) ? gp2.InstructionCount : mMaxSegmentLength; int ls1 = 1 + DistributionModel.NextInt(max_segment_length); if (gp1.InstructionCount < ls1) { ls1 = gp1.InstructionCount - mMinProgramLength; } else if (gp1.InstructionCount - ls1 < mMinProgramLength) { ls1 = gp1.InstructionCount - mMinProgramLength; } int i1 = DistributionModel.NextInt(gp1.InstructionCount - ls1); List <LGPInstruction> instructions1 = gp1.Instructions; instructions1.RemoveRange(i1, ls1); } gp1.TrashFitness(); }
public override void Mutate(LGPPop lgpPop, LGPProgram child) { // CSChen says: // This is derived from Algorithm 6.1 (Section 6.2.1) of Linear Genetic Programming // Macro instruction mutations either insert or delete a single instruction. // In doing so, they change absolute program length with minimum step size on the // level of full instructions, the macro level. On the functional level , a single // node is inserted in or deleted from the program graph, together with all // its connecting edges. // Exchanging an instruction or change the position of an existing instruction is not // regarded as macro mutation. Both of these variants are on average more // destructive, i.e. they imply a larger variation step size, since they include a deletion // and an insertion at the same time. A further, but important argument against // substitutios of single instructions is that these do not vary program length. If // single instruction would only be exchanged there would be no code growth. double r = DistributionModel.GetUniform(); List <LGPInstruction> instructions = child.Instructions; if (child.InstructionCount < _macroMutateMaxProgramLength && ((r < _macroMutateInsertionRate) || child.InstructionCount == _macroMutateMinProgramLength)) { LGPInstruction inserted_instruction = new LGPInstruction(child); inserted_instruction.Create(); int loc = DistributionModel.NextInt(child.InstructionCount); if (loc == child.InstructionCount - 1) { instructions.Add(inserted_instruction); } else { instructions.Insert(loc, inserted_instruction); } if (_effectiveMutation) { while (instructions[loc].IsConditionalConstruct && loc < instructions.Count) { loc++; } if (loc < instructions.Count) { HashSet <int> Reff = new HashSet <int>(); child.MarkStructuralIntrons(loc, Reff); if (Reff.Count > 0) { int iRegisterIndex = -1; foreach (int Reff_value in Reff) { if (iRegisterIndex == -1) { iRegisterIndex = Reff_value; } else if (DistributionModel.GetUniform() < 0.5) { iRegisterIndex = Reff_value; } } instructions[loc].DestinationRegister = child.RegisterSet.FindRegisterByIndex(iRegisterIndex); } } } } else if (child.InstructionCount > _macroMutateMinProgramLength && ((r > _macroMutateInsertionRate) || child.InstructionCount == _macroMutateMaxProgramLength)) { int loc = DistributionModel.NextInt(instructions.Count); if (_effectiveMutation) { for (int i = 0; i < 10; i++) { loc = DistributionModel.NextInt(instructions.Count); if (!instructions[loc].IsStructuralIntron) { break; } } } instructions.RemoveAt(loc); } child.TrashFitness(); }