Free cookie consent management tool by TermsFeed Policy Generator

source: branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/Comparators/PopulationQualityComparator.cs @ 13599

Last change on this file since 13599 was 12079, checked in by ascheibe, 10 years ago

#2267 adapted branch to changes from #2332

File size: 13.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 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
22using System.Linq;
23using HeuristicLab.Analysis;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Operators;
28using HeuristicLab.Optimization;
29using HeuristicLab.Optimization.Operators;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.PluginInfrastructure;
33
34namespace HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm {
35  [Item("PopulationQualityComparator", "Compares the quality of the child to the population.")]
36  [StorableClass]
37  public class PopulationQualityComparator : SingleSuccessorOperator, ISubScopesQualityComparatorOperator {
38    [Storable]
39    public ISolutionSimilarityCalculator SimilarityCalculator { get; set; }
40    public IValueLookupParameter<ISolutionSimilarityCalculator> SimilarityCalculatorParameter {
41      get { return (IValueLookupParameter<ISolutionSimilarityCalculator>)Parameters["SimilarityCalculator"]; }
42    }
43    public IValueLookupParameter<BoolValue> MaximizationParameter {
44      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
45    }
46    public ILookupParameter<DoubleValue> LeftSideParameter {
47      get { return (ILookupParameter<DoubleValue>)Parameters["LeftSide"]; }
48    }
49    public ILookupParameter<ItemArray<DoubleValue>> RightSideParameter {
50      get { return (ILookupParameter<ItemArray<DoubleValue>>)Parameters["RightSide"]; }
51    }
52    public ILookupParameter<BoolValue> ResultParameter {
53      get { return (ILookupParameter<BoolValue>)Parameters["Result"]; }
54    }
55    public ValueLookupParameter<DoubleValue> ComparisonFactorParameter {
56      get { return (ValueLookupParameter<DoubleValue>)Parameters["ComparisonFactor"]; }
57    }
58    public ValueLookupParameter<DoubleValue> DiversityComparisonFactorParameter {
59      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactor"]; }
60    }
61    private ValueLookupParameter<DoubleValue> ComparisonFactorLowerBoundParameter {
62      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactorLowerBound"]; }
63    }
64    private ValueLookupParameter<DoubleValue> ComparisonFactorUpperBoundParameter {
65      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactorUpperBound"]; }
66    }
67    public IConstrainedValueParameter<IDiscreteDoubleValueModifier> ComparisonFactorModifierParameter {
68      get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["ComparisonFactorModifier"]; }
69    }
70    public ValueLookupParameter<ResultCollection> ResultsParameter {
71      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
72    }
73    public ILookupParameter<IntValue> GenerationsParameter {
74      get { return (LookupParameter<IntValue>)Parameters["Generations"]; }
75    }
76    public ValueParameter<BoolValue> EnableDivCriteriaParameter {
77      get { return (ValueParameter<BoolValue>)Parameters["EnableDivCriteria"]; }
78    }
79
80    private const string spDetailsParameterName = "SPDetails";
81    private const string divDataRowName = "DiversitySuccessCount";
82    private const string qualityDataRowName = "QualitySuccessCount";
83    private const string divFailDataRowName = "DiversityFailCount";
84    private const string qualityFailDataRowName = "QualityFailCount";
85    private const string overallCountDataRowName = "OverallCount";
86    private const string successCountDataRowName = "SuccessCount";
87
88    [Storable]
89    private int currentGeneration;
90    [Storable]
91    private int divCount;
92    [Storable]
93    private int qualityCount;
94    [Storable]
95    private int badQualityCount;
96    [Storable]
97    private int badDivCount;
98    [Storable]
99    private int overallCount;
100    [Storable]
101    private int successCount;
102
103    [StorableConstructor]
104    protected PopulationQualityComparator(bool deserializing) : base(deserializing) { }
105    protected PopulationQualityComparator(PopulationQualityComparator original, Cloner cloner)
106      : base(original, cloner) {
107      SimilarityCalculator = cloner.Clone(original.SimilarityCalculator);
108      currentGeneration = original.currentGeneration;
109      divCount = original.divCount;
110      qualityCount = original.qualityCount;
111      overallCount = original.overallCount;
112      successCount = original.successCount;
113      badDivCount = original.badDivCount;
114      badQualityCount = original.badQualityCount;
115    }
116    public PopulationQualityComparator()
117      : base() {
118      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
119      Parameters.Add(new LookupParameter<DoubleValue>("LeftSide", "The quality of the child."));
120      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("RightSide", "The qualities of the parents."));
121      Parameters.Add(new LookupParameter<BoolValue>("Result", "The result of the comparison: True means Quality is better, False means it is worse than parents."));
122      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."));
123      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactor", "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.", new DoubleValue(0.0)));
124      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactorLowerBound", "The lower bound of the comparison factor (start).", new DoubleValue(0.5)));
125      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactorUpperBound", "The upper bound of the comparison factor (end).", new DoubleValue(1.0)));
126      Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>("ComparisonFactorModifier", "The operator used to modify the comparison factor.", new ItemSet<IDiscreteDoubleValueModifier>(new IDiscreteDoubleValueModifier[] { new LinearDiscreteDoubleValueModifier() }), new LinearDiscreteDoubleValueModifier()));
127      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the population diversity analysis results should be stored."));
128      Parameters.Add(new LookupParameter<IntValue>("Generations", "The current number of generations."));
129      Parameters.Add(new ValueParameter<BoolValue>("EnableDivCriteria", "Use diversity as additional offspring selection criteria.", new BoolValue(false)));
130      Parameters.Add(new ValueLookupParameter<ISolutionSimilarityCalculator>("SimilarityCalculator", "The similarity calculator that should be used to calculate solution similarity."));
131
132      foreach (IDiscreteDoubleValueModifier modifier in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name))
133        ComparisonFactorModifierParameter.ValidValues.Add(modifier);
134      IDiscreteDoubleValueModifier linearModifier = ComparisonFactorModifierParameter.ValidValues.FirstOrDefault(x => x.GetType().Name.Equals("LinearDiscreteDoubleValueModifier"));
135      if (linearModifier != null) ComparisonFactorModifierParameter.Value = linearModifier;
136      ParameterizeComparisonFactorModifiers();
137    }
138
139    public override IDeepCloneable Clone(Cloner cloner) {
140      return new PopulationQualityComparator(this, cloner);
141    }
142
143    [StorableHook(HookType.AfterDeserialization)]
144    private void AfterDeserialization() {
145      // BackwardsCompatibility3.3
146      #region Backwards compatible code, remove with 3.4
147      if (!Parameters.ContainsKey("SimilarityCalculator"))
148        Parameters.Add(new ValueLookupParameter<ISolutionSimilarityCalculator>("SimilarityCalculator", "The similarity calculator that should be used to calculate solution similarity."));
149      #endregion
150    }
151
152    private void ParameterizeComparisonFactorModifiers() {
153      //TODO: does not work if Generations parameter names are changed
154      foreach (IDiscreteDoubleValueModifier modifier in ComparisonFactorModifierParameter.ValidValues) {
155        modifier.IndexParameter.ActualName = "Generations";
156        modifier.EndIndexParameter.ActualName = "MaximumGenerations";
157        modifier.EndValueParameter.ActualName = ComparisonFactorUpperBoundParameter.Name;
158        modifier.StartIndexParameter.Value = new IntValue(0);
159        modifier.StartValueParameter.ActualName = ComparisonFactorLowerBoundParameter.Name;
160        modifier.ValueParameter.ActualName = "DiversityComparisonFactor";
161      }
162    }
163
164    private IScope GetRemainingScope() {
165      var scope = ExecutionContext.Scope;
166
167      while (scope != null) {
168        if (scope.SubScopes.Any(x => x.Name == "Remaining")) {
169          return scope.SubScopes.Single(x => x.Name == "Remaining");
170        }
171        scope = scope.Parent;
172      }
173      return null;
174    }
175
176    public override IOperation Apply() {
177      double compFact = ComparisonFactorParameter.ActualValue.Value;
178      double diversityComFact = DiversityComparisonFactorParameter.ActualValue.Value;
179      bool maximization = MaximizationParameter.ActualValue.Value;
180      double leftQuality = LeftSideParameter.ActualValue.Value;
181      bool resultDiversity;
182
183      DataTable spDetailsTable;
184      if (ResultsParameter.ActualValue.ContainsKey(spDetailsParameterName)) {
185        spDetailsTable = (DataTable)ResultsParameter.ActualValue[spDetailsParameterName].Value;
186      } else {
187        spDetailsTable = new DataTable(spDetailsParameterName);
188        spDetailsTable.Rows.Add(new DataRow(divDataRowName));
189        spDetailsTable.Rows.Add(new DataRow(qualityDataRowName));
190        spDetailsTable.Rows.Add(new DataRow(overallCountDataRowName));
191        spDetailsTable.Rows.Add(new DataRow(successCountDataRowName));
192        spDetailsTable.Rows.Add(new DataRow(divFailDataRowName));
193        spDetailsTable.Rows.Add(new DataRow(qualityFailDataRowName));
194        ResultsParameter.ActualValue.Add(new Result(spDetailsParameterName, spDetailsTable));
195      }
196
197      if (GenerationsParameter.ActualValue.Value != currentGeneration) {
198        spDetailsTable.Rows[divDataRowName].Values.Add(divCount);
199        divCount = 0;
200        spDetailsTable.Rows[qualityDataRowName].Values.Add(qualityCount);
201        qualityCount = 0;
202        spDetailsTable.Rows[overallCountDataRowName].Values.Add(overallCount);
203        overallCount = 0;
204        spDetailsTable.Rows[successCountDataRowName].Values.Add(successCount);
205        successCount = 0;
206        spDetailsTable.Rows[qualityFailDataRowName].Values.Add(badQualityCount);
207        badQualityCount = 0;
208        spDetailsTable.Rows[divFailDataRowName].Values.Add(badDivCount);
209        badDivCount = 0;
210        currentGeneration = GenerationsParameter.ActualValue.Value;
211      }
212
213      string qualityVariableName = ((ISingleObjectiveSolutionSimilarityCalculator)SimilarityCalculator).QualityVariableName;
214      string solutionVariableName = ((ISingleObjectiveSolutionSimilarityCalculator)SimilarityCalculator).SolutionVariableName;
215
216      var remainingScope = GetRemainingScope();
217      double oldPopQuality = 0.0;
218      int popSize = 0;
219      foreach (IScope oldSolScope in remainingScope.SubScopes) {
220        double curQuality = ((DoubleValue)oldSolScope.Variables[qualityVariableName].Value).Value;
221        IItem curSol = oldSolScope.Variables[solutionVariableName].Value;
222        oldPopQuality += curQuality;
223        popSize++;
224      }
225
226      //diversity compared to population
227      Scope fakeScope = new Scope();
228      fakeScope.SubScopes.Add((IScope)ExecutionContext.Scope.Clone());
229      var similarities = SimilarityCalculator.CalculateSolutionCrowdSimilarity(fakeScope, remainingScope);
230      double averageSimilarity = similarities[0].Average();
231      resultDiversity = averageSimilarity < diversityComFact;
232
233
234      //quality compared to population
235      double averageQuality = oldPopQuality / popSize;
236      bool result = maximization && leftQuality > averageQuality || !maximization && leftQuality < averageQuality;
237
238      //collect statistics
239      if (result) {
240        qualityCount++;
241      } else {
242        badQualityCount++;
243      }
244      if (resultDiversity) {
245        divCount++;
246      } else {
247        badDivCount++;
248      }
249      if (result && resultDiversity) {
250        successCount++;
251      }
252      overallCount++;
253
254      //use diveristiy criteria or not
255      if (EnableDivCriteriaParameter.Value.Value) {
256        result = result && resultDiversity;
257      }
258
259      BoolValue resultValue = ResultParameter.ActualValue;
260      if (resultValue == null) {
261        ResultParameter.ActualValue = new BoolValue(result);
262      } else {
263        resultValue.Value = result;
264      }
265
266      //like the placeholder, though we create child operations
267      OperationCollection next = new OperationCollection(base.Apply());
268      IOperator op = ComparisonFactorModifierParameter.Value;
269      if (op != null)
270        next.Insert(0, ExecutionContext.CreateChildOperation(op));
271      return next;
272    }
273  }
274}
Note: See TracBrowser for help on using the repository browser.