Index: branches/gp-crossover/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Analyzers/SymbolicExpressionTreeLengthAnalyzer.cs
===================================================================
--- branches/gp-crossover/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Analyzers/SymbolicExpressionTreeLengthAnalyzer.cs	(revision 6996)
+++ branches/gp-crossover/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Analyzers/SymbolicExpressionTreeLengthAnalyzer.cs	(revision 7344)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -30,4 +30,5 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
@@ -52,12 +53,8 @@
     }
     public ValueLookupParameter<DataTable> SymbolicExpressionTreeLengthsParameter {
-      get {
-        return (ValueLookupParameter<DataTable>)Parameters[SymbolicExpressionTreeLengthsParameterName];
-      }
+      get { return (ValueLookupParameter<DataTable>)Parameters[SymbolicExpressionTreeLengthsParameterName]; }
     }
     public ValueLookupParameter<DataTableHistory> SymbolicExpressionTreeLengthsHistoryParameter {
-      get {
-        return (ValueLookupParameter<DataTableHistory>)Parameters[SymbolicExpressionTreeLengthsHistoryParameterName];
-      }
+      get { return (ValueLookupParameter<DataTableHistory>)Parameters[SymbolicExpressionTreeLengthsHistoryParameterName]; }
     }
     public ValueLookupParameter<ResultCollection> ResultsParameter {
@@ -71,13 +68,28 @@
       get { return (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
     }
-    public LookupParameter<IntValue> UpdateCounterParameter {
-      get { return (LookupParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
+    public ValueParameter<IntValue> UpdateCounterParameter {
+      get { return (ValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
     }
     #endregion
+
+    #region Properties
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    public IntValue UpdateInterval {
+      get { return UpdateIntervalParameter.Value; }
+    }
+    public IntValue UpdateCounter {
+      get { return UpdateCounterParameter.Value; }
+    }
+    public BoolValue StoreHistory {
+      get { return StoreHistoryParameter.Value; }
+    }
+    #endregion
+
     [StorableConstructor]
     private SymbolicExpressionTreeLengthAnalyzer(bool deserializing) : base() { }
     private SymbolicExpressionTreeLengthAnalyzer(SymbolicExpressionTreeLengthAnalyzer original, Cloner cloner)
       : base(original, cloner) {
-      AfterDeserialization();
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -91,14 +103,12 @@
       Parameters.Add(new ValueLookupParameter<DataTableHistory>(SymbolicExpressionTreeLengthsHistoryParameterName, "The data table to store the symbolic expression tree lengths history."));
       Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
-
-      #region Add parameters for history
       Parameters.Add(new ValueParameter<BoolValue>(StoreHistoryParameterName, "True if the tree lengths history of the population should be stored.", new BoolValue(false)));
       Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
-      Parameters.Add(new LookupParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", "MinMaxAverageSymbolicExpressionTreeLengthAnalyzerUpdateCounter"));
-      #endregion
-
+      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
+
+      SymbolicExpressionTreeLengthsParameter.Hidden = true;
+      SymbolicExpressionTreeLengthsHistoryParameter.Hidden = true;
+      ResultsParameter.Hidden = true;
       UpdateCounterParameter.Hidden = true;
-
-      AfterDeserialization();
     }
 
@@ -112,21 +122,29 @@
         Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
       }
+      //necessary code to correct UpdateCounterParameter - type was changed from LookupParameter to ValueParameter
+      if (Parameters.ContainsKey(UpdateCounterParameterName) && (Parameters[UpdateCounterParameterName] is LookupParameter<IntValue>))
+        Parameters.Remove(UpdateCounterParameterName);
       if (!Parameters.ContainsKey(UpdateCounterParameterName)) {
-        Parameters.Add(new LookupParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", "MinMaxAverageSymbolicExpressionTreeLengthAnalyzerUpdateCounter"));
-      }
-    }
+        Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
+        UpdateCounterParameter.Hidden = true;
+      }
+    }
+
+    #region IStatefulItem members
+    public override void InitializeState() {
+      base.InitializeState();
+      UpdateCounter.Value = 0;
+    }
+    public override void ClearState() {
+      base.ClearState();
+      UpdateCounter.Value = 0;
+    }
+    #endregion
 
     public override IOperation Apply() {
-      int updateInterval = UpdateIntervalParameter.Value.Value;
-      IntValue updateCounter = UpdateCounterParameter.ActualValue;
-      // if the counter doesn't exist yet, we initialize it here with the current update interval
-      if (updateCounter == null) {
-        updateCounter = new IntValue(updateInterval);
-        UpdateCounterParameter.ActualValue = updateCounter;
-      } else updateCounter.Value++;
-
+      UpdateCounter.Value++;
       // the analyzer runs periodically, every 'updateInterval' times
-      if (updateCounter.Value == updateInterval) {
-        updateCounter.Value = 0; // reset counter
+      if (UpdateCounter.Value == UpdateInterval.Value) {
+        UpdateCounter.Value = 0; // reset counter
 
         // compute all tree lengths and store them in the lengthsTable
@@ -136,40 +154,51 @@
         // if the table was not created yet, we create it here
         if (treeLengthsTable == null) {
-          treeLengthsTable = new DataTable("Tree Length Values");
+          treeLengthsTable = new DataTable("Histogram");
           SymbolicExpressionTreeLengthsParameter.ActualValue = treeLengthsTable;
         }
 
         // data table which stores tree length values
-        DataRow dataRow;
-
-        var treeLengths = solutions.Select(s => (double)s.Length);
-
-        if (!treeLengthsTable.Rows.ContainsKey("Tree Lengths")) {
-          dataRow = new DataRow("Tree Lengths", "", treeLengths);
-          treeLengthsTable.Rows.Add(dataRow);
+        DataRow treeLengthsTableRow;
+
+        const string treeLengthsTableRowName = "Symbolic expression tree lengths";
+        const string treeLengthsTableRowDesc = "The distribution of symbolic expression tree lengths";
+        const string xAxisTitle = "Symbolic expression tree lengths";
+        const string yAxisTitle = "Frequency / Number of tree individuals";
+
+        var treeLengths = solutions.Select(s => (int)s.Length).ToList();
+
+        int maxLength = treeLengths.Max(t => t);
+        int minLength = treeLengths.Min(t => t);
+
+        if (!treeLengthsTable.Rows.ContainsKey(treeLengthsTableRowName)) {
+          treeLengthsTableRow = new DataRow(treeLengthsTableRowName, treeLengthsTableRowDesc, treeLengths.Select(x => (double)x));
+          treeLengthsTable.Rows.Add(treeLengthsTableRow);
         } else {
-          dataRow = treeLengthsTable.Rows["Tree Lengths"];
-          dataRow.Values.Replace(treeLengths);
+          treeLengthsTableRow = treeLengthsTable.Rows[treeLengthsTableRowName];
+          treeLengthsTableRow.Values.Replace(treeLengths.Select(x => (double)x));
         }
 
         double maximumAllowedTreeLength = ((LookupParameter<IntValue>)Parameters[MaximumSymbolicExpressionTreeLengthParameterName]).ActualValue.Value;
 
-        dataRow.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Histogram;
-        dataRow.VisualProperties.ExactBins = false;
-
-        // the following trick should result in an intervalWidth of 1,2,4,... (an int value)
-        dataRow.VisualProperties.Bins = solutions.Max(s => s.Length) - solutions.Min(s => s.Length);
-
-        int maxLength = solutions.Max(s => s.Length);
-        if (maxLength <= 25)      // [0,25]
-          dataRow.VisualProperties.ScaleFactor = 1.0;
-        else if (maxLength <= 100) // [26,100])
-          dataRow.VisualProperties.ScaleFactor = 1.0 / 2.0;
-        else if (maxLength <= 250) // [100,250]
-          dataRow.VisualProperties.ScaleFactor = 1.0 / 5.0;
+        treeLengthsTableRow.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Histogram;
+        treeLengthsTableRow.VisualProperties.ExactBins = false;
+
+        int range = maxLength - minLength;
+        if (range == 0) range = 1;
+        // the following trick should result in an integer intervalWidth of 1,2,4,...
+        treeLengthsTableRow.VisualProperties.Bins = range;
+
+        if (maxLength <= 25) // [0,25]
+          treeLengthsTableRow.VisualProperties.ScaleFactor = 1.0;
+        else if (maxLength <= 100) // [26,100]
+          treeLengthsTableRow.VisualProperties.ScaleFactor = 1.0 / 2.0;
+        else if (maxLength <= 250) // [101,250]
+          treeLengthsTableRow.VisualProperties.ScaleFactor = 1.0 / 5.0;
         else if (maxLength <= 500) // [251,500]
-          dataRow.VisualProperties.ScaleFactor = 1.0 / 10.0;
+          treeLengthsTableRow.VisualProperties.ScaleFactor = 1.0 / 10.0;
         else
-          dataRow.VisualProperties.ScaleFactor = 1.0 / 20.0;   // [501,inf]
+          treeLengthsTableRow.VisualProperties.ScaleFactor = 1.0 / 20.0; // [501,inf]
+
+        treeLengthsTableRow.VisualProperties.IsVisibleInLegend = false;
 
         // visual properties for the X-axis
@@ -178,46 +207,32 @@
         treeLengthsTable.VisualProperties.XAxisMinimumFixedValue = 0.0;
         if (maxLength > maximumAllowedTreeLength + 1)
-          treeLengthsTable.VisualProperties.XAxisMaximumFixedValue = solutions.Max(s => s.Length) + 1; // +1 so the histogram column for the maximum length won't get trimmed
+          treeLengthsTable.VisualProperties.XAxisMaximumFixedValue = maxLength + 1; // +1 so the histogram column for the maximum length won't get trimmed
         else
           treeLengthsTable.VisualProperties.XAxisMaximumFixedValue = maximumAllowedTreeLength + 1;
-        // visual properties for the Y-axis
+        treeLengthsTable.VisualProperties.XAxisTitle = xAxisTitle;
+        //visual properties for the Y-axis
         treeLengthsTable.VisualProperties.YAxisMinimumAuto = false;
         treeLengthsTable.VisualProperties.YAxisMaximumAuto = false;
         treeLengthsTable.VisualProperties.YAxisMinimumFixedValue = 0.0;
-        treeLengthsTable.VisualProperties.YAxisMaximumFixedValue = Math.Ceiling(solutions.Length / 2.0);
+        int maxFreq = (int)Math.Round(solutions.GroupBy(s => s.Length).Max(g => g.Count()) / treeLengthsTableRow.VisualProperties.ScaleFactor);
+        if (maxFreq % 5 != 0)
+          maxFreq += (5 - maxFreq % 5);
+        double yAxisMaximumFixedValue = maxFreq;
+
+        treeLengthsTable.VisualProperties.YAxisMaximumFixedValue = yAxisMaximumFixedValue;
+        treeLengthsTable.VisualProperties.YAxisTitle = yAxisTitle;
 
         var results = ResultsParameter.ActualValue;
 
-        if (!results.ContainsKey("Tree Lengths")) {
-          results.Add(new Result("Tree Lengths", treeLengthsTable));
+        if (!results.ContainsKey(treeLengthsTableRowName)) {
+          results.Add(new Result(treeLengthsTableRowName, treeLengthsTable));
         } else {
-          results["Tree Lengths"].Value = treeLengthsTable;
+          results[treeLengthsTableRowName].Value = treeLengthsTable;
         }
 
         bool storeHistory = StoreHistoryParameter.Value.Value;
+        const string treeLengthHistoryTableName = "Tree lengths history";
 
         if (storeHistory) {
-          // store tree lengths for each generation
-          var historyDataRow = new DataRow("Tree Lengths " + results["Generations"].Value, "", dataRow.Values);
-          historyDataRow.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Histogram;
-          historyDataRow.VisualProperties.ExactBins = false;
-          historyDataRow.VisualProperties.Bins = solutions.Max(s => s.Length) - solutions.Min(s => s.Length);
-          historyDataRow.VisualProperties.ScaleFactor = dataRow.VisualProperties.ScaleFactor;
-          var historyTable = new DataTable("Lengths Table " + results["Generations"]);
-          historyTable.Rows.Add(historyDataRow);
-          // visual properties for the X-axis
-          historyTable.VisualProperties.XAxisMinimumAuto = false;
-          historyTable.VisualProperties.XAxisMaximumAuto = false;
-          historyTable.VisualProperties.XAxisMinimumFixedValue = 0.0;
-          if (solutions.Max(s => s.Length) > maximumAllowedTreeLength + 1)
-            historyTable.VisualProperties.XAxisMaximumFixedValue = maxLength + 1; // +1 so the histogram column for the maximum length won't get trimmed
-          else
-            historyTable.VisualProperties.XAxisMaximumFixedValue = maximumAllowedTreeLength + 1;
-          // visual properties for the Y-axis
-          historyTable.VisualProperties.YAxisMinimumAuto = false;
-          historyTable.VisualProperties.YAxisMaximumAuto = false;
-          historyTable.VisualProperties.YAxisMinimumFixedValue = 0.0;
-          historyTable.VisualProperties.YAxisMaximumFixedValue = Math.Ceiling(solutions.Length / 2.0);
-
           var treeLengthsHistory = SymbolicExpressionTreeLengthsHistoryParameter.ActualValue;
           if (treeLengthsHistory == null) {
@@ -225,15 +240,13 @@
             SymbolicExpressionTreeLengthsHistoryParameter.ActualValue = treeLengthsHistory;
           }
-
-          treeLengthsHistory.Add(historyTable);
-
-          if (!results.ContainsKey("Tree Lengths History")) {
-            results.Add(new Result("Tree Lengths History", treeLengthsHistory));
+          treeLengthsHistory.Add((DataTable)treeLengthsTable.Clone());
+
+          if (!results.ContainsKey(treeLengthHistoryTableName)) {
+            results.Add(new Result(treeLengthHistoryTableName, treeLengthsHistory));
           } else {
-            results["Tree Lengths History"].Value = treeLengthsHistory;
+            results[treeLengthHistoryTableName].Value = treeLengthsHistory;
           }
         }
       }
-
       return base.Apply();
     }
