Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/29/14 02:17:14 (10 years ago)
Author:
bburlacu
Message:

#1772: Added storable attributes to all the tracking operators. Added an additional method in the genealogy analyzer which computes the relative reproductive success for each individual in the population as the ratio of its offspring which make it into the next generation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.EvolutionTracking/3.4/Analyzers/GenealogyAnalyzer.cs

    r11032 r11227  
    2121
    2222using System.Linq;
     23using HeuristicLab.Analysis;
    2324using HeuristicLab.Common;
    2425using HeuristicLab.Core;
     
    3435  public class GenealogyAnalyzer<T> : SingleSuccessorOperator, IAnalyzer
    3536  where T : class,IItem {
     37    #region parameter names
    3638    private const string GenerationsParameterName = "Generations";
    3739    private const string ResultsParameterName = "Results";
     
    5355    private const string EnableManipulatorTrackingParameterName = "EnableManipulatorTracking";
    5456    private const string EnableSolutionCreatorTrackingParameterName = "EnableSolutionCreatorTracking"; // should always be enabled. maybe superfluous
     57    #endregion
    5558
    5659    #region parameter properties
     
    140143
    141144    public GenealogyAnalyzer() {
     145      #region add parameters
    142146      // the instrumented operators
    143147      Parameters.Add(new LookupParameter<ICrossover>(CrossoverParameterName, "The crossover operator."));
     
    157161      Parameters.Add(new ValueParameter<IManipulatorOperator<T>>(BeforeManipulatorOperatorParameterName));
    158162      Parameters.Add(new ValueParameter<IManipulatorOperator<T>>(AfterManipulatorOperatorParameterName));
     163      #endregion
    159164    }
    160165    public override IDeepCloneable Clone(Cloner cloner) {
     
    164169      : base(original, cloner) {
    165170    }
     171
     172    [StorableConstructor]
     173    protected GenealogyAnalyzer(bool deserializing) : base(deserializing) { }
     174
    166175    [StorableHook(HookType.AfterDeserialization)]
    167176    private void AfterDeserialization() {
     
    232241
    233242    public override IOperation Apply() {
    234       var population = PopulationParameter.ActualValue.ToList();
     243      var population = PopulationParameter.ActualValue;
    235244      var qualities = QualityParameter.ActualValue.ToList();
    236245
    237       int currentGeneration = GenerationsParameter.ActualValue.Value;
    238       if (currentGeneration == 0) {
     246      int generation = GenerationsParameter.ActualValue.Value;
     247      if (generation == 0) {
    239248        ConfigureTrackingOperators();
    240249
    241         for (int i = 0; i < population.Count; ++i) {
     250        for (int i = 0; i < population.Length; ++i) {
    242251          var individual = population[i];
    243           var vertex = new GenealogyGraphNode<T>(individual) { Rank = currentGeneration };
     252          var vertex = new GenealogyGraphNode<T>(individual) { Rank = generation };
    244253          GenealogyGraph.AddVertex(vertex);
    245254          // save the vertex id in the individual scope (so that we can identify graph indices)
     
    249258        int index = 0;
    250259        T elite = null;
    251         for (int i = 0; i < population.Count; ++i) {
     260        for (int i = 0; i < population.Length; ++i) {
    252261          if (GenealogyGraph.Contains(population[i])) {
    253262            elite = population[i];
    254263            index = i;
    255           }
    256           break;
    257         }
    258 
     264            break;
     265          }
     266        }
     267
     268        #region add elite in the graph and connect it with the previous elite
    259269        if (elite != null) {
    260270          var prevVertex = (IGenealogyGraphNode<T>)GenealogyGraph.GetVertex(elite);
     
    264274
    265275          var vertex = new GenealogyGraphNode<T>(prevVertex.Content) {
    266             Rank = currentGeneration,
     276            Rank = generation,
    267277            Quality = prevVertex.Quality,
    268278            IsElite = false
     
    272282          // inject the graph node unique id to the scope
    273283          ExecutionContext.Scope.SubScopes[index].Variables["Id"].Value = new StringValue(vertex.Id);
    274 
    275284          GenealogyGraph.AddVertex(vertex);
    276 
    277285          GenealogyGraph.AddArc(prevVertex, vertex); // connect current elite with previous elite
    278286
     
    281289          }
    282290        }
     291        #endregion
     292
     293        ComputeSuccessRatios();
    283294      }
    284295      // update qualities
    285       for (int i = 0; i < population.Count; ++i) {
     296      for (int i = 0; i < population.Length; ++i) {
    286297        var vertex = (IGenealogyGraphNode)GenealogyGraph.GetVertex(population[i]);
    287298        vertex.Quality = qualities[i].Value;
     
    289300
    290301      // remove extra graph nodes (added by the instrumented operators in the case of offspring selection)
    291       var discardedOffspring = GenealogyGraph.Ranks[currentGeneration].Select(x => (T)x.Content).Except(population).ToList();
    292       foreach (var individual in discardedOffspring) {
    293         var vertex = GenealogyGraph.GetVertex(individual);
     302      var discardedOffspring = GenealogyGraph.Ranks[generation].Select(x => (T)x.Content).Except(population).ToList();
     303      foreach (var vertex in discardedOffspring.Select(individual => GenealogyGraph.GetVertex(individual))) {
    294304        GenealogyGraph.RemoveVertex(vertex);
    295305      }
    296306
    297307      return base.Apply();
     308    }
     309
     310    private void ComputeSuccessRatios() {
     311      var population = PopulationParameter.ActualValue;
     312      var generation = GenerationsParameter.ActualValue.Value;
     313      // compute the weight of each genealogy graph node as the ratio (produced offspring) / (surviving offspring)
     314      foreach (var ind in population) {
     315        var v = (IGenealogyGraphNode)GenealogyGraph.GetVertex(ind);
     316        foreach (var p in v.Parents)
     317          p.Weight++;
     318      }
     319      foreach (var v in GenealogyGraph.Ranks[generation - 1]) {
     320        if (v.OutDegree > 0)
     321          v.Weight /= v.OutDegree;
     322      }
     323
     324      var results = ResultsParameter.ActualValue;
     325      DataTable table;
     326      if (!results.ContainsKey("Successful offspring ratio")) {
     327        table = new DataTable("Successful offspring ratio");
     328        results.Add(new Result("Successful offspring ratio", table));
     329        table.Rows.Add(new DataRow("Successful offspring ratio") { VisualProperties = { ChartType = DataRowVisualProperties.DataRowChartType.Columns, StartIndexZero = true } });
     330      } else {
     331        table = (DataTable)results["Successful offspring ratio"].Value;
     332      }
     333      var row = table.Rows["Successful offspring ratio"];
     334      row.Values.Replace(GenealogyGraph.Ranks[generation - 1].OrderByDescending(x => x.Quality).Select(x => x.Weight));
    298335    }
    299336  }
Note: See TracChangeset for help on using the changeset viewer.