示例#1
0
 /// <summary>
 /// Destructively crosses over the individual with another in some default manner.  In most
 /// implementations provided in ECJ, one-, two-, and any-point crossover is done with a
 /// for loop, rather than a possibly more efficient approach like arrayCopy().  The disadvantage
 /// is that Array.Copy(...) takes advantage of a CPU's bulk copying.  The advantage is that Array.Copy(...)
 /// would require a scratch array, so you'd be allocing and GCing an array for every crossover.
 /// Dunno which is more efficient.
 /// </summary>
 public virtual void DefaultCrossover(IEvolutionState state, int thread, VectorIndividual ind)
 {
 }
        public override void DefaultCrossover(IEvolutionState state, int thread, VectorIndividual ind)
        {
            var   s = (IntegerVectorSpecies)Species;
            var   i = (ShortVectorIndividual)ind;
            short tmp;
            int   point;

            if (genome.Length != i.genome.Length)
            {
                state.Output.Fatal("Genome lengths are not the same for fixed-length vector crossover");
            }
            switch (s.CrossoverType)
            {
            case VectorSpecies.C_ONE_POINT:
                point = state.Random[thread].NextInt((genome.Length / s.ChunkSize) + 1);
                for (var x = 0; x < point * s.ChunkSize; x++)
                {
                    tmp         = i.genome[x];
                    i.genome[x] = genome[x];
                    genome[x]   = tmp;
                }
                break;

            case VectorSpecies.C_TWO_POINT:
                var point0 = state.Random[thread].NextInt((genome.Length / s.ChunkSize) + 1);
                point = state.Random[thread].NextInt((genome.Length / s.ChunkSize) + 1);
                if (point0 > point)
                {
                    var p = point0;
                    point0 = point;
                    point  = p;
                }
                for (var x = point0 * s.ChunkSize; x < point * s.ChunkSize; x++)
                {
                    tmp         = i.genome[x];
                    i.genome[x] = genome[x];
                    genome[x]   = tmp;
                }
                break;

            case VectorSpecies.C_ANY_POINT:
                for (var x = 0; x < genome.Length / s.ChunkSize; x++)
                {
                    if (state.Random[thread].NextBoolean(s.CrossoverProbability))
                    {
                        for (var y = x * s.ChunkSize; y < (x + 1) * s.ChunkSize; y++)
                        {
                            tmp         = i.genome[y];
                            i.genome[y] = genome[y];
                            genome[y]   = tmp;
                        }
                    }
                }
                break;

            case VectorSpecies.C_LINE_RECOMB:
            {
                var alpha = state.Random[thread].NextDouble() * (1 + 2 * s.LineDistance) - s.LineDistance;
                var beta  = state.Random[thread].NextDouble() * (1 + 2 * s.LineDistance) - s.LineDistance;
                for (var x = 0; x < genome.Length; x++)
                {
                    var min = s.GetMinGene(x);
                    var max = s.GetMaxGene(x);
                    var t   = (long)Math.Floor(alpha * genome[x] + (1 - alpha) * i.genome[x] + 0.5);
                    var u   = (long)Math.Floor(beta * i.genome[x] + (1 - beta) * genome[x] + 0.5);
                    if ((t < min || t > max || u < min || u > max))
                    {
                        continue;
                    }
                    genome[x]   = (short)t;
                    i.genome[x] = (short)u;
                }
            }
            break;

            case VectorSpecies.C_INTERMED_RECOMB:
            {
                for (var x = 0; x < genome.Length; x++)
                {
                    long t;
                    long u;
                    long min;
                    long max;
                    do
                    {
                        var alpha = state.Random[thread].NextDouble() * (1 + 2 * s.LineDistance) - s.LineDistance;
                        var beta  = state.Random[thread].NextDouble() * (1 + 2 * s.LineDistance) - s.LineDistance;
                        min = s.GetMinGene(x);
                        max = s.GetMaxGene(x);
                        t   = (long)Math.Floor(alpha * genome[x] + (1 - alpha) * i.genome[x] + 0.5);
                        u   = (long)Math.Floor(beta * i.genome[x] + (1 - beta) * genome[x] + 0.5);
                    } while (t < min || t > max || u < min || u > max);
                    genome[x]   = (short)t;
                    i.genome[x] = (short)u;
                }
            }
            break;
            }
        }
        public override void DefaultCrossover(IEvolutionState state, int thread, VectorIndividual ind)
        {
            var    s = (FloatVectorSpecies)Species;
            var    i = (DoubleVectorIndividual)ind;
            double tmp;
            int    point;

            if (genome.Length != i.genome.Length)
            {
                state.Output.Fatal("Genome lengths are not the same for fixed-length vector crossover");
            }
            switch (s.CrossoverType)
            {
            case VectorSpecies.C_ONE_POINT:
                point = state.Random[thread].NextInt((genome.Length / s.ChunkSize) + 1);
                for (var x = 0; x < point * s.ChunkSize; x++)
                {
                    tmp         = i.genome[x];
                    i.genome[x] = genome[x];
                    genome[x]   = tmp;
                }
                break;

            case VectorSpecies.C_TWO_POINT:
                var point0 = state.Random[thread].NextInt((genome.Length / s.ChunkSize) + 1);
                point = state.Random[thread].NextInt((genome.Length / s.ChunkSize) + 1);
                if (point0 > point)
                {
                    var p = point0;
                    point0 = point;
                    point  = p;
                }
                for (var x = point0 * s.ChunkSize; x < point * s.ChunkSize; x++)
                {
                    tmp         = i.genome[x];
                    i.genome[x] = genome[x];
                    genome[x]   = tmp;
                }
                break;

            case VectorSpecies.C_ANY_POINT:
                for (var x = 0; x < genome.Length / s.ChunkSize; x++)
                {
                    if (state.Random[thread].NextBoolean(s.CrossoverProbability))
                    {
                        for (var y = x * s.ChunkSize; y < (x + 1) * s.ChunkSize; y++)
                        {
                            tmp         = i.genome[y];
                            i.genome[y] = genome[y];
                            genome[y]   = tmp;
                        }
                    }
                }
                break;

            case VectorSpecies.C_LINE_RECOMB:
            {
                var alpha = state.Random[thread].NextDouble(includeZero: true, includeOne: true) * (1 + 2 * s.LineDistance) - s.LineDistance;
                var beta  = state.Random[thread].NextDouble(includeZero: true, includeOne: true) * (1 + 2 * s.LineDistance) - s.LineDistance;
                for (var x = 0; x < genome.Length; x++)
                {
                    var min = s.GetMinGene(x);
                    var max = s.GetMaxGene(x);
                    var t   = alpha * genome[x] + (1 - alpha) * i.genome[x];
                    var u   = beta * i.genome[x] + (1 - beta) * genome[x];
                    if ((t < min || t > max || u < min || u > max))
                    {
                        continue;
                    }
                    genome[x]   = t;
                    i.genome[x] = u;
                }
            }
            break;

            case VectorSpecies.C_INTERMED_RECOMB:
            {
                for (var x = 0; x < genome.Length; x++)
                {
                    double t;
                    double u;
                    double min;
                    double max;
                    do
                    {
                        var alpha = state.Random[thread].NextDouble(includeZero: true, includeOne: true) * (1 + 2 * s.LineDistance) - s.LineDistance;
                        var beta  = state.Random[thread].NextDouble(includeZero: true, includeOne: true) * (1 + 2 * s.LineDistance) - s.LineDistance;
                        min = s.GetMinGene(x);
                        max = s.GetMaxGene(x);
                        t   = alpha * genome[x] + (1 - alpha) * i.genome[x];
                        u   = beta * i.genome[x] + (1 - beta) * genome[x];
                    } while (t < min || t > max || u < min || u > max);
                    genome[x]   = t;
                    i.genome[x] = u;
                }
            }
            break;

            case VectorSpecies.C_SIMULATED_BINARY:
            {
                SimulatedBinaryCrossover(state.Random[thread], i, s.CrossoverDistributionIndex);
            }
            break;
            }
        }