Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ichiriac/HeuristicLab.Algorithms.GDE3/GDE3.cs @ 13849

Last change on this file since 13849 was 13849, checked in by ichiriac, 8 years ago

Constrained test function

Check for constrained test function and evaluated the constraints violations
Add to dominance comparator also constraints violations

File size: 29.4 KB
Line 
1using System;
2using System.Linq;
3using System.Collections.Generic;
4using HeuristicLab.Analysis;
5using HeuristicLab.Common;
6using HeuristicLab.Core;
7using HeuristicLab.Data;
8using HeuristicLab.Encodings.RealVectorEncoding;
9using HeuristicLab.Operators;
10using HeuristicLab.Optimization;
11using HeuristicLab.Optimization.Operators;
12using HeuristicLab.Parameters;
13using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
14using HeuristicLab.PluginInfrastructure;
15using HeuristicLab.Problems.MultiObjectiveTestFunctions;
16using HeuristicLab.Random;
17using System.Threading;
18using HeuristicLab.Algorithms.GDE3;
19
20namespace HeuristicLab.Algoritms.GDE3
21{
22
23    [Item("Generalized Differential Evolution (GDE3)", "A generalized differential evolution algorithm.")]
24    [StorableClass]
25    [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 400)]
26    public class GDE3 : BasicAlgorithm
27    {
28        public override Type ProblemType
29        {
30            get { return typeof(MultiObjectiveTestFunctionProblem); }
31        }
32        public new MultiObjectiveTestFunctionProblem Problem
33        {
34            get { return (MultiObjectiveTestFunctionProblem)base.Problem; }
35            set { base.Problem = value; }
36        }
37
38        public ILookupParameter<DoubleMatrix> BestKnownFrontParameter
39        {
40            get
41            {
42                return (ILookupParameter<DoubleMatrix>)Parameters["BestKnownFront"];
43            }
44        }
45
46        private readonly IRandom _random = new MersenneTwister();
47        private int evals;
48        private double IGDSumm;
49
50        #region ParameterNames
51        private const string MaximumGenerationsParameterName = "Maximum Generations";
52        private const string CrossoverProbabilityParameterName = "CrossoverProbability";
53        private const string PopulationSizeParameterName = "PopulationSize";
54        private const string ScalingFactorParameterName = "ScalingFactor";
55
56        #endregion
57
58        #region ParameterProperties
59        public IFixedValueParameter<IntValue> MaximumGenerationsParameter
60        {
61            get { return (IFixedValueParameter<IntValue>)Parameters[MaximumGenerationsParameterName]; }
62        }
63        private ValueParameter<IntValue> PopulationSizeParameter
64        {
65            get { return (ValueParameter<IntValue>)Parameters[PopulationSizeParameterName]; }
66        }
67        public ValueParameter<DoubleValue> CrossoverProbabilityParameter
68        {
69            get { return (ValueParameter<DoubleValue>)Parameters[CrossoverProbabilityParameterName]; }
70        }
71        public ValueParameter<DoubleValue> ScalingFactorParameter
72        {
73            get { return (ValueParameter<DoubleValue>)Parameters[ScalingFactorParameterName]; }
74        }
75        #endregion
76
77        #region Properties
78        public int MaximumEvaluations
79        {
80            get { return MaximumGenerationsParameter.Value.Value; }
81            set { MaximumGenerationsParameter.Value.Value = value; }
82        }
83
84        public Double CrossoverProbability
85        {
86            get { return CrossoverProbabilityParameter.Value.Value; }
87            set { CrossoverProbabilityParameter.Value.Value = value; }
88        }
89        public Double ScalingFactor
90        {
91            get { return ScalingFactorParameter.Value.Value; }
92            set { ScalingFactorParameter.Value.Value = value; }
93        }
94        public IntValue PopulationSize
95        {
96            get { return PopulationSizeParameter.Value; }
97            set { PopulationSizeParameter.Value = value; }
98        }
99        #endregion
100
101        #region ResultsProperties
102        private double ResultsBestQuality
103        {
104            get { return ((DoubleValue)Results["Best Quality"].Value).Value; }
105            set { ((DoubleValue)Results["Best Quality"].Value).Value = value; }
106        }
107
108        private double ResultsIGDMean
109        {
110            get { return ((DoubleValue)Results["IGDMeanValue"].Value).Value; }
111            set { ((DoubleValue)Results["IGDMeanValue"].Value).Value = value; }
112        }
113
114        private double ResultsIGDBest
115        {
116            get { return ((DoubleValue)Results["IGDBestValue"].Value).Value; }
117            set { ((DoubleValue)Results["IGDBestValue"].Value).Value = value; }
118        }
119
120        private double ResultsIGDWorst
121        {
122            get { return ((DoubleValue)Results["IGDWorstValue"].Value).Value; }
123            set { ((DoubleValue)Results["IGDWorstValue"].Value).Value = value; }
124        }
125
126        private double ResultsInvertedGenerationalDistance
127        {
128            get { return ((DoubleValue)Results["InvertedGenerationalDistance"].Value).Value; }
129            set { ((DoubleValue)Results["InvertedGenerationalDistance"].Value).Value = value; }
130        }
131
132        private double ResultsHypervolume
133        {
134            get { return ((DoubleValue)Results["HyperVolumeValue"].Value).Value; }
135            set { ((DoubleValue)Results["HyperVolumeValue"].Value).Value = value; }
136        }
137
138        private DoubleMatrix ResultsBestFront
139        {
140            get { return (DoubleMatrix)Results["Best Front"].Value; }
141            set { Results["Best Front"].Value = value; }
142        }
143
144        private int ResultsEvaluations
145        {
146            get { return ((IntValue)Results["Evaluations"].Value).Value; }
147            set { ((IntValue)Results["Evaluations"].Value).Value = value; }
148        }
149        private int ResultsGenerations
150        {
151            get { return ((IntValue)Results["Generations"].Value).Value; }
152            set { ((IntValue)Results["Generations"].Value).Value = value; }
153        }
154        private double ResultsGenerationalDistance
155        {
156            get { return ((DoubleValue)Results["GenerationalDistance"].Value).Value; }
157            set { ((DoubleValue)Results["GenerationalDistance"].Value).Value = value; }
158        }
159
160        private double ResultsSpacing
161        {
162            get { return ((DoubleValue)Results["Spacing"].Value).Value; }
163            set { ((DoubleValue)Results["Spacing"].Value).Value = value; }
164        }
165
166        private double ResultsCrowding
167        {
168            get { return ((DoubleValue)Results["Crowding"].Value).Value; }
169            set { ((DoubleValue)Results["Crowding"].Value).Value = value; }
170        }
171
172        #endregion
173
174        [StorableConstructor]
175        protected GDE3(bool deserializing) : base(deserializing) { }
176
177        protected GDE3(GDE3 original, Cloner cloner)
178          : base(original, cloner)
179        {
180        }
181
182        public override IDeepCloneable Clone(Cloner cloner)
183        {
184            return new GDE3(this, cloner);
185        }
186
187        public GDE3()
188        {
189            Parameters.Add(new FixedValueParameter<IntValue>(MaximumGenerationsParameterName, "", new IntValue(1000)));
190            Parameters.Add(new ValueParameter<IntValue>(PopulationSizeParameterName, "The size of the population of solutions.", new IntValue(100)));
191            Parameters.Add(new ValueParameter<DoubleValue>(CrossoverProbabilityParameterName, "The value for crossover rate", new DoubleValue(0.5)));
192            Parameters.Add(new ValueParameter<DoubleValue>(ScalingFactorParameterName, "The value for scaling factor", new DoubleValue(0.5)));
193            Parameters.Add(new LookupParameter<DoubleMatrix>("BestKnownFront", "The currently best known Pareto front"));
194        }
195
196        protected override void Run(CancellationToken cancellationToken)
197        {
198            // Set up the results display
199            Results.Add(new Result("Generations", new IntValue(0)));
200            Results.Add(new Result("Evaluations", new IntValue(0)));
201            Results.Add(new Result("Best Front", new DoubleMatrix()));
202            Results.Add(new Result("Crowding", new DoubleValue(0)));
203            Results.Add(new Result("InvertedGenerationalDistance", new DoubleValue(0)));
204            Results.Add(new Result("GenerationalDistance", new DoubleValue(0)));
205            Results.Add(new Result("HyperVolumeValue", new DoubleValue(0)));
206            Results.Add(new Result("IGDMeanValue", new DoubleValue(0)));
207            Results.Add(new Result("IGDBestValue", new DoubleValue(Int32.MaxValue)));
208            Results.Add(new Result("IGDWorstValue", new DoubleValue(0)));
209
210            Results.Add(new Result("Spacing", new DoubleValue(0)));
211            Results.Add(new Result("Scatterplot", typeof(IMOFrontModel)));
212            var table = new DataTable("Qualities");
213            table.Rows.Add(new DataRow("Best Quality"));
214            Results.Add(new Result("Qualities", table));
215
216            //setup the variables
217            List<SolutionSet> population;
218            List<SolutionSet> offspringPopulation;
219            SolutionSet[] parent;
220            double IGDSumm = 0;
221           
222            //initialize population
223            population = new List<SolutionSet>(PopulationSizeParameter.Value.Value);
224
225            for (int i = 0; i < PopulationSizeParameter.Value.Value; ++i)
226            {
227                var m = createIndividual();
228                m.Quality = Problem.Evaluate(m.Population, _random);
229                //the test function is constrained
230                if (m.Quality.Length > Problem.Objectives)
231                {
232                    m.OverallConstrainViolation = m.Quality[Problem.Objectives];
233                } else {
234                    m.OverallConstrainViolation = 0;
235                }
236                population.Add(m);
237            }
238
239            this.initProgress();
240            int generations = 1;
241
242            while (ResultsGenerations < MaximumGenerationsParameter.Value.Value
243               && !cancellationToken.IsCancellationRequested)
244            {
245                var populationSize = PopulationSizeParameter.Value.Value;
246
247                // Create the offSpring solutionSet
248                offspringPopulation = new List<SolutionSet>(PopulationSizeParameter.Value.Value * 2);
249
250                for (int i = 0; i < populationSize; i++)
251                {
252                    // Obtain parents. Two parameters are required: the population and the
253                    //                 index of the current individual
254                    parent = selection(population, i);
255
256                    SolutionSet child;
257                    // Crossover. The parameters are the current individual and the index of the array of parents
258                    child = reproduction(population[i], parent);
259
260                    child.Quality = Problem.Evaluate(child.Population, _random);
261
262                    this.updateProgres();
263
264                    //the test function is constrained
265                    if (child.Quality.Length > Problem.Objectives)
266                    {
267                        child.OverallConstrainViolation = child.Quality[Problem.Objectives];
268                    } else {
269                        child.OverallConstrainViolation = 0;
270                    }
271
272                    // Dominance test
273                    int result;
274                    result = compareDomination(population[i], child);
275
276                    if (result == -1)
277                    { // Solution i dominates child
278                        offspringPopulation.Add(population[i]);
279                    }
280                    else if (result == 1)
281                    { // child dominates
282                        offspringPopulation.Add(child);
283                    }
284                    else
285                    { // the two solutions are non-dominated
286                        offspringPopulation.Add(child);
287                        offspringPopulation.Add(population[i]);
288                    }
289                }
290
291                // Ranking the offspring population
292                List<SolutionSet>[] ranking = computeRanking(offspringPopulation);
293                population = crowdingDistanceSelection(ranking);
294                generations++;
295                ResultsGenerations = generations;
296                displayResults(population);
297            }
298        }
299
300        private void displayResults(List<SolutionSet> population)
301        {
302            List<SolutionSet>[] rankingFinal = computeRanking(population);
303
304            int objectives = Problem.Objectives;
305            var optimalfront = Problem.TestFunction.OptimalParetoFront(objectives);
306
307            double[][] opf = new double[0][];
308            if (optimalfront != null)
309            {
310                opf = optimalfront.Select(s => s.ToArray()).ToArray();
311            }
312
313            //compute the final qualities and population
314            double[][] qualitiesFinal = new double[rankingFinal[0].Count][];
315            double[][] populationFinal = new double[rankingFinal[0].Count][];
316
317            for (int i = 0; i < rankingFinal[0].Count; ++i)
318            {
319                qualitiesFinal[i] = new double[Problem.Objectives];
320                populationFinal[i] = new double[Problem.Objectives];
321                for (int j = 0; j < Problem.Objectives; ++j)
322                {
323                    populationFinal[i][j] = rankingFinal[0][i].Population[j];
324                    qualitiesFinal[i][j] = rankingFinal[0][i].Quality[j];
325                }
326            }
327            IEnumerable<double[]> en = qualitiesFinal;
328            IEnumerable<double[]> frontVectors = NonDominatedSelect.selectNonDominatedVectors(qualitiesFinal, Problem.TestFunction.Maximization(objectives), true);
329            //update the results
330
331            ResultsEvaluations = this.evals;
332            ResultsBestFront = new DoubleMatrix(MultiObjectiveTestFunctionProblem.To2D(qualitiesFinal));
333            ResultsCrowding = Crowding.Calculate(qualitiesFinal, Problem.TestFunction.Bounds(objectives));
334            ResultsInvertedGenerationalDistance = InvertedGenerationalDistance.Calculate(en, optimalfront, 1);
335            ResultsHypervolume = Hypervolume.Calculate(frontVectors, Problem.TestFunction.ReferencePoint(objectives), Problem.TestFunction.Maximization(objectives));
336            ResultsGenerationalDistance = GenerationalDistance.Calculate(qualitiesFinal, optimalfront, 1);
337            Results["Scatterplot"].Value = new MOSolution(qualitiesFinal, populationFinal, opf, objectives);
338            ResultsSpacing = Spacing.Calculate(qualitiesFinal);
339
340            if (ResultsIGDBest > ResultsInvertedGenerationalDistance) {
341                ResultsIGDBest = ResultsInvertedGenerationalDistance;
342            }
343            if (ResultsIGDWorst < ResultsInvertedGenerationalDistance)
344            {
345                ResultsIGDWorst = ResultsInvertedGenerationalDistance;
346            }
347            this.IGDSumm += ResultsInvertedGenerationalDistance;
348            ResultsIGDMean = this.IGDSumm / ResultsGenerations;
349        }
350
351        private int getWorstIndex(List<SolutionSet> SolutionsList)
352        {
353            int result = 0;
354
355            if ((SolutionsList == null) || SolutionsList.Count == 0)
356            {
357                result = 0;
358            }
359            else
360            {
361                SolutionSet worstKnown = SolutionsList[0],
362                            candidateSolution;
363                int flag;
364                for (int i = 1; i < SolutionsList.Count; i++)
365                {
366                    candidateSolution = SolutionsList[i];
367                    flag = compareDomination(worstKnown, candidateSolution);
368                    if (flag == -1)
369                    {
370                        result = i;
371                        worstKnown = candidateSolution;
372                    }
373                }
374            }
375            return result;
376        }
377
378        protected SolutionSet createIndividual()
379        {
380            var dim = Problem.ProblemSize;
381            var lb = Problem.Bounds[0, 0];
382            var ub = Problem.Bounds[0, 1];
383            var range = ub - lb;
384            var v = new double[Problem.ProblemSize];
385            SolutionSet solutionObject = new SolutionSet(PopulationSizeParameter.Value.Value);
386
387            for (int i = 0; i < Problem.ProblemSize; ++i)
388            {
389                v[i] = _random.NextDouble() * range + lb;
390
391            }
392            solutionObject.createSolution(v);
393            return solutionObject;
394        }
395
396        private SolutionSet createEmptyIndividual()
397        {
398            SolutionSet solutionObject = new SolutionSet(PopulationSizeParameter.Value.Value);
399            var n = new RealVector(Problem.ProblemSize);
400            solutionObject.Population = n;
401            return solutionObject;
402        }
403
404        protected void initProgress()
405        {
406            this.evals = PopulationSizeParameter.Value.Value;
407        }
408
409        protected void updateProgres()
410        {
411            this.evals++;
412        }
413
414        protected SolutionSet[] selection(List<SolutionSet> population, int i)
415        {
416            SolutionSet[] parents = new SolutionSet[3];
417            int r0, r1, r2;
418            //assure the selected vectors r0, r1 and r2 are different
419            do
420            {
421                r0 = _random.Next(0, PopulationSizeParameter.Value.Value);
422            } while (r0 == i);
423            do
424            {
425                r1 = _random.Next(0, PopulationSizeParameter.Value.Value);
426            } while (r1 == i || r1 == r0);
427            do
428            {
429                r2 = _random.Next(0, PopulationSizeParameter.Value.Value);
430            } while (r2 == i || r2 == r0 || r2 == r1);
431
432            parents[0] = population[r0];
433            parents[1] = population[r1];
434            parents[2] = population[r2];
435
436            return parents;
437        }
438
439        protected SolutionSet reproduction(SolutionSet parent, SolutionSet[] parentsSolutions)
440        {
441            var individual = createEmptyIndividual();
442            double rnbr = _random.Next(0, Problem.ProblemSize);
443            for (int m = 0; m < Problem.ProblemSize; m++)
444            {
445                if (_random.NextDouble() < CrossoverProbabilityParameter.Value.Value || m == rnbr)
446                {
447                    double value;
448                    value = parentsSolutions[2].Population[m] +
449                        ScalingFactorParameter.Value.Value * (parentsSolutions[0].Population[m] - parentsSolutions[1].Population[m]);
450                    //check the problem upper and lower bounds
451                    if (value > Problem.Bounds[0, 1]) value = Problem.Bounds[0, 1];
452                    if (value < Problem.Bounds[0, 0]) value = Problem.Bounds[0, 0];
453                    individual.Population[m] = value;
454                }
455                else
456                {
457                    double value;
458                    value = parent.Population[m];
459                    individual.Population[m] = value;
460                }
461            }
462            return individual;
463        }
464
465        private List<SolutionSet> crowdingDistanceSelection(List<SolutionSet>[] ranking)
466        {
467            List<SolutionSet> population = new List<SolutionSet>();
468            int rankingIndex = 0;
469            while (populationIsNotFull(population))
470            {
471                if (subFrontFillsIntoThePopulation(ranking, rankingIndex, population))
472                {
473                    addRankedSolutionToPopulation(ranking, rankingIndex, population);
474                    rankingIndex++;
475                }
476                else {
477                    crowdingDistanceAssignment(ranking[rankingIndex]);
478                    addLastRankedSolutionToPopulation(ranking, rankingIndex, population);
479                }
480            }
481            return population;
482        }
483
484        private void addLastRankedSolutionToPopulation(List<SolutionSet>[] ranking, int rankingIndex, List<SolutionSet> population)
485        {
486            List<SolutionSet> currentRankedFront = ranking[rankingIndex];
487            //descending sort and add the front with highest crowding distance to the population
488            currentRankedFront.Sort((x, y) => -x.CrowdingDistance.CompareTo(y.CrowdingDistance));
489            int i = 0;
490            while (population.Count < PopulationSizeParameter.Value.Value)
491            {
492                population.Add(currentRankedFront[i]);
493                i++;
494            }
495        }
496
497        public void crowdingDistanceAssignment(List<SolutionSet> rankingSubfront)
498        {
499            int size = rankingSubfront.Count;
500
501            if (size == 0)
502                return;
503
504            if (size == 1)
505            {
506                rankingSubfront[0].CrowdingDistance = double.PositiveInfinity;
507                return;
508            }
509
510            if (size == 2)
511            {
512                rankingSubfront[0].CrowdingDistance = double.PositiveInfinity;
513                rankingSubfront[1].CrowdingDistance = double.PositiveInfinity;
514                return;
515            }
516
517            //Use a new SolutionSet to evite alter original solutionSet
518            List<SolutionSet> front = new List<SolutionSet>(size);
519            for (int i = 0; i < size; i++)
520            {
521                front.Add(rankingSubfront[i]);
522            }
523
524            for (int i = 0; i < size; i++)
525                front[i].CrowdingDistance = 0.0;
526
527            double objetiveMaxn;
528            double objetiveMinn;
529            double distance;
530
531            for (int i = 0; i < Problem.Objectives; i++)
532            {
533                // Sort the front population by the objective i         
534                front.Sort((x, y) => x.Quality[i].CompareTo(y.Quality[i]));
535                objetiveMinn = front[0].Quality[i];
536                objetiveMaxn = front[front.Count - 1].Quality[i];
537
538                //Set crowding distance for the current front           
539                front[0].CrowdingDistance = double.PositiveInfinity;
540                front[size - 1].CrowdingDistance = double.PositiveInfinity;
541
542                for (int j = 1; j < size - 1; j++)
543                {
544                    distance = front[j + 1].Quality[i] - front[j - 1].Quality[i];
545                    distance = distance / (objetiveMaxn - objetiveMinn);
546                    distance += front[j].CrowdingDistance;
547                    front[j].CrowdingDistance = distance;
548                }
549            }
550        }
551
552        private void addRankedSolutionToPopulation(List<SolutionSet>[] ranking, int rankingIndex, List<SolutionSet> population)
553        {
554            foreach (SolutionSet solution in ranking[rankingIndex])
555            {
556                population.Add(solution);
557            }
558        }
559
560        private bool subFrontFillsIntoThePopulation(List<SolutionSet>[] ranking, int rankingIndex, List<SolutionSet> population)
561        {
562            return ranking[rankingIndex].Count < (PopulationSizeParameter.Value.Value - population.Count);
563        }
564
565        private bool populationIsNotFull(List<SolutionSet> population)
566        {
567            return population.Count < PopulationSizeParameter.Value.Value;
568        }
569
570        private List<SolutionSet>[] computeRanking(List<SolutionSet> tmpList)
571        {
572            // dominateMe[i] contains the number of solutions dominating i       
573            int[] dominateMe = new int[tmpList.Count];
574
575            // iDominate[k] contains the list of solutions dominated by k
576            List<int>[] iDominate = new List<int>[tmpList.Count];
577
578            // front[i] contains the list of individuals belonging to the front i
579            List<int>[] front = new List<int>[tmpList.Count + 1];
580
581            // flagDominate is an auxiliar encodings.variable
582            int flagDominate;
583
584            // Initialize the fronts
585            for (int i = 0; i < front.Length; i++)
586            {
587                front[i] = new List<int>();
588            }
589
590            //-> Fast non dominated sorting algorithm
591            // Contribution of Guillaume Jacquenot
592            for (int p = 0; p < tmpList.Count; p++)
593            {
594                // Initialize the list of individuals that i dominate and the number
595                // of individuals that dominate me
596                iDominate[p] = new List<int>();
597                dominateMe[p] = 0;
598            }
599            for (int p = 0; p < (tmpList.Count - 1); p++)
600            {
601                // For all q individuals , calculate if p dominates q or vice versa
602                for (int q = p + 1; q < tmpList.Count; q++)
603                {
604                    flagDominate = compareConstraintsViolation(tmpList[p], tmpList[q]);
605                    if (flagDominate == 0) {
606                        flagDominate = compareDomination(tmpList[p], tmpList[q]);
607                    }
608                    if (flagDominate == -1)
609                    {
610                        iDominate[p].Add(q);
611                        dominateMe[q]++;
612                    }
613                    else if (flagDominate == 1)
614                    {
615                        iDominate[q].Add(p);
616                        dominateMe[p]++;
617                    }
618                }
619                // If nobody dominates p, p belongs to the first front
620            }
621            for (int i = 0; i < tmpList.Count; i++)
622            {
623                if (dominateMe[i] == 0)
624                {
625                    front[0].Add(i);
626                    tmpList[i].Rank = 0;
627                }
628            }
629
630            //Obtain the rest of fronts
631            int k = 0;
632
633            while (front[k].Count != 0)
634            {
635                k++;
636                foreach (var it1 in front[k - 1])
637                {
638                    foreach (var it2 in iDominate[it1])
639                    {
640                        int index = it2;
641                        dominateMe[index]--;
642                        if (dominateMe[index] == 0)
643                        {
644                            front[k].Add(index);
645                            tmpList[index].Rank = k;
646                        }
647                    }
648                }
649            }
650            //<-
651
652            var rankedSubpopulation = new List<SolutionSet>[k];
653            //0,1,2,....,i-1 are front, then i fronts
654            for (int j = 0; j < k; j++)
655            {
656                rankedSubpopulation[j] = new List<SolutionSet>(front[j].Count);
657                foreach (var it1 in front[j])
658                {
659                    rankedSubpopulation[j].Add(tmpList[it1]);
660                }
661            }
662            return rankedSubpopulation;
663        }
664
665        private int compareDomination(SolutionSet solution1, SolutionSet solution2)
666        {
667            int dominate1; // dominate1 indicates if some objective of solution1
668                           // dominates the same objective in solution2. dominate2
669            int dominate2; // is the complementary of dominate1.
670
671            dominate1 = 0;
672            dominate2 = 0;
673
674            int flag; //stores the result of the comparison
675
676            // Test to determine whether at least a solution violates some constraint
677            if (needToCompareViolations(solution1, solution2))
678            {
679                return compareConstraintsViolation(solution1, solution2);
680            }
681
682            // Equal number of violated constraints. Applying a dominance Test then
683            double value1, value2;
684            for (int i = 0; i < Problem.Objectives; i++)
685            {
686                value1 = solution1.Quality[i];
687                value2 = solution2.Quality[i];
688                if (value1 < value2)
689                {
690                    flag = -1;
691                }
692                else if (value2 < value1)
693                {
694                    flag = 1;
695                }
696                else
697                {
698                    flag = 0;
699                }
700
701                if (flag == -1)
702                {
703                    dominate1 = 1;
704                }
705
706                if (flag == 1)
707                {
708                    dominate2 = 1;
709                }
710            }
711
712            if (dominate1 == dominate2)
713            {
714                return 0; //No one dominate the other
715            }
716            if (dominate1 == 1)
717            {
718                return -1; // solution1 dominate
719            }
720            return 1;    // solution2 dominate   
721        }
722
723        private bool needToCompareViolations(SolutionSet solution1, SolutionSet solution2)
724        {
725            bool needToCompare;
726            needToCompare = (solution1.OverallConstrainViolation < 0) || (solution2.OverallConstrainViolation < 0);
727
728            return needToCompare;
729        }
730
731        private int compareConstraintsViolation(SolutionSet solution1, SolutionSet solution2)
732        {
733            int result;
734            double overall1, overall2;
735            overall1 = solution1.OverallConstrainViolation;
736            overall2 = solution2.OverallConstrainViolation;
737
738            if ((overall1 < 0) && (overall2 < 0))
739            {
740                if (overall1 > overall2)
741                {
742                    result = -1;
743                }
744                else if (overall2 > overall1)
745                {
746                    result = 1;
747                }
748                else
749                {
750                    result = 0;
751                }
752            }
753            else if ((overall1 == 0) && (overall2 < 0))
754            {
755                result = -1;
756            }
757            else if ((overall1 < 0) && (overall2 == 0))
758            {
759                result = 1;
760            }
761            else
762            {
763                result = 0;
764            }
765            return result;
766        }
767    }
768}
769
770
771
Note: See TracBrowser for help on using the repository browser.