Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
12/17/15 20:13:57 (8 years ago)
Author:
bburlacu
Message:

#1772: Schema diversification strategy: implement adaptive replacement ratio and added number of evaluated solutions per generation to the diversification statistics operator

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaCreator.cs

    r12988 r13480  
    3535  [StorableClass]
    3636  public class SchemaCreator : EvolutionTrackingOperator<ISymbolicExpressionTree> {
     37    #region parameter names
    3738    private const string MinimumSchemaLengthParameterName = "MinimumSchemaLength";
    3839    private const string MinimumSchemaFrequencyParameterName = "MinimumSchemaFrequency";
     
    4849    private const string NumberOfSchemasParameterName = "NumberOfSchemas";
    4950    private const string AverageSchemaLengthParameterName = "AverageSchemaLength";
     51    private const string UseAdaptiveReplacementRatioParameterName = "UseAdaptiveReplacementRatio";
     52    private const string ReplacementRatioUpdateRuleParameterName = "ReplacementRatioUpdateRule";
     53    #endregion
    5054
    5155    #region parameters
     56
     57    public IConstrainedValueParameter<StringValue> ReplacementRatioUpdateRuleParameter {
     58      get { return (IConstrainedValueParameter<StringValue>)Parameters[ReplacementRatioUpdateRuleParameterName]; }
     59    }
     60    public IFixedValueParameter<BoolValue> UseAdaptiveReplacementRatioParameter {
     61      get { return (IFixedValueParameter<BoolValue>)Parameters[UseAdaptiveReplacementRatioParameterName]; }
     62    }
    5263    public IFixedValueParameter<BoolValue> ExclusiveMatchingParameter {
    5364      get { return (IFixedValueParameter<BoolValue>)Parameters[ExclusiveMatchingParameterName]; }
     
    99110
    100111    public SchemaCreator() {
     112      #region add parameters
    101113      Parameters.Add(new FixedValueParameter<IntValue>(MinimumSchemaLengthParameterName, new IntValue(10)));
    102114      Parameters.Add(new FixedValueParameter<PercentValue>(MinimumSchemaFrequencyParameterName, new PercentValue(0.01)));
     
    112124      Parameters.Add(new ValueParameter<IntValue>(NumberOfSchemasParameterName, new IntValue(0)));
    113125      Parameters.Add(new ValueParameter<DoubleValue>(AverageSchemaLengthParameterName, new DoubleValue(0)));
    114 
     126      Parameters.Add(new FixedValueParameter<BoolValue>(UseAdaptiveReplacementRatioParameterName, new BoolValue(true)));
     127
     128      var replacementRatioUpdateRules = new ItemSet<StringValue>(new[] { new StringValue("f(x) = x"), new StringValue("f(x) = tanh(x)"), new StringValue("f(x) = tanh(2x)"), new StringValue("f(x) = tanh(3x)") });
     129      Parameters.Add(new ConstrainedValueParameter<StringValue>(ReplacementRatioUpdateRuleParameterName, replacementRatioUpdateRules));
     130      #endregion
    115131      NumberOfChangedTreesParameter.Hidden = true;
    116132      NumberOfSchemasParameter.Hidden = true;
     
    138154      var n = (int)Math.Round(ExecutionContext.Scope.SubScopes.Count * PercentageOfPopulation);
    139155      var scopes = new ScopeList(ExecutionContext.Scope.SubScopes.Take(n));
     156
     157      var updateEstimatedValues = new OperationCollection { Parallel = true };
     158      if (updateEstimatedValuesOperator == null)
     159        updateEstimatedValuesOperator = new UpdateEstimatedValuesOperator();
     160
     161      foreach (var s in scopes) {
     162        if (!s.Variables.ContainsKey("EstimatedValues"))
     163          s.Variables.Add(new Core.Variable("EstimatedValues"));
     164        updateEstimatedValues.Add(ExecutionContext.CreateChildOperation(updateEstimatedValuesOperator, s));
     165      }
     166
     167      Func<double, double> rule;
     168      var replacementRule = ReplacementRatioUpdateRuleParameter.Value.Value;
     169
     170      switch (replacementRule) {
     171        case "f(x) = x": {
     172            rule = x => x;
     173            break;
     174          }
     175        case "f(x) = tanh(x)": {
     176            rule = x => Math.Tanh(x);
     177            break;
     178          }
     179        case "f(x) = tanh(2x)": {
     180            rule = x => Math.Tanh(2 * x);
     181            break;
     182          }
     183        case "f(x) = tanh(3x)": {
     184            rule = x => Math.Tanh(3 * x);
     185            break;
     186          }
     187        default:
     188          throw new ArgumentException("Unknown replacement rule");
     189      }
     190
     191      var evaluateSchemas = new OperationCollection();
    140192
    141193      // for now, only consider crossover offspring
     
    146198                     select v;
    147199
     200      var schemas = new List<ISymbolicExpressionTree>(GenerateSchemas(vertices, MinimumSchemaLength));
     201
     202      #region create schemas and add subscopes representing the individuals
     203      foreach (var schema in schemas) {
     204        evaluateSchemas.Add(ExecutionContext.CreateChildOperation(new SchemaEvaluator { Schema = schema, ReplacementRule = rule }, ExecutionContext.Scope));
     205      }
     206      #endregion
     207
     208      if (diversificationStatisticsOperator == null)
     209        diversificationStatisticsOperator = new DiversificationStatisticsOperator();
     210
     211      var calculateStatistics = ExecutionContext.CreateChildOperation(diversificationStatisticsOperator);
     212
     213      // set parameters for statistics
     214      AverageSchemaLengthParameter.Value = new DoubleValue(schemas.Average(x => x.Length));
     215      NumberOfSchemasParameter.Value = new IntValue(schemas.Count);
     216      NumberOfChangedTreesParameter.Value = new IntValue(0);
     217
     218      // return an operation collection containing all the scope operations + base.Apply()
     219      return new OperationCollection { updateEstimatedValues, evaluateSchemas, calculateStatistics, base.Apply() };
     220    }
     221
     222    public static IEnumerable<ISymbolicExpressionTree> GenerateSchemas(IEnumerable<IGenealogyGraphNode<ISymbolicExpressionTree>> vertices, int minimumSchemaLength) {
     223      var anySubtreeSymbol = new AnySubtreeSymbol();
     224      //      var anyNodeSymbol = new AnyNodeSymbol();
    148225      var groups = vertices.GroupBy(x => x.Parents.First()).OrderByDescending(g => g.Count()).ToList();
    149       var anySubtreeSymbol = new AnySubtreeSymbol();
    150 
    151       var updateEstimatedValues = new OperationCollection { Parallel = true };
    152       if (updateEstimatedValuesOperator == null)
    153         updateEstimatedValuesOperator = new UpdateEstimatedValuesOperator();
    154 
    155       foreach (var s in scopes) {
    156         if (!s.Variables.ContainsKey("EstimatedValues"))
    157           s.Variables.Add(new Core.Variable("EstimatedValues"));
    158         updateEstimatedValues.Add(ExecutionContext.CreateChildOperation(updateEstimatedValuesOperator, s));
    159       }
    160 
    161       var evaluateSchemas = new OperationCollection();
    162       var schemas = new List<ISymbolicExpressionTree>();
    163       var wildCardCounts = new List<double>();
    164       #region create schemas and add subscopes representing the individuals
     226      var hash = new HashSet<string>();
     227      var formatter = new SymbolicExpressionTreeStringFormatter { Indent = false, AppendNewLines = false };
    165228      foreach (var g in groups) {
    166229        var parent = g.Key;
    167         if (parent.Data.Length < MinimumSchemaLength)
     230        if (parent.Data.Length < minimumSchemaLength)
    168231          continue;
    169232        bool replaced = false;
     
    171234        var nodes = schema.IterateNodesPrefix().ToList();
    172235        var arcs = g.Select(x => x.InArcs.Last()).Where(x => x.Data != null);
    173         var indices = arcs.Select(x => ((IFragment<ISymbolicExpressionTreeNode>)x.Data).Index1).Distinct().ToArray();
     236        var indices = (from arc in arcs
     237                       let fragment = (IFragment<ISymbolicExpressionTreeNode>)arc.Data
     238                       select fragment.Index1).Distinct().ToArray();
    174239        Array.Sort(indices);
    175240        var nodesToReplace = indices.Select(x => nodes[x]).ToList();
    176         int w = 0;
    177241        for (int i = nodesToReplace.Count - 1; i >= 0; --i) {
    178242          var node = nodesToReplace[i];
    179243
    180244          // do not replace the node with a wildcard if it would result in a length < MinimumSchemaLength
    181           if ((schema.Length - node.GetLength() + 1) < MinimumSchemaLength)
     245          if (schema.Length - node.GetLength() + 1 < minimumSchemaLength)
    182246            continue;
    183247
    184           var replacement = anySubtreeSymbol.CreateTreeNode();
    185           ReplaceSubtree(node, replacement, false);
     248          //          var replacement = anySubtreeSymbol.CreateTreeNode();
     249          //          ReplaceSubtree(node, replacement, false);
     250          var replacement = new AnyNodeSymbol(node.Symbol.MinimumArity, node.Symbol.MinimumArity).CreateTreeNode();
     251          ReplaceSubtree(node, replacement, true);
    186252          replaced = true;
    187           ++w;
    188253        }
    189254        if (replaced) {
    190           // store the schemas and the number of wildcards they contain in two lists
    191           schemas.Add(schema);
    192           wildCardCounts.Add(w);
     255          var str = formatter.Format(schema.Root.GetSubtree(0).GetSubtree(0));
     256          if (hash.Contains(str)) continue;
     257          yield return schema;
     258          hash.Add(str);
    193259        }
    194260      }
    195 
    196       for (int i = 0; i < schemas.Count; ++i) {
    197         var schema = schemas[i];
    198         evaluateSchemas.Add(ExecutionContext.CreateChildOperation(new SchemaEvaluator { Schema = schema }, ExecutionContext.Scope));
    199       }
    200       #endregion
    201 
    202       if (diversificationStatisticsOperator == null)
    203         diversificationStatisticsOperator = new DiversificationStatisticsOperator();
    204 
    205       var calculateStatistics = ExecutionContext.CreateChildOperation(diversificationStatisticsOperator);
    206 
    207       // set parameters for statistics
    208       AverageSchemaLengthParameter.Value = new DoubleValue(schemas.Average(x => x.Length));
    209       NumberOfSchemasParameter.Value = new IntValue(schemas.Count);
    210       NumberOfChangedTreesParameter.Value = new IntValue(0);
    211 
    212       // return an operation collection containing all the scope operations + base.Apply()
    213       return new OperationCollection { updateEstimatedValues, evaluateSchemas, calculateStatistics, base.Apply() };
    214     }
    215 
    216     private static void ReplaceSubtree(ISymbolicExpressionTreeNode original, ISymbolicExpressionTreeNode replacement,
    217       bool preserveChildren = true) {
     261    }
     262
     263    private static void ReplaceSubtree(ISymbolicExpressionTreeNode original, ISymbolicExpressionTreeNode replacement, bool preserveChildren = true) {
    218264      var parent = original.Parent;
    219265      if (parent == null)
Note: See TracChangeset for help on using the changeset viewer.