1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)


4  *


5  * This file is part of HeuristicLab.


6  *


7  * HeuristicLab is free software: you can redistribute it and/or modify


8  * it under the terms of the GNU General Public License as published by


9  * the Free Software Foundation, either version 3 of the License, or


10  * (at your option) any later version.


11  *


12  * HeuristicLab is distributed in the hope that it will be useful,


13  * but WITHOUT ANY WARRANTY; without even the implied warranty of


14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


15  * GNU General Public License for more details.


16  *


17  * You should have received a copy of the GNU General Public License


18  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.


19  */


20  #endregion


21 


22  using System;


23  using System.Collections.Generic;


24  using System.Linq;


25  using HeuristicLab.Core;


26  using HeuristicLab.Data;


27  using HeuristicLab.Operators;


28  using HeuristicLab.Parameters;


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


30 


31  namespace HeuristicLab.Optimization.Operators {


32  [Item("WeightedParentsQualityComparator", "Compares the quality against that of its parents (assumes the parents are subscopes to the child scope). This operator works with any number of subscopes > 0.")]


33  [StorableClass]


34  public class WeightedParentsQualityComparator : SingleSuccessorOperator, ISubScopesQualityComparator {


35  public IValueLookupParameter<BoolValue> MaximizationParameter {


36  get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }


37  }


38  public ILookupParameter<DoubleValue> LeftSideParameter {


39  get { return (ILookupParameter<DoubleValue>)Parameters["LeftSide"]; }


40  }


41  public ILookupParameter<ItemArray<DoubleValue>> RightSideParameter {


42  get { return (ILookupParameter<ItemArray<DoubleValue>>)Parameters["RightSide"]; }


43  }


44  public ILookupParameter<BoolValue> ResultParameter {


45  get { return (ILookupParameter<BoolValue>)Parameters["Result"]; }


46  }


47  public ValueLookupParameter<DoubleValue> ComparisonFactorParameter {


48  get { return (ValueLookupParameter<DoubleValue>)Parameters["ComparisonFactor"]; }


49  }


50 


51  public WeightedParentsQualityComparator()


52  : base() {


53  Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));


54  Parameters.Add(new LookupParameter<DoubleValue>("LeftSide", "The quality of the child."));


55  Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("RightSide", "The qualities of the parents."));


56  Parameters.Add(new LookupParameter<BoolValue>("Result", "The result of the comparison: True means Quality is better, False means it is worse than parents."));


57  Parameters.Add(new ValueLookupParameter<DoubleValue>("ComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them."));


58  }


59 


60  public override IOperation Apply() {


61  ItemArray<DoubleValue> rightQualities = RightSideParameter.ActualValue;


62  if (rightQualities.Length < 1) throw new InvalidOperationException(Name + ": No subscopes found.");


63  double compFact = ComparisonFactorParameter.ActualValue.Value;


64  bool maximization = MaximizationParameter.ActualValue.Value;


65  double leftQuality = LeftSideParameter.ActualValue.Value;


66 


67  double threshold = 0;


68 


69  #region Calculate threshold


70  if (rightQualities.Length == 2) { // this case will probably be used most often


71  double minQuality = Math.Min(rightQualities[0].Value, rightQualities[1].Value);


72  double maxQuality = Math.Max(rightQualities[0].Value, rightQualities[1].Value);


73  if (maximization)


74  threshold = minQuality + (maxQuality  minQuality) * compFact;


75  else


76  threshold = maxQuality  (maxQuality  minQuality) * compFact;


77  } else if (rightQualities.Length == 1) { // case for just one parent


78  threshold = rightQualities[0].Value;


79  } else { // general case extended to 3 or more parents


80  List<double> sortedQualities = rightQualities.Select(x => x.Value).ToList();


81  sortedQualities.Sort();


82  double minimumQuality = sortedQualities.First();


83 


84  double integral = 0;


85  for (int i = 0; i < sortedQualities.Count  1; i++) {


86  integral += (sortedQualities[i] + sortedQualities[i + 1]) / 2.0; // sum of the trapezoid


87  }


88  integral = minimumQuality * sortedQualities.Count;


89  if (integral == 0) threshold = sortedQualities[0]; // all qualities are equal


90  else {


91  double selectedArea = integral * (maximization ? compFact : (1  compFact));


92  integral = 0;


93  for (int i = 0; i < sortedQualities.Count  1; i++) {


94  double currentSliceArea = (sortedQualities[i] + sortedQualities[i + 1]) / 2.0;


95  double windowedSliceArea = currentSliceArea  minimumQuality;


96  if (windowedSliceArea == 0) continue;


97  integral += windowedSliceArea;


98  if (integral >= selectedArea) {


99  double factor = 1  ((integral  selectedArea) / (windowedSliceArea));


100  threshold = sortedQualities[i] + (sortedQualities[i + 1]  sortedQualities[i]) * factor;


101  break;


102  }


103  }


104  }


105  }


106  #endregion


107 


108  bool result = maximization && leftQuality > threshold  !maximization && leftQuality < threshold;


109  BoolValue resultValue = ResultParameter.ActualValue;


110  if (resultValue == null) {


111  ResultParameter.ActualValue = new BoolValue(result);


112  } else {


113  resultValue.Value = result;


114  }


115 


116  return base.Apply();


117  }


118  }


119  }

