1  using System;


2  using System.Linq;


3  using System.Collections.Generic;


4  using HeuristicLab.Analysis;


5  using HeuristicLab.Common;


6  using HeuristicLab.Core;


7  using HeuristicLab.Data;


8  using HeuristicLab.Encodings.RealVectorEncoding;


9  using HeuristicLab.Operators;


10  using HeuristicLab.Optimization;


11  using HeuristicLab.Optimization.Operators;


12  using HeuristicLab.Parameters;


13  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;


14  using HeuristicLab.PluginInfrastructure;


15  using HeuristicLab.Problems.MultiObjectiveTestFunctions;


16  using HeuristicLab.Random;


17  using System.Threading;


18  using HeuristicLab.Algorithms.GDE3;


19 


20  namespace 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 


49  #region ParameterNames


50  private const string MaximumGenerationsParameterName = "Maximum Generations";


51  private const string CrossoverProbabilityParameterName = "CrossoverProbability";


52  private const string PopulationSizeParameterName = "PopulationSize";


53  private const string ScalingFactorParameterName = "ScalingFactor";


54  #endregion


55 


56  #region ParameterProperties


57  public IFixedValueParameter<IntValue> MaximumGenerationsParameter


58  {


59  get { return (IFixedValueParameter<IntValue>)Parameters[MaximumGenerationsParameterName]; }


60  }


61  private ValueParameter<IntValue> PopulationSizeParameter


62  {


63  get { return (ValueParameter<IntValue>)Parameters[PopulationSizeParameterName]; }


64  }


65  public ValueParameter<DoubleValue> CrossoverProbabilityParameter


66  {


67  get { return (ValueParameter<DoubleValue>)Parameters[CrossoverProbabilityParameterName]; }


68  }


69  public ValueParameter<DoubleValue> ScalingFactorParameter


70  {


71  get { return (ValueParameter<DoubleValue>)Parameters[ScalingFactorParameterName]; }


72  }


73  #endregion


74 


75  #region Properties


76  public int MaximumEvaluations


77  {


78  get { return MaximumGenerationsParameter.Value.Value; }


79  set { MaximumGenerationsParameter.Value.Value = value; }


80  }


81 


82  public Double CrossoverProbability


83  {


84  get { return CrossoverProbabilityParameter.Value.Value; }


85  set { CrossoverProbabilityParameter.Value.Value = value; }


86  }


87  public Double ScalingFactor


88  {


89  get { return ScalingFactorParameter.Value.Value; }


90  set { ScalingFactorParameter.Value.Value = value; }


91  }


92  public IntValue PopulationSize


93  {


94  get { return PopulationSizeParameter.Value; }


95  set { PopulationSizeParameter.Value = value; }


96  }


97  #endregion


98 


99  #region ResultsProperties


100  private double ResultsBestQuality


101  {


102  get { return ((DoubleValue)Results["Best Quality"].Value).Value; }


103  set { ((DoubleValue)Results["Best Quality"].Value).Value = value; }


104  }


105 


106  private double ResultsInvertedGenerationalDistance


107  {


108  get { return ((DoubleValue)Results["InvertedGenerationalDistance"].Value).Value; }


109  set { ((DoubleValue)Results["InvertedGenerationalDistance"].Value).Value = value; }


110  }


111 


112  private double ResultsHypervolume


113  {


114  get { return ((DoubleValue)Results["HyperVolumeValue"].Value).Value; }


115  set { ((DoubleValue)Results["HyperVolumeValue"].Value).Value = value; }


116  }


117 


118  private DoubleMatrix ResultsBestFront


119  {


120  get { return (DoubleMatrix)Results["Best Front"].Value; }


121  set { Results["Best Front"].Value = value; }


122  }


123 


124  private int ResultsEvaluations


125  {


126  get { return ((IntValue)Results["Evaluations"].Value).Value; }


127  set { ((IntValue)Results["Evaluations"].Value).Value = value; }


128  }


129  private int ResultsGenerations


130  {


131  get { return ((IntValue)Results["Generations"].Value).Value; }


132  set { ((IntValue)Results["Generations"].Value).Value = value; }


133  }


134  private double ResultsGenerationalDistance


135  {


136  get { return ((DoubleValue)Results["GenerationalDistance"].Value).Value; }


137  set { ((DoubleValue)Results["GenerationalDistance"].Value).Value = value; }


138  }


139  private int ResultsIterations


140  {


141  get { return ((IntValue)Results["Iterations"].Value).Value; }


142  set { ((IntValue)Results["Iterations"].Value).Value = value; }


143  }


144 


145  private double ResultsSpacing


146  {


147  get { return ((DoubleValue)Results["Spacing"].Value).Value; }


148  set { ((DoubleValue)Results["Spacing"].Value).Value = value; }


149  }


150 


151  private double ResultsCrowding


152  {


153  get { return ((DoubleValue)Results["Crowding"].Value).Value; }


154  set { ((DoubleValue)Results["Crowding"].Value).Value = value; }


155  }


156 


157  #endregion


158 


159  [StorableConstructor]


160  protected GDE3(bool deserializing) : base(deserializing) { }


161 


162  protected GDE3(GDE3 original, Cloner cloner)


163  : base(original, cloner)


164  {


165  }


166 


167  public override IDeepCloneable Clone(Cloner cloner)


168  {


169  return new GDE3(this, cloner);


170  }


171 


172  public GDE3()


173  {


174  Parameters.Add(new FixedValueParameter<IntValue>(MaximumGenerationsParameterName, "", new IntValue(1000)));


175  Parameters.Add(new ValueParameter<IntValue>(PopulationSizeParameterName, "The size of the population of solutions.", new IntValue(100)));


176  Parameters.Add(new ValueParameter<DoubleValue>(CrossoverProbabilityParameterName, "The value for crossover rate", new DoubleValue(0.5)));


177  Parameters.Add(new ValueParameter<DoubleValue>(ScalingFactorParameterName, "The value for scaling factor", new DoubleValue(0.5)));


178  Parameters.Add(new LookupParameter<DoubleMatrix>("BestKnownFront", "The currently best known Pareto front"));


179  }


180 


181  protected override void Run(CancellationToken cancellationToken)


182  {


183  // Set up the results display


184  Results.Add(new Result("Generations", new IntValue(0)));


185  Results.Add(new Result("Evaluations", new IntValue(0)));


186  Results.Add(new Result("Best Front", new DoubleMatrix()));


187  Results.Add(new Result("Crowding", new DoubleValue(0)));


188  Results.Add(new Result("InvertedGenerationalDistance", new DoubleValue(0)));


189  Results.Add(new Result("GenerationalDistance", new DoubleValue(0)));


190  Results.Add(new Result("HyperVolumeValue", new DoubleValue(0)));


191  Results.Add(new Result("Spacing", new DoubleValue(0)));


192  Results.Add(new Result("Scatterplot", typeof(IMOFrontModel)));


193  var table = new DataTable("Qualities");


194  table.Rows.Add(new DataRow("Best Quality"));


195  Results.Add(new Result("Qualities", table));


196 


197  //setup the variables


198  List<SolutionSet> population;


199  List<SolutionSet> offspringPopulation;


200  SolutionSet[] parent;


201 


202  //initialize population


203  population = new List<SolutionSet>(PopulationSizeParameter.Value.Value);


204 


205  for (int i = 0; i < PopulationSizeParameter.Value.Value; ++i)


206  {


207  var m = createIndividual();


208  population.Add(m);


209  }


210 


211  this.initProgress();


212  int iterations = 1;


213 


214  while (ResultsGenerations < MaximumGenerationsParameter.Value.Value


215  && !cancellationToken.IsCancellationRequested)


216  {


217  var populationSize = PopulationSizeParameter.Value.Value;


218 


219  // Create the offSpring solutionSet


220  offspringPopulation = new List<SolutionSet>(PopulationSizeParameter.Value.Value * 2);


221 


222  for (int i = 0; i < populationSize; i++)


223  {


224  // Obtain parents. Two parameters are required: the population and the


225  // index of the current individual


226  parent = selection(population, i);


227 


228  SolutionSet child;


229  // Crossover. The parameters are the current individual and the index of the array of parents


230  child = reproduction(population[i], parent);


231 


232  child.Quality = Problem.Evaluate(child.Population, _random);


233  this.updateProgres();


234 


235  // Dominance test


236  int result;


237  result = compareDomination(population[i].Quality, child.Quality);


238  if (result == 1)


239  { // Solution i dominates child


240  offspringPopulation.Add(population[i]);


241  }


242  else if (result == 1)


243  { // child dominates


244  offspringPopulation.Add(child);


245  }


246  else


247  { // the two solutions are nondominated


248  offspringPopulation.Add(child);


249  offspringPopulation.Add(population[i]);


250  }


251  }


252  // Ranking the offspring population


253  List<SolutionSet>[] ranking = computeRanking(offspringPopulation);


254 


255  int remain = populationSize;


256  int index = 0;


257  population.Clear();


258  List<SolutionSet> front = null;


259 


260  // Obtain the next front


261  front = ranking[index];


262 


263  while ((remain > 0) && (remain >= front.Count))


264  {


265  //Assign crowding distance to individuals


266  crowdingDistanceAssignment(front, index);


267  //Add the individuals of this front


268  for (int k = 0; k < front.Count; k++)


269  {


270  population.Add(front[k]);


271  } // for


272 


273  //Decrement remain


274  remain = remain  front.Count;


275 


276  //Obtain the next front


277  index++;


278  if (remain > 0)


279  {


280  front = ranking[index];


281  }


282  }


283 


284  // remain is less than front(index).size, insert only the best one


285  if (remain > 0)


286  { // front contains individuals to insert


287  while (front.Count > remain)


288  {


289  crowdingDistanceAssignment(front, index);


290  int indx = getWorstIndex(front);


291  front.RemoveAt(indx);


292  }


293  for (int k = 0; k < front.Count; k++)


294  {


295  population.Add(front[k]);


296  }


297 


298  remain = 0;


299  }


300  iterations++;


301  ResultsGenerations = iterations;


302  displayResults(front);


303  }


304  }


305 


306  private void displayResults(List<SolutionSet> population)


307  {


308  //compute the 0 front


309  // Return the first nondominated front


310  List<SolutionSet>[] rankingFinal = computeRanking(population);


311 


312  int objectives = Problem.Objectives;


313  var optimalfront = Problem.TestFunction.OptimalParetoFront(objectives);


314 


315  double[][] opf = new double[0][];


316  if (optimalfront != null)


317  {


318  opf = optimalfront.Select(s => s.ToArray()).ToArray();


319  }


320 


321  double[][] qualitiesFinal = new double[rankingFinal[0].Count][];


322 


323  for (int i = 0; i < rankingFinal[0].Count; ++i)


324  {


325  qualitiesFinal[i] = new double[Problem.Objectives];


326  for (int j = 0; j < Problem.Objectives; ++j)


327  {


328  qualitiesFinal[i][j] = rankingFinal[0][i].Quality[j];


329  }


330  }


331 


332  double[][] populationFinal = new double[rankingFinal[0].Count][];


333 


334  for (int i = 0; i < rankingFinal[0].Count; ++i)


335  {


336  populationFinal[i] = new double[Problem.ProblemSize];


337  for (int j = 0; j < Problem.ProblemSize; ++j)


338  {


339  populationFinal[i][j] = rankingFinal[0][i].Population[j];


340  }


341  }


342  IEnumerable<double[]> en = qualitiesFinal;


343  IEnumerable<double[]> frontVectors = NonDominatedSelect.selectNonDominatedVectors(qualitiesFinal, Problem.TestFunction.Maximization(objectives), true);


344  //update the results


345 


346  ResultsEvaluations = this.evals;


347  ResultsBestFront = new DoubleMatrix(MultiObjectiveTestFunctionProblem.To2D(qualitiesFinal));


348  ResultsCrowding = Crowding.Calculate(qualitiesFinal, Problem.TestFunction.Bounds(objectives));


349  ResultsInvertedGenerationalDistance = InvertedGenerationalDistance.Calculate(en, optimalfront, 1);


350  ResultsHypervolume = Hypervolume.Calculate(frontVectors, Problem.TestFunction.ReferencePoint(objectives), Problem.TestFunction.Maximization(objectives));


351  ResultsGenerationalDistance = GenerationalDistance.Calculate(qualitiesFinal, optimalfront, 1);


352  Results["Scatterplot"].Value = new MOSolution(qualitiesFinal, populationFinal, opf, objectives);


353  ResultsSpacing = Spacing.Calculate(qualitiesFinal);


354  }


355 


356  private int getWorstIndex(List<SolutionSet> SolutionsList)


357  {


358  int result = 0;


359 


360  if ((SolutionsList == null)  SolutionsList.Count == 0)


361  {


362  result = 0;


363  }


364  else


365  {


366  SolutionSet worstKnown = SolutionsList[0],


367  candidateSolution;


368  int flag;


369  for (int i = 1; i < SolutionsList.Count; i++)


370  {


371  candidateSolution = SolutionsList[i];


372  flag = compareDomination(worstKnown.Quality, candidateSolution.Quality);


373  if (flag == 1)


374  {


375  result = i;


376  worstKnown = candidateSolution;


377  }


378  }


379  }


380  return result;


381  }


382 


383  protected SolutionSet createIndividual()


384  {


385  var dim = Problem.ProblemSize;


386  var lb = Problem.Bounds[0, 0];


387  var ub = Problem.Bounds[0, 1];


388  var range = ub  lb;


389  var v = new double[Problem.ProblemSize];


390  SolutionSet solutionObject = new SolutionSet(PopulationSizeParameter.Value.Value);


391 


392  for (int i = 0; i < Problem.ProblemSize; ++i)


393  {


394  v[i] = _random.NextDouble() * range + lb;


395 


396  }


397  var m = new RealVector(v);


398  solutionObject.Population = m;


399  solutionObject.Quality = Problem.Evaluate(m, _random);


400  return solutionObject;


401  }


402 


403  private SolutionSet createEmptyIndividual()


404  {


405  SolutionSet solutionObject = new SolutionSet(PopulationSizeParameter.Value.Value);


406  var n = new RealVector(Problem.ProblemSize);


407  solutionObject.Population = n;


408  return solutionObject;


409  }


410 


411  protected void initProgress()


412  {


413  this.evals = PopulationSizeParameter.Value.Value;


414  }


415 


416  protected void updateProgres()


417  {


418  this.evals++;


419  }


420 


421  protected SolutionSet[] selection(List<SolutionSet> population, int i)


422  {


423  SolutionSet[] parents = new SolutionSet[3];


424  int r0, r1, r2;


425  //assure the selected vectors r0, r1 and r2 are different


426  do


427  {


428  r0 = _random.Next(0, PopulationSizeParameter.Value.Value);


429  } while (r0 == i);


430  do


431  {


432  r1 = _random.Next(0, PopulationSizeParameter.Value.Value);


433  } while (r1 == i  r1 == r0);


434  do


435  {


436  r2 = _random.Next(0, PopulationSizeParameter.Value.Value);


437  } while (r2 == i  r2 == r0  r2 == r1);


438 


439  parents[0] = population[r0];


440  parents[1] = population[r1];


441  parents[2] = population[r2];


442 


443  return parents;


444  }


445 


446  protected SolutionSet reproduction(SolutionSet parent, SolutionSet[] parentsSolutions)


447  {


448  var individual = createEmptyIndividual();


449  double rnbr = _random.Next(0, Problem.ProblemSize);


450  for (int m = 0; m < Problem.ProblemSize; m++)


451  {


452  if (_random.NextDouble() < CrossoverProbabilityParameter.Value.Value  m == rnbr)


453  {


454  double value;


455  value = parentsSolutions[2].Population[m] +


456  ScalingFactorParameter.Value.Value * (parentsSolutions[0].Population[m]  parentsSolutions[1].Population[m]);


457  //check the problem upper and lower bounds


458  if (value > Problem.Bounds[0, 1]) value = Problem.Bounds[0, 1];


459  if (value < Problem.Bounds[0, 0]) value = Problem.Bounds[0, 0];


460  individual.Population[m] = value;


461  }


462  else


463  {


464  double value;


465  value = parent.Population[m];


466  individual.Population[m] = value;


467  }


468  }


469  return individual;


470  }


471 


472  private List<SolutionSet> replacement(List<SolutionSet> population, List<SolutionSet> offspringPopulation)


473  {


474  List<SolutionSet> tmpList = new List<SolutionSet>();


475  for (int i = 0; i < PopulationSizeParameter.Value.Value; i++)


476  {


477  int result;


478  result = compareDomination(population[i].Quality, offspringPopulation[i].Quality);


479  if (result == 1)


480  { // Solution i dominates child


481  tmpList.Add(population[i]);


482  }


483  else if (result == 1)


484  { // child dominates


485  tmpList.Add(offspringPopulation[i]);


486  }


487  else


488  { // the two solutions are nondominated


489  tmpList.Add(offspringPopulation[i]);


490  tmpList.Add(population[i]);


491  }


492  }


493 


494  List<SolutionSet>[] ranking = computeRanking(tmpList);


495  List<SolutionSet> finalPopulation = crowdingDistanceSelection(ranking);


496  return finalPopulation;


497  }


498 


499  private List<SolutionSet> crowdingDistanceSelection(List<SolutionSet>[] ranking)


500  {


501  List<SolutionSet> population = new List<SolutionSet>();


502  int rankingIndex = 0;


503  while (populationIsNotFull(population))


504  {


505  if (subFrontFillsIntoThePopulation(ranking, rankingIndex, population))


506  {


507  addRankedSolutionToPopulation(ranking, rankingIndex, population);


508  rankingIndex++;


509  }


510  else {


511  crowdingDistanceAssignment(ranking[rankingIndex], rankingIndex);


512  addLastRankedSolutionToPopulation(ranking, rankingIndex, population);


513  }


514  }


515  return population;


516  }


517 


518  private void addLastRankedSolutionToPopulation(List<SolutionSet>[] ranking, int rankingIndex, List<SolutionSet> population)


519  {


520  List<SolutionSet> currentRankedFront = ranking[rankingIndex];


521  currentRankedFront.Sort((x, y) => x.CrowdingDistance.CompareTo(y.CrowdingDistance));


522  int i = 0;


523  while (population.Count < PopulationSizeParameter.Value.Value)


524  {


525  population.Add(currentRankedFront[i]);


526  i++;


527  }


528  }


529 


530  public void crowdingDistanceAssignment(List<SolutionSet> rankingSubfront, int index)


531  {


532  int size = rankingSubfront.Count;


533 


534  if (size == 0)


535  return;


536 


537  if (size == 1)


538  {


539  rankingSubfront[0].CrowdingDistance = double.PositiveInfinity;


540  return;


541  }


542 


543  if (size == 2)


544  {


545  rankingSubfront[0].CrowdingDistance = double.PositiveInfinity;


546  rankingSubfront[1].CrowdingDistance = double.PositiveInfinity;


547  return;


548  }


549 


550  //Use a new SolutionSet to evite alter original solutionSet


551  List<SolutionSet> front = new List<SolutionSet>(size);


552  for (int i = 0; i < size; i++)


553  {


554  front.Add(rankingSubfront[i]);


555  }


556 


557  for (int i = 0; i < size; i++)


558  rankingSubfront[i].CrowdingDistance = 0.0;


559 


560  double objetiveMaxn;


561  double objetiveMinn;


562  double distance;


563 


564  for (int i = 0; i < Problem.Objectives; i++)


565  {


566  // Sort the population by Obj n


567  front.Sort((x, y) => x.Quality[i].CompareTo(y.Quality[i]));


568  objetiveMinn = front[0].Quality[i];


569  objetiveMaxn = front[front.Count  1].Quality[i];


570 


571  //Set de crowding distance


572  front[0].CrowdingDistance = double.PositiveInfinity;


573  front[size  1].CrowdingDistance = double.PositiveInfinity;


574 


575  for (int j = 1; j < size  1; j++)


576  {


577  distance = front[j + 1].Quality[i]  front[j  1].Quality[i];


578  distance = distance / (objetiveMaxn  objetiveMinn);


579  distance += front[j].CrowdingDistance;


580  front[j].CrowdingDistance = distance;


581  }


582  }


583  }


584 


585  private void addRankedSolutionToPopulation(List<SolutionSet>[] ranking, int rankingIndex, List<SolutionSet> population)


586  {


587  foreach (SolutionSet solution in ranking[rankingIndex])


588  {


589  population.Add(solution);


590  }


591  }


592 


593  private bool subFrontFillsIntoThePopulation(List<SolutionSet>[] ranking, int rankingIndex, List<SolutionSet> population)


594  {


595  return ranking[rankingIndex].Count < (PopulationSizeParameter.Value.Value  population.Count);


596  }


597 


598  private bool populationIsNotFull(List<SolutionSet> population)


599  {


600  return population.Count < PopulationSizeParameter.Value.Value;


601  }


602 


603  private List<SolutionSet>[] computeRanking(List<SolutionSet> tmpList)


604  {


605  // dominateMe[i] contains the number of solutions dominating i


606  int[] dominateMe = new int[tmpList.Count];


607 


608  // iDominate[k] contains the list of solutions dominated by k


609  List<int>[] iDominate = new List<int>[tmpList.Count];


610 


611  // front[i] contains the list of individuals belonging to the front i


612  List<int>[] front = new List<int>[tmpList.Count + 1];


613 


614  // flagDominate is an auxiliar encodings.variable


615  int flagDominate;


616 


617  // Initialize the fronts


618  for (int i = 0; i < front.Length; i++)


619  {


620  front[i] = new List<int>();


621  }


622 


623  //> Fast non dominated sorting algorithm


624  // Contribution of Guillaume Jacquenot


625  for (int p = 0; p < tmpList.Count; p++)


626  {


627  // Initialize the list of individuals that i dominate and the number


628  // of individuals that dominate me


629  iDominate[p] = new List<int>();


630  dominateMe[p] = 0;


631  }


632  for (int p = 0; p < (tmpList.Count  1); p++)


633  {


634  // For all q individuals , calculate if p dominates q or vice versa


635  for (int q = p + 1; q < tmpList.Count; q++)


636  {


637  flagDominate = compareDomination(tmpList[p].Quality, tmpList[q].Quality);


638  if (flagDominate == 1)


639  {


640  iDominate[p].Add(q);


641  dominateMe[q]++;


642  }


643  else if (flagDominate == 1)


644  {


645  iDominate[q].Add(p);


646  dominateMe[p]++;


647  }


648  }


649  // If nobody dominates p, p belongs to the first front


650  }


651  for (int i = 0; i < tmpList.Count; i++)


652  {


653  if (dominateMe[i] == 0)


654  {


655  front[0].Add(i);


656  tmpList[i].Rank = 0;


657  }


658  }


659 


660  //Obtain the rest of fronts


661  int k = 0;


662 


663  while (front[k].Count != 0)


664  {


665  k++;


666  foreach (var it1 in front[k  1])


667  {


668  foreach (var it2 in iDominate[it1])


669  {


670  int index = it2;


671  dominateMe[index];


672  if (dominateMe[index] == 0)


673  {


674  front[k].Add(index);


675  tmpList[index].Rank = k;


676  }


677  }


678  }


679  }


680  //<


681 


682  var rankedSubpopulation = new List<SolutionSet>[k];


683  //0,1,2,....,i1 are front, then i fronts


684  for (int j = 0; j < k; j++)


685  {


686  rankedSubpopulation[j] = new List<SolutionSet>(front[j].Count);


687  foreach (var it1 in front[j])


688  {


689  rankedSubpopulation[j].Add(tmpList[it1]);


690  }


691  }


692  return rankedSubpopulation;


693  }


694 


695  private int compareDomination(double[] solution1, double[] solution2)


696  {


697  int dominate1; // dominate1 indicates if some objective of solution1


698  // dominates the same objective in solution2. dominate2


699  int dominate2; // is the complementary of dominate1.


700 


701  dominate1 = 0;


702  dominate2 = 0;


703 


704  int flag; //stores the result of the comparison


705 


706  // Equal number of violated constraints. Applying a dominance Test then


707  double value1, value2;


708  for (int i = 0; i < Problem.Objectives; i++)


709  {


710  value1 = solution1[i];


711  value2 = solution2[i];


712  if (value1 < value2)


713  {


714  flag = 1;


715  }


716  else if (value1 > value2)


717  {


718  flag = 1;


719  }


720  else


721  {


722  flag = 0;


723  }


724 


725  if (flag == 1)


726  {


727  dominate1 = 1;


728  }


729 


730  if (flag == 1)


731  {


732  dominate2 = 1;


733  }


734  }


735 


736  if (dominate1 == dominate2)


737  {


738  return 0; //No one dominate the other


739  }


740  if (dominate1 == 1)


741  {


742  return 1; // solution1 dominate


743  }


744  return 1; // solution2 dominate


745  }


746  }


747  }


748 


749 


750 

