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();
        }
コード例 #2
0
        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();
        }