source: branches/ichiriac/HeuristicLab.Algorithms.Schade/Shade.cs @ 14088

Last change on this file since 14088 was 14088, checked in by ichiriac, 5 years ago

Add SHADE algorithm implementation

File size: 27.0 KB
Line 
1using HeuristicLab.Analysis;
2using HeuristicLab.Common;
3using HeuristicLab.Core;
4using HeuristicLab.Data;
5using HeuristicLab.Encodings.RealVectorEncoding;
6using HeuristicLab.Optimization;
7using HeuristicLab.Parameters;
8using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
9using HeuristicLab.Problems.TestFunctions;
10using HeuristicLab.Random;
11using System;
12using System.Collections.Generic;
13using System.Threading;
14
15namespace HeuristicLab.Algorithms.Shade
16{
17
18    [Item("Success-History Based Parameter Adaptation for DE (SHADE)", "A self-adaptive version of differential evolution")]
19    [StorableClass]
20    [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 400)]
21    public class Shade : BasicAlgorithm
22    {
23        public Func<IEnumerable<double>, double> Evaluation;
24
25        public override Type ProblemType
26        {
27            get { return typeof(SingleObjectiveTestFunctionProblem); }
28        }
29        public new SingleObjectiveTestFunctionProblem Problem
30        {
31            get { return (SingleObjectiveTestFunctionProblem)base.Problem; }
32            set { base.Problem = value; }
33        }
34
35        private readonly IRandom _random = new MersenneTwister();
36        private int evals;
37        private int pop_size;
38        private double arc_rate;
39        private int arc_size;
40        private double p_best_rate;
41        private int memory_size;
42
43        private double[][] pop;
44        private double[] fitness;
45        private double[][] children;
46        private double[] children_fitness;
47
48        private double[] bsf_solution;
49        private double bsf_fitness = 1e+30;
50        private double[,] archive;
51        private int num_arc_inds = 0;
52
53        #region ParameterNames
54        private const string MaximumEvaluationsParameterName = "Maximum Evaluations";
55        private const string SeedParameterName = "Seed";
56        private const string SetSeedRandomlyParameterName = "SetSeedRandomly";
57        private const string CrossoverProbabilityParameterName = "CrossoverProbability";
58        private const string PopulationSizeParameterName = "PopulationSize";
59        private const string ScalingFactorParameterName = "ScalingFactor";
60        private const string ValueToReachParameterName = "ValueToReach";
61        private const string ArchiveRateParameterName = "ArchiveRate";
62        private const string MemorySizeParameterName = "MemorySize";
63        private const string BestRateParameterName = "BestRate";
64        #endregion
65
66        #region ParameterProperties
67        public IFixedValueParameter<IntValue> MaximumEvaluationsParameter
68        {
69            get { return (IFixedValueParameter<IntValue>)Parameters[MaximumEvaluationsParameterName]; }
70        }
71        public IFixedValueParameter<IntValue> SeedParameter
72        {
73            get { return (IFixedValueParameter<IntValue>)Parameters[SeedParameterName]; }
74        }
75        public FixedValueParameter<BoolValue> SetSeedRandomlyParameter
76        {
77            get { return (FixedValueParameter<BoolValue>)Parameters[SetSeedRandomlyParameterName]; }
78        }
79        private ValueParameter<IntValue> PopulationSizeParameter
80        {
81            get { return (ValueParameter<IntValue>)Parameters[PopulationSizeParameterName]; }
82        }
83        public ValueParameter<DoubleValue> CrossoverProbabilityParameter
84        {
85            get { return (ValueParameter<DoubleValue>)Parameters[CrossoverProbabilityParameterName]; }
86        }
87        public ValueParameter<DoubleValue> ScalingFactorParameter
88        {
89            get { return (ValueParameter<DoubleValue>)Parameters[ScalingFactorParameterName]; }
90        }
91        public ValueParameter<DoubleValue> ValueToReachParameter
92        {
93            get { return (ValueParameter<DoubleValue>)Parameters[ValueToReachParameterName]; }
94        }
95        public ValueParameter<DoubleValue> ArchiveRateParameter
96        {
97            get { return (ValueParameter<DoubleValue>)Parameters[ArchiveRateParameterName]; }
98        }
99        public ValueParameter<IntValue> MemorySizeParameter
100        {
101            get { return (ValueParameter<IntValue>)Parameters[MemorySizeParameterName]; }
102        }
103        public ValueParameter<DoubleValue> BestRateParameter
104        {
105            get { return (ValueParameter<DoubleValue>)Parameters[BestRateParameterName]; }
106        }
107        #endregion
108
109        #region Properties
110        public int MaximumEvaluations
111        {
112            get { return MaximumEvaluationsParameter.Value.Value; }
113            set { MaximumEvaluationsParameter.Value.Value = value; }
114        }
115
116        public Double CrossoverProbability
117        {
118            get { return CrossoverProbabilityParameter.Value.Value; }
119            set { CrossoverProbabilityParameter.Value.Value = value; }
120        }
121        public Double ScalingFactor
122        {
123            get { return ScalingFactorParameter.Value.Value; }
124            set { ScalingFactorParameter.Value.Value = value; }
125        }
126        public int Seed
127        {
128            get { return SeedParameter.Value.Value; }
129            set { SeedParameter.Value.Value = value; }
130        }
131        public bool SetSeedRandomly
132        {
133            get { return SetSeedRandomlyParameter.Value.Value; }
134            set { SetSeedRandomlyParameter.Value.Value = value; }
135        }
136        public IntValue PopulationSize
137        {
138            get { return PopulationSizeParameter.Value; }
139            set { PopulationSizeParameter.Value = value; }
140        }
141        public Double ValueToReach
142        {
143            get { return ValueToReachParameter.Value.Value; }
144            set { ValueToReachParameter.Value.Value = value; }
145        }
146        public Double ArchiveRate
147        {
148            get { return ArchiveRateParameter.Value.Value; }
149            set { ArchiveRateParameter.Value.Value = value; }
150        }
151        public IntValue MemorySize
152        {
153            get { return MemorySizeParameter.Value; }
154            set { MemorySizeParameter.Value = value; }
155        }
156        public Double BestRate
157        {
158            get { return BestRateParameter.Value.Value; }
159            set { BestRateParameter.Value.Value = value; }
160        }
161        #endregion
162
163        #region ResultsProperties
164        private double ResultsBestQuality
165        {
166            get { return ((DoubleValue)Results["Best Quality"].Value).Value; }
167            set { ((DoubleValue)Results["Best Quality"].Value).Value = value; }
168        }
169
170        private double VTRBestQuality
171        {
172            get { return ((DoubleValue)Results["VTR"].Value).Value; }
173            set { ((DoubleValue)Results["VTR"].Value).Value = value; }
174        }
175
176        private RealVector ResultsBestSolution
177        {
178            get { return (RealVector)Results["Best Solution"].Value; }
179            set { Results["Best Solution"].Value = value; }
180        }
181
182        private int ResultsEvaluations
183        {
184            get { return ((IntValue)Results["Evaluations"].Value).Value; }
185            set { ((IntValue)Results["Evaluations"].Value).Value = value; }
186        }
187        private int ResultsIterations
188        {
189            get { return ((IntValue)Results["Iterations"].Value).Value; }
190            set { ((IntValue)Results["Iterations"].Value).Value = value; }
191        }
192
193        private DataTable ResultsQualities
194        {
195            get { return ((DataTable)Results["Qualities"].Value); }
196        }
197        private DataRow ResultsQualitiesBest
198        {
199            get { return ResultsQualities.Rows["Best Quality"]; }
200        }
201
202        #endregion
203
204        [StorableConstructor]
205        protected Shade(bool deserializing) : base(deserializing) { }
206
207        protected Shade(Shade original, Cloner cloner)
208          : base(original, cloner)
209        {
210        }
211
212        public override IDeepCloneable Clone(Cloner cloner)
213        {
214            return new Shade(this, cloner);
215        }
216
217        public Shade()
218        {
219            Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluationsParameterName, "", new IntValue(Int32.MaxValue)));
220            Parameters.Add(new ValueParameter<IntValue>(PopulationSizeParameterName, "The size of the population of solutions.", new IntValue(75)));
221            Parameters.Add(new ValueParameter<DoubleValue>(ValueToReachParameterName, "Value to reach (VTR) parameter", new DoubleValue(0.00000001)));
222            Parameters.Add(new ValueParameter<DoubleValue>(ArchiveRateParameterName, "Archive rate parameter", new DoubleValue(2.0)));
223            Parameters.Add(new ValueParameter<IntValue>(MemorySizeParameterName, "Memory size parameter", new IntValue(0)));
224            Parameters.Add(new ValueParameter<DoubleValue>(BestRateParameterName, "Best rate parameter", new DoubleValue(0.1)));
225        }
226
227        protected override void Run(CancellationToken cancellationToken)
228        {
229
230            // Set up the results display
231            Results.Add(new Result("Iterations", new IntValue(0)));
232            Results.Add(new Result("Evaluations", new IntValue(0)));
233            Results.Add(new Result("Best Solution", new RealVector()));
234            Results.Add(new Result("Best Quality", new DoubleValue(double.NaN)));
235            Results.Add(new Result("VTR", new DoubleValue(double.NaN)));
236            var table = new DataTable("Qualities");
237            table.Rows.Add(new DataRow("Best Quality"));
238            Results.Add(new Result("Qualities", table));
239
240
241            this.evals = 0;
242            int archive_size = (int)Math.Round(ArchiveRateParameter.Value.Value * PopulationSize.Value);
243            int problem_size = Problem.ProblemSize.Value;
244
245            int pop_size = PopulationSizeParameter.Value.Value;
246            this.arc_rate = ArchiveRateParameter.Value.Value;
247            this.arc_size = (int)Math.Round(this.arc_rate * pop_size);
248            this.p_best_rate = BestRateParameter.Value.Value;
249            this.memory_size = MemorySizeParameter.Value.Value;
250
251            this.pop = new double[pop_size][];
252            this.fitness = new double[pop_size];
253            this.children = new double[pop_size][];
254            this.children_fitness = new double[pop_size];
255
256            this.bsf_solution = new double[problem_size];
257            this.bsf_fitness = 1e+30;
258            this.archive = new double[arc_size, Problem.ProblemSize.Value];
259            this.num_arc_inds = 0;
260
261            double[,] populationOld = new double[PopulationSizeParameter.Value.Value, Problem.ProblemSize.Value];
262            double[,] mutationPopulation = new double[PopulationSizeParameter.Value.Value, Problem.ProblemSize.Value];
263            double[,] trialPopulation = new double[PopulationSizeParameter.Value.Value, Problem.ProblemSize.Value];
264            double[] bestPopulation = new double[Problem.ProblemSize.Value];
265            double[] bestPopulationIteration = new double[Problem.ProblemSize.Value];
266            double[,] archive = new double[archive_size, Problem.ProblemSize.Value];
267
268
269            // //for external archive
270            int rand_arc_ind;
271
272            int num_success_params;
273
274            double[] success_sf = new double[PopulationSizeParameter.Value.Value];
275            double[] success_cr = new double[PopulationSizeParameter.Value.Value];
276            double[] dif_fitness = new double[PopulationSizeParameter.Value.Value];
277            double[] fitness = new double[PopulationSizeParameter.Value.Value];
278
279            // the contents of M_f and M_cr are all initialiezed 0.5
280            double[] memory_sf = new double[MemorySizeParameter.Value.Value];
281            double[] memory_cr = new double[MemorySizeParameter.Value.Value];
282
283            for (int i = 0; i < MemorySizeParameter.Value.Value; i++)
284            {
285                memory_sf[i] = 0.5;
286                memory_cr[i] = 0.5;
287            }
288
289            //memory index counter
290            int memory_pos = 0;
291            double temp_sum_sf1, temp_sum_sf2, temp_sum_cr1, temp_sum_cr2, temp_sum, temp_weight;
292
293            //for new parameters sampling
294            double mu_sf, mu_cr;
295            int rand_mem_index;
296
297            double[] pop_sf = new double[PopulationSizeParameter.Value.Value];
298            double[] pop_cr = new double[PopulationSizeParameter.Value.Value];
299
300            //for current-to-pbest/1
301            int p_best_ind;
302            double m = PopulationSizeParameter.Value.Value * BestRateParameter.Value.Value;
303            int p_num = (int)Math.Round(m);
304            int[] sorted_array = new int[PopulationSizeParameter.Value.Value];
305            double[] sorted_fitness = new double[PopulationSizeParameter.Value.Value];
306
307            //initialize the population
308            populationOld = makeNewIndividuals();
309
310            //evaluate the best member after the intialiazation
311            //the idea is to select first member and after that to check the others members from the population
312
313            int best_index = 0;
314            double[] populationRow = new double[Problem.ProblemSize.Value];
315            bestPopulation = getMatrixRow(populationOld, best_index);
316            RealVector bestPopulationVector = new RealVector(bestPopulation);
317            double bestPopulationValue = Obj(bestPopulationVector);
318            fitness[best_index] = bestPopulationValue;
319            RealVector selectionVector;
320            RealVector trialVector;
321            double qtrial;
322
323
324            for (var i = 0; i < PopulationSizeParameter.Value.Value; i++)
325            {
326                populationRow = getMatrixRow(populationOld, i);
327                trialVector = new RealVector(populationRow);
328
329                qtrial = Obj(trialVector);
330                fitness[i] = qtrial;
331
332                if (qtrial > bestPopulationValue)
333                {
334                    bestPopulationVector = new RealVector(populationRow);
335                    bestPopulationValue = qtrial;
336                    best_index = i;
337                }
338            }
339
340            int iterations = 1;
341
342            // Loop until iteration limit reached or canceled.
343            // todo replace with a function
344            // && bestPopulationValue > Problem.BestKnownQuality.Value + ValueToReachParameter.Value.Value
345            while (ResultsEvaluations < MaximumEvaluations
346                && !cancellationToken.IsCancellationRequested &&
347                bestPopulationValue > Problem.BestKnownQuality.Value + ValueToReachParameter.Value.Value)
348            {
349                for (int i = 0; i < PopulationSizeParameter.Value.Value; i++) sorted_array[i] = i;
350                for (int i = 0; i < PopulationSizeParameter.Value.Value; i++) sorted_fitness[i] = fitness[i];
351
352                Quicksort(sorted_fitness, 0, PopulationSizeParameter.Value.Value - 1, sorted_array);
353
354                for (int target = 0; target < PopulationSizeParameter.Value.Value; target++)
355                {
356                    rand_mem_index = (int)(_random.NextDouble() * MemorySizeParameter.Value.Value);
357                    mu_sf = memory_sf[rand_mem_index];
358                    mu_cr = memory_cr[rand_mem_index];
359
360                    //generate CR_i and repair its value
361                    if (mu_cr == -1)
362                    {
363                        pop_cr[target] = 0;
364                    }
365                    else {
366                        pop_cr[target] = gauss(mu_cr, 0.1);
367                        if (pop_cr[target] > 1) pop_cr[target] = 1;
368                        else if (pop_cr[target] < 0) pop_cr[target] = 0;
369                    }
370
371                    //generate F_i and repair its value
372                    do {
373                        pop_sf[target] = cauchy_g(mu_sf, 0.1);
374                    } while (pop_sf[target] <= 0);
375
376                    if (pop_sf[target] > 1) pop_sf[target] = 1;
377
378                    //p-best individual is randomly selected from the top pop_size *  p_i members
379                    p_best_ind = sorted_array[(int)(_random.NextDouble() * p_num)];
380
381                    trialPopulation = operateCurrentToPBest1BinWithArchive(populationOld, trialPopulation, target, p_best_ind, pop_sf[target], pop_cr[target]);
382                }
383
384                for (int i = 0; i < pop_size; i++) {
385                    trialVector = new RealVector(getMatrixRow(trialPopulation, i));
386                    children_fitness[i] = Obj(trialVector);
387                }
388
389                //update bfs solution
390                for (var i = 0; i < PopulationSizeParameter.Value.Value; i++)
391                {
392                    populationRow = getMatrixRow(populationOld, i);
393                    qtrial = fitness[i];
394
395                    if (qtrial > bestPopulationValue)
396                    {
397                        bestPopulationVector = new RealVector(populationRow);
398                        bestPopulationValue = qtrial;
399                        best_index = i;
400                    }
401                }
402
403                num_success_params = 0;
404
405                //generation alternation
406                for (int i = 0; i < pop_size; i++)
407                {
408                    if (children_fitness[i] == fitness[i])
409                    {
410                        fitness[i] = children_fitness[i];
411                        for (int j = 0; j < problem_size; j++) populationOld[i,j] = trialPopulation[i,j];
412                    }
413                    else if (children_fitness[i] < fitness[i])
414                    {
415                        //parent vectors x_i which were worse than the trial vectors u_i are preserved
416                        if (arc_size > 1)
417                        {
418                            if (num_arc_inds < arc_size)
419                            {
420                                for (int j = 0; j < problem_size; j++) this.archive[num_arc_inds, j] = populationOld[i, j];
421                                num_arc_inds++;
422
423                            }
424                            //Whenever the size of the archive exceeds, randomly selected elements are deleted to make space for the newly inserted elements
425                            else {
426                                rand_arc_ind = (int)(_random.NextDouble() * arc_size);
427                                for (int j = 0; j < problem_size; j++) this.archive[rand_arc_ind, j] = populationOld[i, j];
428                            }
429                        }
430
431                        dif_fitness[num_success_params] = Math.Abs(fitness[i] - children_fitness[i]);
432
433                        fitness[i] = children_fitness[i];
434                        for (int j = 0; j < problem_size; j++) populationOld[i, j] = trialPopulation[i, j];
435
436                        //successful parameters are preserved in S_F and S_CR
437                        success_sf[num_success_params] = pop_sf[i];
438                        success_cr[num_success_params] = pop_cr[i];
439                        num_success_params++;
440                    }
441                }
442
443                if (num_success_params > 0)
444                {
445                    temp_sum_sf1 = 0;
446                    temp_sum_sf2 = 0;
447                    temp_sum_cr1 = 0;
448                    temp_sum_cr2 = 0;
449                    temp_sum = 0;
450                    temp_weight = 0;
451
452                    for (int i = 0; i < num_success_params; i++) temp_sum += dif_fitness[i];
453
454                    //weighted lehmer mean
455                    for (int i = 0; i < num_success_params; i++)
456                    {
457                        temp_weight = dif_fitness[i] / temp_sum;
458
459                        temp_sum_sf1 += temp_weight * success_sf[i] * success_sf[i];
460                        temp_sum_sf2 += temp_weight * success_sf[i];
461
462                        temp_sum_cr1 += temp_weight * success_cr[i] * success_cr[i];
463                        temp_sum_cr2 += temp_weight * success_cr[i];
464                    }
465
466                    memory_sf[memory_pos] = temp_sum_sf1 / temp_sum_sf2;
467
468                    if (temp_sum_cr2 == 0 || memory_cr[memory_pos] == -1)
469                    {
470                        memory_cr[memory_pos] = -1;
471                    } else {
472                        memory_cr[memory_pos] = temp_sum_cr1 / temp_sum_cr2;
473                    }
474
475                    //increment the counter
476                    memory_pos++;
477                    if (memory_pos >= memory_size) memory_pos = 0;
478                }
479
480                //update the best candidate
481                for (int i = 0; i < PopulationSizeParameter.Value.Value; i++)
482                {
483                    selectionVector = new RealVector(getMatrixRow(populationOld, i));
484                    var quality = fitness[i];
485                    if (quality < bestPopulationValue)
486                    {
487                        bestPopulationVector = (RealVector)selectionVector.Clone();
488                        bestPopulationValue = quality;
489                    }
490                }
491
492                iterations = iterations + 1;
493
494                //update the results
495                ResultsEvaluations = evals;
496                ResultsIterations = iterations;
497                ResultsBestSolution = bestPopulationVector;
498                ResultsBestQuality = bestPopulationValue;
499
500                //update the results in view
501                if (iterations % 10 == 0) ResultsQualitiesBest.Values.Add(bestPopulationValue);
502                if (bestPopulationValue < Problem.BestKnownQuality.Value + ValueToReachParameter.Value.Value)
503                {
504                    VTRBestQuality = bestPopulationValue;
505                }
506            }
507        }
508
509        //evaluate the vector
510        public double Obj(RealVector x)
511        {
512            evals = evals + 1;
513            if (Problem.Maximization.Value)
514                return -Problem.Evaluator.Evaluate(x);
515
516            return Problem.Evaluator.Evaluate(x);
517        }
518
519        // Get ith row from the matrix
520        public double[] getMatrixRow(double[,] Mat, int i)
521        {
522            double[] tmp = new double[Mat.GetUpperBound(1) + 1];
523
524            for (int j = 0; j <= Mat.GetUpperBound(1); j++)
525            {
526                tmp[j] = Mat[i, j];
527            }
528
529            return tmp;
530        }
531
532        /*
533            Return random value from Cauchy distribution with mean "mu" and variance "gamma"
534            http://www.sat.t.u-tokyo.ac.jp/~omi/random_variables_generation.html#Cauchy
535        */
536        private double cauchy_g(double mu, double gamma)
537        {
538            return mu + gamma * Math.Tan(Math.PI * (_random.NextDouble() - 0.5));
539        }
540
541        /*
542             Return random value from normal distribution with mean "mu" and variance "gamma"
543             http://www.sat.t.u-tokyo.ac.jp/~omi/random_variables_generation.html#Gauss
544        */
545        private double gauss(double mu, double sigma)
546        {
547            return mu + sigma * Math.Sqrt(-2.0 * Math.Log(_random.NextDouble())) * Math.Sin(2.0 * Math.PI * _random.NextDouble());
548        }
549
550        private double[,] makeNewIndividuals() {
551            //problem variables
552            var dim = Problem.ProblemSize.Value;
553            var lb = Problem.Bounds[0, 0];
554            var ub = Problem.Bounds[0, 1];
555            var range = ub - lb;
556            double[,] population = new double[PopulationSizeParameter.Value.Value, Problem.ProblemSize.Value];
557
558            //create initial population
559            //population is a matrix of size PopulationSize*ProblemSize
560            for (int i = 0; i < PopulationSizeParameter.Value.Value; i++)
561            {
562                for (int j = 0; j < Problem.ProblemSize.Value; j++)
563                {
564                    population[i, j] = _random.NextDouble() * range + lb;
565                }
566            }
567            return population;
568        }
569
570        private static void Quicksort(double[] elements, int left, int right, int[] index)
571        {
572            int i = left, j = right;
573            double pivot = elements[(left + right) / 2];
574            double tmp_var = 0;
575            int tmp_index = 0;
576
577            while (i <= j)
578            {
579                while (elements[i].CompareTo(pivot) < 0)
580                {
581                    i++;
582                }
583
584                while (elements[j].CompareTo(pivot) > 0)
585                {
586                    j--;
587                }
588
589                if (i <= j)
590                {
591                    // Swap
592                    tmp_var = elements[i];
593                    elements[i] = elements[j];
594                    elements[j] = tmp_var;
595
596                    tmp_index = index[i];
597                    index[i] = index[j];
598                    index[j] = tmp_index;
599
600                    i++;
601                    j--;
602                }
603            }
604
605            // Recursive calls
606            if (left < j)
607            {
608                Quicksort(elements, left, j, index);
609            }
610
611            if (i < right)
612            {
613                Quicksort(elements, i, right, index);
614            }
615        }
616
617        // current to best selection scheme with archive
618        // analyze how the archive is implemented
619        private double[,] operateCurrentToPBest1BinWithArchive(double[,] pop, double[,]children, int target, int p_best_individual, double scaling_factor, double cross_rate)
620        {
621            int r1, r2;
622            int num_arc_inds = 0;
623            var lb = Problem.Bounds[0, 0];
624            var ub = Problem.Bounds[0, 1];
625
626            do
627            {
628                r1 = (int)(_random.NextDouble() * PopulationSizeParameter.Value.Value);
629            } while (r1 == target);
630            do
631            {
632                r2 = (int)(_random.NextDouble() * (PopulationSizeParameter.Value.Value + num_arc_inds));
633            } while ((r2 == target) || (r2 == r1));
634
635            int random_variable = (int)(_random.NextDouble() * Problem.ProblemSize.Value);
636
637            if (r2 >= PopulationSizeParameter.Value.Value)
638            {
639                r2 -= PopulationSizeParameter.Value.Value;
640                for (int i = 0; i < Problem.ProblemSize.Value; i++)
641                {
642                    if ((_random.NextDouble() < cross_rate) || (i == random_variable)) children[target, i] = pop[target, i] + scaling_factor * (pop[p_best_individual, i] - pop[target, i]) + scaling_factor * (pop[r1, i] - archive[r2, i]);
643                    else children[target, i] = pop[target, i];
644                }
645            }
646            else {
647                for (int i = 0; i < Problem.ProblemSize.Value; i++)
648                {
649                    if ((_random.NextDouble() < cross_rate) || (i == random_variable)) children[target, i] = pop[target, i] + scaling_factor * (pop[p_best_individual, i] - pop[target, i]) + scaling_factor * (pop[r1, i] - pop[r2, i]);
650                    else children[target, i] = pop[target, i];
651                }
652            }
653
654            for (int i = 0; i < Problem.ProblemSize.Value; i++) {
655                if (children[target, i] < lb) children[target, i] = (lb + pop[target, i]) / 2.0;
656                else if (children[target, i] > ub) children[target, i] = (ub + pop[target, i]) / 2.0;
657            }
658
659            return children;
660        }
661    }
662}
Note: See TracBrowser for help on using the repository browser.