Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionTracking/HeuristicLab.EvolutionTracking/3.4/Analyzers/GenealogyAnalyzer.cs @ 10285

Last change on this file since 10285 was 10285, checked in by bburlacu, 10 years ago

#1772: Added SymbolicDataAnalysisGenealogyView, updated generic analyzer and operators.

File size: 9.5 KB
Line 
1using System.Collections.Generic;
2using System.Linq;
3using HeuristicLab.Common;
4using HeuristicLab.Core;
5using HeuristicLab.Data;
6using HeuristicLab.Operators;
7using HeuristicLab.Optimization;
8using HeuristicLab.Parameters;
9using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
10
11namespace HeuristicLab.EvolutionTracking {
12  [StorableClass]
13  [Item("GenealogyAnalyzer", "An analyzer which performs the necessary instrumentation to record the evolution of a genetic algorithm.")]
14  public class GenealogyAnalyzer<TGraph, TVertex, TContent> : SingleSuccessorOperator, IAnalyzer
15    where TGraph : class, IGenealogyGraph<TVertex, TContent>
16    where TVertex : class, IGenealogyGraphNode<TContent>, new()
17    where TContent : class, IItem {
18
19    private AfterCrossoverOperator<TGraph, TVertex, TContent> afterCrossoverOperator;
20    private AfterManipulatorOperator<TGraph, TVertex, TContent> afterManipulatorOperator;
21    private BeforeManipulatorOperator<TGraph, TVertex, TContent> beforeManipulatorOperator;
22    public string CrossoverParentsParameterName { get; set; }
23    public string CrossoverChildParameterName { get; set; }
24    public string ManipulatorChildParameterName { get; set; }
25
26    public IScopeTreeLookupParameter<DoubleValue> QualityParameter;
27    public IScopeTreeLookupParameter<TContent> PopulationParameter;
28
29    private const string PopulationParameterName = "Population";
30    private const string QualityParameterName = "Quality";
31
32    private const string GenerationsParameterName = "Generations";
33    private const string ResultsParameterName = "Results";
34    private const string PopulationGraphParameterName = "PopulationGraph";
35
36    private const string CrossoverParameterName = "Crossover";
37    private const string ManipulatorParameterName = "Mutator";
38    private const string SolutionCreatorParameterName = "SolutionCreator";
39
40    private const string EnableCrossoverTrackingParameterName = "EnableCrossoverTracking";
41    private const string EnableManipulatorTrackingParameterName = "EnableManipulatorTracking";
42    private const string EnableSolutionCreatorTrackingParameterName = "EnableSolutionCreatorTracking"; // should always be enabled. maybe superfluous
43
44    #region parameter properties
45    public ILookupParameter<ResultCollection> ResultsParameter {
46      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
47    }
48    public ILookupParameter<IntValue> GenerationsParameter {
49      get { return (ILookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
50    }
51    public IValueParameter<BoolValue> EnableCrossoverTrackingParameter {
52      get { return (IValueParameter<BoolValue>)Parameters[EnableCrossoverTrackingParameterName]; }
53    }
54    public IValueParameter<BoolValue> EnableManipulatorTrackingParameter {
55      get { return (IValueParameter<BoolValue>)Parameters[EnableManipulatorTrackingParameterName]; }
56    }
57    public IValueParameter<BoolValue> EnableSolutionCreatorTrackingParameter {
58      get { return (IValueParameter<BoolValue>)Parameters[EnableSolutionCreatorTrackingParameterName]; }
59    }
60    public ILookupParameter<ICrossover> CrossoverParameter {
61      get { return (ILookupParameter<ICrossover>)Parameters[CrossoverParameterName]; }
62    }
63    public ILookupParameter<IManipulator> ManipulatorParameter {
64      get { return (ILookupParameter<IManipulator>)Parameters[ManipulatorParameterName]; }
65    }
66    public ILookupParameter<ISolutionCreator> SolutionCreatorParameter {
67      get { return (ILookupParameter<ISolutionCreator>)Parameters[SolutionCreatorParameterName]; }
68    }
69    #endregion
70
71    #region properties
72    public ICrossover Crossover {
73      get { return CrossoverParameter.ActualValue; }
74    }
75    public IManipulator Manipulator {
76      get { return ManipulatorParameter.ActualValue; }
77    }
78    public ISolutionCreator SolutionCreator {
79      get { return SolutionCreatorParameter.ActualValue; }
80    }
81    public BoolValue EnableCrossoverTracking {
82      get { return EnableCrossoverTrackingParameter.Value; }
83    }
84    public BoolValue EnableManipulatorTracking {
85      get { return EnableManipulatorTrackingParameter.Value; }
86    }
87    public BoolValue EnableSolutionCreatorTracking {
88      get { return EnableSolutionCreatorTrackingParameter.Value; }
89    }
90    public ResultCollection Results {
91      get { return ResultsParameter.ActualValue; }
92    }
93    public IntValue Generations {
94      get { return GenerationsParameter.ActualValue; }
95    }
96    public IGenealogyGraph<TVertex, TContent> GenealogyGraph {
97      get {
98        IResult result;
99        if (!Results.ContainsKey(PopulationGraphParameterName)) {
100          result = new Result(PopulationGraphParameterName, new GenealogyGraph<TVertex, TContent>());
101          Results.Add(result);
102        } else {
103          result = Results[PopulationGraphParameterName];
104        }
105        var graph = (GenealogyGraph<TVertex, TContent>)result.Value;
106        return graph;
107      }
108    }
109    #endregion
110
111    public GenealogyAnalyzer() {
112      // the instrumented operators
113      Parameters.Add(new LookupParameter<ICrossover>(CrossoverParameterName, "The crossover operator."));
114      Parameters.Add(new LookupParameter<IManipulator>(ManipulatorParameterName, "The manipulator operator."));
115      Parameters.Add(new LookupParameter<ISolutionCreator>(SolutionCreatorParameterName, "The solution creator operator."));
116      // the analyzer parameters
117      Parameters.Add(new ValueParameter<BoolValue>(EnableCrossoverTrackingParameterName, new BoolValue(true)));
118      Parameters.Add(new ValueParameter<BoolValue>(EnableManipulatorTrackingParameterName, new BoolValue(true)));
119      Parameters.Add(new ValueParameter<BoolValue>(EnableSolutionCreatorTrackingParameterName, new BoolValue(true)));
120      // parameters required by the analyzer to do its work
121      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations so far."));
122      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName));
123      PopulationParameter = new ScopeTreeLookupParameter<TContent>(PopulationParameterName);
124      QualityParameter = new ScopeTreeLookupParameter<DoubleValue>(QualityParameterName);
125      Parameters.Add(PopulationParameter);
126      Parameters.Add(QualityParameter);
127    }
128    public override IDeepCloneable Clone(Cloner cloner) {
129      return new GenealogyAnalyzer<TGraph, TVertex, TContent>(this, cloner);
130    }
131    protected GenealogyAnalyzer(GenealogyAnalyzer<TGraph, TVertex, TContent> original, Cloner cloner)
132      : base(original, cloner) {
133    }
134
135    public bool EnabledByDefault {
136      get { return false; }
137    }
138
139    public override IOperation Apply() {
140      if (Generations.Value == 0) {
141        foreach (var individual in PopulationParameter.ActualValue) {
142          var vertex = new TVertex {
143            Content = individual,
144            Rank = Generations.Value
145          };
146          GenealogyGraph.AddVertex(vertex);
147        }
148        // at the beginning we add the before/after operators to the instrumented operators
149        if (EnableCrossoverTracking.Value) {
150          if (afterCrossoverOperator == null) {
151            afterCrossoverOperator = new AfterCrossoverOperator<TGraph, TVertex, TContent>();
152            afterCrossoverOperator.ParentsParameter.ActualName = CrossoverParentsParameterName;
153            afterCrossoverOperator.ChildParameter.ActualName = CrossoverChildParameterName;
154          }
155          var instrumentedCrossover = (InstrumentedOperator)Crossover;
156          instrumentedCrossover.AfterExecutionOperators.Add(afterCrossoverOperator);
157        }
158
159        if (EnableManipulatorTracking.Value && Manipulator != null) {
160          if (beforeManipulatorOperator == null) {
161            beforeManipulatorOperator = new BeforeManipulatorOperator<TGraph, TVertex, TContent>();
162            beforeManipulatorOperator.ChildParameter.ActualName = ManipulatorChildParameterName;
163          }
164          if (afterManipulatorOperator == null) {
165            afterManipulatorOperator = new AfterManipulatorOperator<TGraph, TVertex, TContent>();
166            afterManipulatorOperator.ChildParameter.ActualName = ManipulatorChildParameterName;
167          }
168          var instrumentedManipulator = (InstrumentedOperator)Manipulator;
169          instrumentedManipulator.BeforeExecutionOperators.Add(beforeManipulatorOperator);
170          instrumentedManipulator.AfterExecutionOperators.Add(afterManipulatorOperator);
171        }
172      } else {
173        // add missing elite individuals in the current generation
174        // TODO: optimize for speed
175        var currGen = new HashSet<TContent>(GenealogyGraph.Ranks[Generations.Value].Select(x => x.Content));
176        foreach (var individual in PopulationParameter.ActualValue) {
177          if (currGen.Contains(individual)) continue;
178          // it is an elite which was already added to the graph in the previous generation
179          var vertex = new TVertex {
180            Content = individual,
181            Rank = Generations.Value,
182            IsElite = true
183          };
184          GenealogyGraph.AddVertex(vertex);
185        }
186      }
187      // update qualities for the nodes in the graph
188      var population = PopulationParameter.ActualValue.ToList();
189      var qualities = QualityParameter.ActualValue.ToList();
190      for (int i = 0; i < population.Count; ++i) {
191        foreach (var v in GenealogyGraph[population[i]]) {
192          v.Quality = qualities[i].Value;
193        }
194      }
195
196      return base.Apply();
197    }
198  }
199}
Note: See TracBrowser for help on using the repository browser.