Changeset 15906
- Timestamp:
- 04/16/18 08:35:59 (7 years ago)
- Location:
- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/Analyzers/SymbolicDataAnalysisSchemaFrequencyAnalyzer.cs
r15351 r15906 43 43 private const string ExecuteInParallelParameterName = "ExecuteInParallel"; 44 44 private const string MaximumDegreeOfParallelismParameterName = "MaximumDegreeOfParallelism"; 45 private const string SchemaDefinitionParameterName = "SchemaDefinition"; 45 46 46 47 private static readonly Dictionary<string, string> ShortNames = new Dictionary<string, string> { 47 { "Addition", "+" },48 { "Subtraction", "-" },49 { "Multiplication", "*" },50 { "Division", "/" },51 { "Exponential", "exp" },52 { "Logarithm", "log" }53 };48 { "Addition", "+" }, 49 { "Subtraction", "-" }, 50 { "Multiplication", "*" }, 51 { "Division", "/" }, 52 { "Exponential", "exp" }, 53 { "Logarithm", "log" } 54 }; 54 55 55 56 [Storable] … … 63 64 private QueryMatch qm; 64 65 66 67 public IConstrainedValueParameter<StringValue> SchemaDefinitionParameter { 68 get { return (IConstrainedValueParameter<StringValue>)Parameters[SchemaDefinitionParameterName]; } 69 } 65 70 public IFixedValueParameter<BoolValue> ExecuteInParallelParameter { 66 71 get { return (IFixedValueParameter<BoolValue>)Parameters[ExecuteInParallelParameterName]; } … … 122 127 Parameters.Add(new LookupParameter<IRegressionProblemData>(ProblemDataParameterName)); 123 128 Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(InterpreterParameterName)); 129 130 var schemaDefinitions = new ItemSet<StringValue>(new[] { 131 new StringValue("="), 132 new StringValue("#"), 133 new StringValue("=,#") 134 }); 135 var schemaDefinitionParameter = new ConstrainedValueParameter<StringValue>(SchemaDefinitionParameterName, schemaDefinitions); 136 schemaDefinitionParameter.Value = schemaDefinitions.First(); 137 Parameters.Add(schemaDefinitionParameter); 124 138 } 125 139 … … 185 199 } 186 200 187 var schemas = SchemaCreator.GenerateCombinedSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching).ToList(); 201 List<ISymbolicExpressionTree> schemas; 202 var def = SchemaDefinitionParameter.Value.Value; 203 switch (def) { 204 case "=": 205 schemas = SchemaCreator.GenerateAnyNodeSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching).ToList(); 206 break; 207 case "#": 208 schemas = SchemaCreator.GenerateAnySubtreeSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching).ToList(); 209 break; 210 case "=,#": 211 schemas = SchemaCreator.GenerateCombinedSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching).ToList(); 212 break; 213 default: 214 return base.Apply(); 215 } 188 216 var schemaStrings = schemas.Select(x => x.Root.GetSubtree(0).GetSubtree(0).FormatToString(StrictSchemaMatching)).ToList(); 189 int[][] matchingIndices; 217 int[][] matchingIndices = new int[schemas.Count][]; 218 219 var tNodes = trees.Select(x => QueryMatch.InitializePostOrder(x.Root.GetSubtree(0).GetSubtree(0))).ToList(); 190 220 if (ExecuteInParallel) { 191 matchingIndices = new int[schemas.Count][];192 221 Parallel.For(0, schemas.Count, new ParallelOptions { MaxDegreeOfParallelism = MaximumDegreeOfParallelism }, i => { 193 222 var schema = schemas[i]; 194 matchingIndices[i] = Enumerable.Range(0, trees.Count).Where(v => qm.Match(trees[v], schema)).ToArray(); 223 var sNodes = QueryMatch.InitializePostOrder(schema.Root.GetSubtree(0).GetSubtree(0)); 224 matchingIndices[i] = Enumerable.Range(0, trees.Count).Where(idx => qm.Match(tNodes[idx], sNodes)).ToArray(); 195 225 }); 196 226 } else { 197 matchingIndices = schemas.Select(x => Enumerable.Range(0, trees.Count).Where(v => qm.Match(trees[v], x)).ToArray()).ToArray(); 227 for (int i = 0; i < schemas.Count; ++i) { 228 var schema = schemas[i]; 229 var sNodes = QueryMatch.InitializePostOrder(schema.Root.GetSubtree(0).GetSubtree(0)); 230 matchingIndices[i] = Enumerable.Range(0, trees.Count).Where(idx => qm.Match(tNodes[idx], sNodes)).ToArray(); 231 } 198 232 } 199 233 … … 203 237 if (ExecuteInParallel) { 204 238 var locker = new object(); 205 Parallel.For(0, schemas.Count, new ParallelOptions { MaxDegreeOfParallelism = MaximumDegreeOfParallelism }, i => { 239 Parallel.For(0, schemas.Count, new ParallelOptions { 240 MaxDegreeOfParallelism = MaximumDegreeOfParallelism 241 }, i => { 206 242 var indices = matchingIndices[i]; 207 243 if (indices.Length > 1) { -
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaCreator.cs
r15482 r15906 39 39 public class SchemaCreator : EvolutionTrackingOperator<ISymbolicExpressionTree> { 40 40 #region parameter names 41 // criteria to trigger schema-based diversification 41 42 private const string MinimumSchemaLengthParameterName = "MinimumSchemaLength"; 42 43 private const string MinimumSchemaFrequencyParameterName = "MinimumSchemaFrequency"; 43 44 private const string MinimumPhenotypicSimilarityParameterName = "MinimumPhenotypicSimilarity"; 44 private const string ReplacementRatioParameterName = "ReplacementRatio"; 45 private const string RandomReplacementParameterName = "RandomReplacement"; 45 // parameters controlling the diversification strategy 46 private const string UseAdaptiveMutationRateParameterName = "UseAdaptiveMutationRate"; // dynamically control mutation rate 47 private const string MutationRateUpdateRuleParameterName = "ReplacementRatioUpdateRule"; 48 private const string MutationRateParameterName = "MutationRate"; // fixed mutation rate when not using adaptive update 49 private const string ExclusiveMatchingParameterName = "ExclusiveMatching"; // an individual can belong to only 1 schema 50 private const string ParentsRatio = "ParentsRatio"; // use best % parents to generate schemas from 51 private const string StrictSchemaMatchingParameterName = "StrictSchemaMatching"; // use strict node comparison (for constant values and variable weights) 52 private const string SchemaDefinitionParameterName = "SchemaDefinition"; // which schema definition to use: {=}, {#} or {=,#} 53 private const string SchemaManipulatorParameterName = "SchemaManipulator"; // mutation operator to apply within schemas 54 55 // control parallel behaviour 46 56 private const string ExecuteInParallelParameterName = "ExecuteInParallel"; 47 57 private const string MaxDegreeOfParalellismParameterName = "MaxDegreeOfParallelism"; 48 private const string PercentageOfPopulationParameterName = "PercentageOfPopulationToDiversify";49 58 private const string ScaleEstimatedValuesParameterName = "ScaleEstimatedValues"; 50 private const string ExclusiveMatchingParameterName = "ExclusiveMatching"; 59 60 private const string UpdateCounterParameterName = "UpdateCounter"; 61 private const string UpdateIntervalParameterName = "UpdateInterval"; 62 63 #region information parameters 51 64 private const string NumberOfChangedTreesParameterName = "NumberOfChangedTrees"; 52 65 private const string NumberOfSchemasParameterName = "NumberOfSchemas"; 53 66 private const string AverageSchemaLengthParameterName = "AverageSchemaLength"; 54 private const string UseAdaptiveReplacementRatioParameterName = "UseAdaptiveReplacementRatio"; 55 private const string ReplacementRatioUpdateRuleParameterName = "ReplacementRatioUpdateRule"; 56 private const string StrictSchemaMatchingParameterName = "StrictSchemaMatching"; 57 private const string SchemaDefinitionParameterName = "SchemaDefinition"; 58 private const string SchemaManipulatorParameterName = "SchemaManipulator"; 67 #endregion 59 68 #endregion 60 69 … … 66 75 get { return (IConstrainedValueParameter<StringValue>)Parameters[SchemaDefinitionParameterName]; } 67 76 } 68 public IConstrainedValueParameter<StringValue> ReplacementRatioUpdateRuleParameter {69 get { return (IConstrainedValueParameter<StringValue>)Parameters[ ReplacementRatioUpdateRuleParameterName]; }70 } 71 public IFixedValueParameter<BoolValue> UseAdaptive ReplacementRatioParameter {72 get { return (IFixedValueParameter<BoolValue>)Parameters[UseAdaptive ReplacementRatioParameterName]; }77 public IConstrainedValueParameter<StringValue> MutationRateUpdateRuleParameter { 78 get { return (IConstrainedValueParameter<StringValue>)Parameters[MutationRateUpdateRuleParameterName]; } 79 } 80 public IFixedValueParameter<BoolValue> UseAdaptiveMutationRateParameter { 81 get { return (IFixedValueParameter<BoolValue>)Parameters[UseAdaptiveMutationRateParameterName]; } 73 82 } 74 83 public IFixedValueParameter<BoolValue> StrictSchemaMatchingParameter { … … 81 90 get { return (IFixedValueParameter<BoolValue>)Parameters[ScaleEstimatedValuesParameterName]; } 82 91 } 83 public IFixedValueParameter<PercentValue> P ercentageOfPopulationParameter {84 get { return (IFixedValueParameter<PercentValue>)Parameters[P ercentageOfPopulationParameterName]; }92 public IFixedValueParameter<PercentValue> ParentsRatioParameter { 93 get { return (IFixedValueParameter<PercentValue>)Parameters[ParentsRatio]; } 85 94 } 86 95 public IFixedValueParameter<IntValue> MinimumSchemaLengthParameter { … … 99 108 get { return (IFixedValueParameter<PercentValue>)Parameters[MinimumPhenotypicSimilarityParameterName]; } 100 109 } 101 public IFixedValueParameter<PercentValue> ReplacementRatioParameter {102 get { return (IFixedValueParameter<PercentValue>)Parameters[ ReplacementRatioParameterName]; }110 public IFixedValueParameter<PercentValue> MutationRateParameter { 111 get { return (IFixedValueParameter<PercentValue>)Parameters[MutationRateParameterName]; } 103 112 } 104 113 public IValueParameter<IntValue> NumberOfSchemasParameter { … … 110 119 public IValueParameter<IntValue> NumberOfChangedTreesParameter { 111 120 get { return (IValueParameter<IntValue>)Parameters[NumberOfChangedTreesParameterName]; } 121 } 122 public IFixedValueParameter<IntValue> UpdateCounterParameter { 123 get { return (IFixedValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; } 124 } 125 public IFixedValueParameter<IntValue> UpdateIntervalParameter { 126 get { return (IFixedValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; } 112 127 } 113 128 #endregion … … 117 132 public int MaxDegreeOfParallelism { get { return MaxDegreeOfParallelismParameter.Value.Value; } } 118 133 public bool ExecuteInParallel { get { return ExecuteInParallelParameter.Value.Value; } } 119 public double PercentageOfPopulation { get { return P ercentageOfPopulationParameter.Value.Value; } }134 public double PercentageOfPopulation { get { return ParentsRatioParameter.Value.Value; } } 120 135 public bool StrictSchemaMatching { get { return StrictSchemaMatchingParameter.Value.Value; } } 136 public IntValue UpdateCounter { get { return UpdateCounterParameter.Value; } } 137 public IntValue UpdateInterval { get { return UpdateIntervalParameter.Value; } } 138 121 139 #endregion 122 140 123 141 private UpdateQualityOperator updateQualityOperator; 124 142 private DiversificationStatisticsOperator diversificationStatisticsOperator; 143 144 public override void InitializeState() { 145 base.InitializeState(); 146 NumberOfChangedTreesParameter.Value.Value = 0; 147 NumberOfChangedTreesParameter.Value.Value = 0; 148 AverageSchemaLengthParameter.Value.Value = 0; 149 UpdateCounter.Value = 0; 150 } 125 151 126 152 public override void ClearState() { … … 128 154 NumberOfChangedTreesParameter.Value.Value = 0; 129 155 AverageSchemaLengthParameter.Value.Value = 0; 156 UpdateCounter.Value = 0; 130 157 base.ClearState(); 131 158 } … … 136 163 Parameters.Add(new FixedValueParameter<PercentValue>(MinimumSchemaFrequencyParameterName, new PercentValue(0.01))); 137 164 Parameters.Add(new FixedValueParameter<PercentValue>(MinimumPhenotypicSimilarityParameterName, new PercentValue(0.9))); 138 Parameters.Add(new FixedValueParameter<PercentValue>(ReplacementRatioParameterName, new PercentValue(0.9))); 139 Parameters.Add(new FixedValueParameter<PercentValue>(PercentageOfPopulationParameterName, new PercentValue(1))); 140 Parameters.Add(new FixedValueParameter<BoolValue>(RandomReplacementParameterName, new BoolValue(false))); 165 Parameters.Add(new FixedValueParameter<PercentValue>(MutationRateParameterName, new PercentValue(0.9))); 166 Parameters.Add(new FixedValueParameter<PercentValue>(ParentsRatio, new PercentValue(1))); 141 167 Parameters.Add(new FixedValueParameter<BoolValue>(ExecuteInParallelParameterName, new BoolValue(false))); 142 168 Parameters.Add(new FixedValueParameter<IntValue>(MaxDegreeOfParalellismParameterName, new IntValue(-1))); … … 147 173 Parameters.Add(new ValueParameter<IntValue>(NumberOfSchemasParameterName, new IntValue(0))); 148 174 Parameters.Add(new ValueParameter<DoubleValue>(AverageSchemaLengthParameterName, new DoubleValue(0))); 149 Parameters.Add(new FixedValueParameter<BoolValue>(UseAdaptiveReplacementRatioParameterName, new BoolValue(true))); 175 Parameters.Add(new FixedValueParameter<BoolValue>(UseAdaptiveMutationRateParameterName, new BoolValue(true))); 176 Parameters.Add(new FixedValueParameter<IntValue>(UpdateCounterParameterName, new IntValue(0))); 177 Parameters.Add(new FixedValueParameter<IntValue>(UpdateIntervalParameterName, new IntValue(1))); 150 178 151 179 // add update rules 152 var replacementRatioUpdateRules = new ItemSet<StringValue>(new[] {180 var mutationRateUpdateRules = new ItemSet<StringValue>(new[] { 153 181 new StringValue("f(x) = x"), 154 182 new StringValue("f(x) = tanh(x)"), … … 158 186 new StringValue("f(x) = 1-sqrt(1-x)") 159 187 }); 160 var replacementRatioUpdateRuleParameter = new ConstrainedValueParameter<StringValue>(ReplacementRatioUpdateRuleParameterName, replacementRatioUpdateRules);161 replacementRatioUpdateRuleParameter.Value = replacementRatioUpdateRules.First();162 Parameters.Add( replacementRatioUpdateRuleParameter);188 var mutationRateUpdateRuleParameter = new ConstrainedValueParameter<StringValue>(MutationRateUpdateRuleParameterName, mutationRateUpdateRules); 189 mutationRateUpdateRuleParameter.Value = mutationRateUpdateRules.First(); 190 Parameters.Add(mutationRateUpdateRuleParameter); 163 191 164 192 // add schema definitions … … 208 236 209 237 public override IOperation Apply() { 238 UpdateCounter.Value++; 239 if (UpdateCounter.Value != UpdateInterval.Value) 240 return base.Apply(); 241 UpdateCounter.Value = 0; 242 210 243 // apply only when at least one generation has passed 211 244 var gen = Generations.Value; … … 213 246 return base.Apply(); 214 247 215 var n = (int)Math.Round(ExecutionContext.Scope.SubScopes.Count * PercentageOfPopulation);216 248 217 249 var updateEstimatedValues = new OperationCollection { Parallel = true }; … … 219 251 updateQualityOperator = new UpdateQualityOperator(); 220 252 221 foreach (var s in ExecutionContext.Scope.SubScopes.Where(s => !s.Variables.ContainsKey("EstimatedValues"))) { 253 var scope = ExecutionContext.Scope; 254 255 foreach (var s in scope.SubScopes.Where(s => !s.Variables.ContainsKey("EstimatedValues"))) { 222 256 updateEstimatedValues.Add(ExecutionContext.CreateChildOperation(updateQualityOperator, s)); 223 257 } 224 258 225 var replacementRule = ReplacementRatioUpdateRuleParameter.Value.Value;259 var updateRule = MutationRateUpdateRuleParameter.Value.Value; 226 260 var schemaManipulator = SchemaManipulatorParameter.Value; 227 261 228 262 var evaluateSchemas = new OperationCollection(); 229 263 264 Func<IScope, double> getQuality = s => ((DoubleValue)s.Variables["Quality"].Value).Value; 265 266 var bestN = (int)Math.Round(scope.SubScopes.Count * PercentageOfPopulation); 267 var scopes = new ScopeList(scope.SubScopes.OrderByDescending(getQuality).Take(bestN)); 230 268 // for now, only consider crossover offspring 231 var scopes = new ScopeList(ExecutionContext.Scope.SubScopes.OrderByDescending(x => ((DoubleValue)x.Variables["Quality"].Value).Value).Take(n));232 269 var vertices = from s in scopes 233 270 let t = (ISymbolicExpressionTree)s.Variables["SymbolicExpressionTree"].Value … … 236 273 select v; 237 274 238 List<ISymbolicExpressionTree> schemas;275 IEnumerable<ISymbolicExpressionTree> schemas; 239 276 switch (SchemaDefinitionParameter.Value.Value) { 240 277 case "=": 241 schemas = GenerateAnyNodeSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching) .ToList();278 schemas = GenerateAnyNodeSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching); 242 279 break; 243 280 case "#": 244 schemas = GenerateAnySubtreeSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching) .ToList();281 schemas = GenerateAnySubtreeSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching); 245 282 break; 246 283 case "=,#": 247 schemas = GenerateCombinedSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching) .ToList();284 schemas = GenerateCombinedSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching); 248 285 break; 249 286 default: … … 255 292 256 293 #region create schemas and add subscopes representing the individuals 294 double avgLength = 0; 295 int count = 0; 257 296 foreach (var schema in schemas) { 258 evaluateSchemas.Add(ExecutionContext.CreateChildOperation(new SchemaEvaluator { Schema = schema, ReplacementRule = replacementRule, SchemaManipulator = schemaManipulator }, ExecutionContext.Scope)); 297 avgLength += schema.Length; 298 ++count; 299 evaluateSchemas.Add(ExecutionContext.CreateChildOperation(new SchemaEvaluator { Schema = schema, MutationRateUpdateRule = updateRule, SchemaManipulator = schemaManipulator }, scope)); 259 300 } 301 avgLength /= count; 260 302 #endregion 303 304 // set parameters for statistics 305 AverageSchemaLengthParameter.Value = new DoubleValue(avgLength); 306 NumberOfSchemasParameter.Value = new IntValue(count); 307 NumberOfChangedTreesParameter.Value = new IntValue(0); 261 308 262 309 if (diversificationStatisticsOperator == null) … … 264 311 265 312 var calculateStatistics = ExecutionContext.CreateChildOperation(diversificationStatisticsOperator); 266 267 // set parameters for statistics268 AverageSchemaLengthParameter.Value = new DoubleValue(schemas.Average(x => x.Length));269 NumberOfSchemasParameter.Value = new IntValue(schemas.Count);270 NumberOfChangedTreesParameter.Value = new IntValue(0);271 313 272 314 // return an operation collection containing all the scope operations + base.Apply() -
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaEvaluator.cs
r15482 r15906 21 21 22 22 using System; 23 using System.Collections.Concurrent; 23 24 using System.Collections.Generic; 24 25 using System.Linq; … … 41 42 private const string MinimumSchemaFrequencyParameterName = "MinimumSchemaFrequency"; 42 43 private const string MinimumPhenotypicSimilarityParameterName = "MinimumPhenotypicSimilarity"; 43 private const string ReplacementRatioParameterName = "ReplacementRatio";44 private const string MutationRateParameterName = "MutationRate"; 44 45 private const string SchemaParameterName = "Schema"; 45 46 private const string PopulationSizeParameterName = "PopulationSize"; … … 52 53 private const string MutatorParameterName = "Mutator"; 53 54 private const string CrossoverParameterName = "Crossover"; 54 private const string RandomReplacementParameterName = "RandomReplacement";55 55 private const string NumberOfChangedTreesParameterName = "NumberOfChangedTrees"; 56 56 private const string ExecuteInParallelParameterName = "ExecuteInParallel"; 57 57 private const string MaxDegreeOfParalellismParameterName = "MaxDegreeOfParallelism"; 58 58 private const string ExclusiveMatchingParameterName = "ExclusiveMatching"; 59 private const string UseAdaptive ReplacementRatioParameterName = "UseAdaptiveReplacementRatio";59 private const string UseAdaptiveMutationRateParameterName = "UseAdaptiveMutationRate"; 60 60 private const string StrictSchemaMatchingParameterName = "StrictSchemaMatching"; 61 61 #endregion 62 62 63 63 #region parameters 64 public ILookupParameter<BoolValue> UseAdaptive ReplacementRatioParameter {65 get { return (ILookupParameter<BoolValue>)Parameters[UseAdaptive ReplacementRatioParameterName]; }64 public ILookupParameter<BoolValue> UseAdaptiveMutationRateParameter { 65 get { return (ILookupParameter<BoolValue>)Parameters[UseAdaptiveMutationRateParameterName]; } 66 66 } 67 67 public ILookupParameter<BoolValue> ExclusiveMatchingParameter { … … 89 89 get { return (ILookupParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; } 90 90 } 91 public ILookupParameter<BoolValue> RandomReplacementParameter {92 get { return (ILookupParameter<BoolValue>)Parameters[RandomReplacementParameterName]; }93 }94 91 public ILookupParameter<ISymbolicExpressionTreeCrossover> CrossoverParameter { 95 92 get { return (ILookupParameter<ISymbolicExpressionTreeCrossover>)Parameters[CrossoverParameterName]; } … … 107 104 get { return (ILookupParameter<PercentValue>)Parameters[MinimumSchemaFrequencyParameterName]; } 108 105 } 109 public ILookupParameter<PercentValue> ReplacementRatioParameter {110 get { return (ILookupParameter<PercentValue>)Parameters[ ReplacementRatioParameterName]; }106 public ILookupParameter<PercentValue> MutationRateParameter { 107 get { return (ILookupParameter<PercentValue>)Parameters[MutationRateParameterName]; } 111 108 } 112 109 public ILookupParameter<PercentValue> MinimumPhenotypicSimilarityParameter { … … 123 120 #region parameter properties 124 121 public PercentValue MinimumSchemaFrequency { get { return MinimumSchemaFrequencyParameter.ActualValue; } } 125 public PercentValue ReplacementRatio { get { return ReplacementRatioParameter.ActualValue; } }122 public PercentValue MutationRate { get { return MutationRateParameter.ActualValue; } } 126 123 public PercentValue MinimumPhenotypicSimilarity { get { return MinimumPhenotypicSimilarityParameter.ActualValue; } } 127 public BoolValue RandomReplacement { get { return RandomReplacementParameter.ActualValue; } }128 124 public IntValue NumberOfChangedTrees { get { return NumberOfChangedTreesParameter.ActualValue; } } 129 125 #endregion … … 135 131 136 132 [Storable] 137 public string ReplacementRule { get; set; }133 public string MutationRateUpdateRule { get; set; } 138 134 139 135 [Storable] … … 171 167 Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SchemaParameterName, "The current schema to be evaluated")); 172 168 Parameters.Add(new LookupParameter<PercentValue>(MinimumSchemaFrequencyParameterName)); 173 Parameters.Add(new LookupParameter<PercentValue>( ReplacementRatioParameterName));169 Parameters.Add(new LookupParameter<PercentValue>(MutationRateParameterName)); 174 170 Parameters.Add(new LookupParameter<PercentValue>(MinimumPhenotypicSimilarityParameterName)); 175 171 Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(PopulationSizeParameterName)); … … 183 179 Parameters.Add(new LookupParameter<ISymbolicExpressionTreeManipulator>(MutatorParameterName)); 184 180 Parameters.Add(new LookupParameter<ISymbolicExpressionTreeCrossover>(CrossoverParameterName)); 185 Parameters.Add(new LookupParameter<BoolValue>(RandomReplacementParameterName));186 181 Parameters.Add(new LookupParameter<IntValue>(NumberOfChangedTreesParameterName)); 187 182 Parameters.Add(new LookupParameter<BoolValue>(ExecuteInParallelParameterName)); 188 183 Parameters.Add(new LookupParameter<IntValue>(MaxDegreeOfParalellismParameterName)); 189 184 Parameters.Add(new LookupParameter<BoolValue>(ExclusiveMatchingParameterName)); 190 Parameters.Add(new LookupParameter<BoolValue>(UseAdaptive ReplacementRatioParameterName));185 Parameters.Add(new LookupParameter<BoolValue>(UseAdaptiveMutationRateParameterName)); 191 186 #endregion 192 187 } … … 218 213 219 214 var individuals = ExecutionContext.Scope.SubScopes; // the scopes represent the individuals 220 var trees = individuals.Select(x => (ISymbolicExpressionTree)x.Variables["SymbolicExpressionTree"].Value).ToList(); 215 var trees = new ISymbolicExpressionTree[individuals.Count]; 216 var qualities = new double[individuals.Count]; 217 218 for (int i = 0; i < individuals.Count; ++i) { 219 trees[i] = (ISymbolicExpressionTree)individuals[i].Variables["SymbolicExpressionTree"].Value; 220 qualities[i] = ((DoubleValue)individuals[i].Variables["Quality"].Value).Value; 221 } 221 222 222 223 var random = RandomParameter.ActualValue; 223 224 var s = Schema; 225 var sRoot = s.Root.GetSubtree(0).GetSubtree(0); 226 int countThreshold = (int)Math.Max(2, Math.Round(MinimumSchemaFrequency.Value * individuals.Count)); 224 var sRoot = Schema.Root.GetSubtree(0).GetSubtree(0); 227 225 228 226 // first apply the length and root equality checks in order to filter the individuals 229 227 var exclusiveMatching = ExclusiveMatchingParameter.ActualValue.Value; 230 228 var filtered = new List<int>(); 231 for (int i = 0; i < individuals.Count; ++i) { 229 230 for (int i = 0; i < trees.Length; ++i) { 232 231 if (exclusiveMatching && individuals[i].Variables.ContainsKey("AlreadyMatched")) continue; 233 232 var t = trees[i]; 234 233 var tRoot = t.Root.GetSubtree(0).GetSubtree(0); 235 if (t.Length < s.Length || !qm.EqualityComparer.Equals(tRoot, sRoot)) continue;234 if (t.Length < Schema.Length || !qm.EqualityComparer.Equals(tRoot, sRoot)) continue; 236 235 filtered.Add(i); 237 236 } … … 239 238 // if we don't have enough filtered individuals, then we are done 240 239 // if the schema exceeds the minimum frequency, it gets processed further 240 int countThreshold = (int)Math.Max(2, Math.Round(MinimumSchemaFrequency.Value * individuals.Count)); 241 241 if (filtered.Count < countThreshold) { 242 242 return base.Apply(); … … 244 244 245 245 // check if the filtered individuals match the schema 246 var matching = new List<int>(); 246 247 var sNodes = QueryMatch.InitializePostOrder(sRoot); 247 var matchingIndividuals = new ScopeList(); 248 248 249 bool executeInParallel = ExecuteInParallelParameter.ActualValue.Value; 249 250 int maxDegreeOfParallelism = MaxDegreeOfParallelismParameter.ActualValue.Value; 250 251 251 252 if (executeInParallel) { 252 var matching = new bool[filtered.Count]; 253 254 Parallel.For(0, filtered.Count, new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism }, 255 i => { 256 var index = filtered[i]; 257 var t = trees[index]; 258 var tNodes = QueryMatch.InitializePostOrder(t.Root.GetSubtree(0).GetSubtree(0)); 259 if (qm.Match(tNodes, sNodes)) { 260 matching[i] = true; 261 } 262 }); 263 264 matchingIndividuals.AddRange(filtered.Where((x, i) => matching[i]).Select(x => individuals[x])); 253 var partitioner = Partitioner.Create(0, filtered.Count); 254 var po = new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism }; 255 256 Parallel.ForEach(partitioner, po, (range, loop) => { 257 var partial = new List<int>(); 258 for (int i = range.Item1; i < range.Item2; ++i) { 259 var idx = filtered[i]; 260 var tRoot = trees[idx].Root.GetSubtree(0).GetSubtree(0); 261 var tNodes = QueryMatch.InitializePostOrder(tRoot); 262 263 if (qm.Match(tNodes, sNodes)) { partial.Add(idx); } 264 } 265 lock (matching) { matching.AddRange(partial); } 266 }); 265 267 } else { 266 268 for (int i = 0; i < filtered.Count; ++i) { 267 // break early if it becomes impossible to reach the minimum threshold268 if (matchingIndividuals.Count + filtered.Count - i < countThreshold)269 break;270 271 269 var index = filtered[i]; 272 270 var tRoot = trees[index].Root.GetSubtree(0).GetSubtree(0); 273 271 var tNodes = QueryMatch.InitializePostOrder(tRoot); 274 if (qm.Match(tNodes, sNodes)) 275 matchingIndividuals.Add(individuals[index]); 272 if (qm.Match(tNodes, sNodes)) { 273 matching.Add(index); 274 } 276 275 } 277 276 } 278 279 if (matchingIndividuals.Count < countThreshold) { 277 if (matching.Count < countThreshold) { 280 278 return base.Apply(); 281 279 } 282 280 281 matching.Sort((a, b) => qualities[a].CompareTo(qualities[b])); // sort by ascending quality 282 var matchingIndividuals = matching.Select(x => individuals[x]).ToArray(); // fittest individual will be last in the array 283 283 var similarity = CalculateSimilarity(matchingIndividuals, calculator, executeInParallel, maxDegreeOfParallelism); 284 284 if (similarity < MinimumPhenotypicSimilarity.Value) { … … 286 286 } 287 287 288 double replacementRatio;289 var adaptiveReplacementRatio = UseAdaptiveReplacementRatioParameter.ActualValue.Value;290 291 if ( adaptiveReplacementRatio) {292 var r = (double)matchingIndividuals. Count/ individuals.Count;293 replacementRatio = CalculateReplacementRatio(r);288 double mutationRate; 289 var useAdaptiveMutationRate = UseAdaptiveMutationRateParameter.ActualValue.Value; 290 291 if (useAdaptiveMutationRate) { 292 var r = (double)matchingIndividuals.Length / individuals.Count; 293 mutationRate = CalculateMutationRate(r); 294 294 } else { 295 replacementRatio = ReplacementRatio.Value; 296 } 297 298 int n = (int)Math.Floor(matchingIndividuals.Count * replacementRatio); 299 var individualsToReplace = RandomReplacement.Value ? matchingIndividuals.SampleRandomWithoutRepetition(random, n).ToList() 300 : matchingIndividuals.OrderBy(x => (DoubleValue)x.Variables["Quality"].Value).Take(n).ToList(); 301 var mutationOc = new OperationCollection { Parallel = false }; // cannot be parallel due to the before/after operators which insert vertices in the genealogy graph 302 var updateEstimatedValues = new OperationCollection { Parallel = true }; // evaluation should be done in parallel when possible 303 foreach (var ind in individualsToReplace) { 304 var mutatorOp = ExecutionContext.CreateChildOperation(SchemaManipulator, ind); 305 var updateOp = ExecutionContext.CreateChildOperation(updateQualityOperator, ind); 306 mutationOc.Add(mutatorOp); 307 updateEstimatedValues.Add(updateOp); 295 mutationRate = MutationRate.Value; 296 } 297 298 var mutations = new OperationCollection { Parallel = false }; // cannot be parallel due to the before/after operators which insert vertices in the genealogy graph 299 var updates = new OperationCollection { Parallel = true }; // evaluation should be done in parallel when possible 300 301 // use length - 1 because we don't want to mutate the best individual in each schema group (which could also be the overall elite) 302 for (int i = 0; i < matchingIndividuals.Length - 1; ++i) { 303 if (random.NextDouble() > mutationRate) continue; 304 305 var ind = matchingIndividuals[i]; 306 307 var mutate = ExecutionContext.CreateChildOperation(SchemaManipulator, ind); 308 var update = ExecutionContext.CreateChildOperation(updateQualityOperator, ind); 309 310 mutations.Add(mutate); 311 updates.Add(update); 312 308 313 if (exclusiveMatching) 309 314 ind.Variables.Add(new Core.Variable("AlreadyMatched")); 310 315 } 311 312 NumberOfChangedTrees.Value += individualsToReplace.Count; // a lock is not necessary here because the SchemaEvaluators cannot be executed in parallel 313 314 return new OperationCollection(mutationOc, updateEstimatedValues, base.Apply()); 315 } 316 317 private double CalculateReplacementRatio(double r) { 318 switch (ReplacementRule) { 316 NumberOfChangedTrees.Value += mutations.Count; 317 318 return new OperationCollection(mutations, updates, base.Apply()); 319 } 320 321 private double CalculateMutationRate(double r) { 322 switch (MutationRateUpdateRule) { 319 323 case "f(x) = x": { 320 324 return r; … … 340 344 } 341 345 342 public static double CalculateSimilarity(ScopeList individuals, ISolutionSimilarityCalculator calculator, bool parallel = false, int nThreads = -1) { 346 public static double CalculateSimilarity(IScope[] individuals, ISolutionSimilarityCalculator calculator, bool parallel = false, int nThreads = -1) { 347 if (individuals.Length < 2) 348 return double.NaN; 349 343 350 double similarity = 0; 344 int count = individuals.Count; 345 if (count < 2) return double.NaN; 351 int count = individuals.Length; 352 int n = count * (count - 1) / 2; 353 346 354 if (parallel) { 347 var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = nThreads };348 var simArray = new double[count - 1];349 Parallel.For(0, count - 1, parallelOptions, i => {350 double innerSim = 0;355 var ii = new int[n]; 356 var jj = new int[n]; 357 int k = 0; 358 for (int i = 0; i < count - 1; ++i) 351 359 for (int j = i + 1; j < count; ++j) { 352 innerSim += calculator.CalculateSolutionSimilarity(individuals[i], individuals[j]); 353 } 354 simArray[i] = innerSim; 360 ii[k] = i; 361 jj[k] = j; 362 ++k; 363 } 364 var po = new ParallelOptions { MaxDegreeOfParallelism = nThreads }; 365 var partitioner = Partitioner.Create(0, n); 366 var locker = new object(); 367 Parallel.ForEach(partitioner, new ParallelOptions { MaxDegreeOfParallelism = 4 }, (range, loop) => { 368 var partial = 0d; 369 for (int idx = range.Item1; idx < range.Item2; ++idx) { 370 int i = ii[idx]; 371 int j = jj[idx]; 372 partial += calculator.CalculateSolutionSimilarity(individuals[i], individuals[j]); 373 } 374 lock (locker) { similarity += partial; } 355 375 }); 356 similarity = simArray.Sum();357 376 } else { 358 377 for (int i = 0; i < count - 1; ++i) { … … 362 381 } 363 382 } 364 return similarity / (count * (count - 1) / 2.0);383 return similarity / n; 365 384 } 366 385 } -
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/UpdateQualityOperator.cs
r13876 r15906 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. … … 21 21 22 22 using System; 23 using System.Collections; 24 using System.Collections.Generic; 23 25 using System.Linq; 24 26 using HeuristicLab.Common; … … 40 42 private const string ScaleEstimatedValuesParameterName = "ScaleEstimatedValues"; 41 43 44 #region parameters 42 45 public ILookupParameter<IRegressionProblemData> ProblemDataParameter { 43 46 get { return (ILookupParameter<IRegressionProblemData>)Parameters[ProblemDataParameterName]; } … … 55 58 get { return (ILookupParameter<BoolValue>)Parameters[ScaleEstimatedValuesParameterName]; } 56 59 } 60 #endregion 57 61 58 62 public UpdateQualityOperator() { … … 76 80 public override IOperation Apply() { 77 81 var tree = SymbolicExpressionTreeParameter.ActualValue; 78 FixParentLinks(tree);79 82 var problemData = ProblemDataParameter.ActualValue; 80 83 var estimationLimits = EstimationLimitsParameter.ActualValue; 81 84 var interpreter = InterpreterParameter.ActualValue; 82 85 83 var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, problemData.TrainingIndices) .ToArray();84 var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices) .ToArray();86 var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, problemData.TrainingIndices); 87 var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices); 85 88 86 if (estimatedValues.Length != targetValues.Length) 87 throw new ArgumentException("Number of elements in target and estimated values enumeration do not match."); 89 var scaleEstimatedValues = ScaleEstimatedValuesParameter.ActualValue.Value; 88 90 89 var linearScalingCalculator = new OnlineLinearScalingParameterCalculator(); 91 IEnumerable<double> scaled; 92 if (scaleEstimatedValues) { 93 var linearScalingCalculator = new OnlineLinearScalingParameterCalculator(); 90 94 91 for (int i = 0; i < estimatedValues.Length; ++i) { 92 var estimated = estimatedValues[i]; 93 var target = targetValues[i]; 94 if (!double.IsNaN(estimated) && !double.IsInfinity(estimated)) 95 linearScalingCalculator.Add(estimated, target); 95 var e1 = estimatedValues.GetEnumerator(); 96 var e2 = targetValues.GetEnumerator(); 97 98 int count = 0; 99 while (e1.MoveNext() && e2.MoveNext()) { 100 var estimated = e1.Current; 101 var target = e2.Current; 102 if (!double.IsNaN(estimated) && !double.IsInfinity(estimated)) 103 linearScalingCalculator.Add(estimated, target); 104 ++count; 105 } 106 if (e1.MoveNext() || e2.MoveNext()) 107 throw new ArgumentException("Number of elements in target and estimated values enumeration do not match."); 108 109 double alpha = linearScalingCalculator.Alpha; 110 double beta = linearScalingCalculator.Beta; 111 if (linearScalingCalculator.ErrorState != OnlineCalculatorError.None) { 112 alpha = 0.0; 113 beta = 1.0; 114 } 115 scaled = estimatedValues.Select(x => x * beta + alpha).LimitToRange(estimationLimits.Lower, estimationLimits.Upper); 116 } else { 117 scaled = estimatedValues.LimitToRange(estimationLimits.Lower, estimationLimits.Upper); 96 118 } 97 double alpha = linearScalingCalculator.Alpha; 98 double beta = linearScalingCalculator.Beta; 99 if (linearScalingCalculator.ErrorState != OnlineCalculatorError.None) { 100 alpha = 0.0; 101 beta = 1.0; 102 } 103 var scaled = estimatedValues.Select(x => x * beta + alpha).LimitToRange(estimationLimits.Lower, estimationLimits.Upper).ToArray(); 119 104 120 OnlineCalculatorError error; 105 121 var r = OnlinePearsonsRCalculator.Calculate(targetValues, scaled, out error); … … 111 127 112 128 ((DoubleValue)variables["Quality"].Value).Value = r2; 113 GenealogyGraph.GetByContent(tree).Quality = r2; 114 115 var scaleEstimatedValues = ScaleEstimatedValuesParameter.ActualValue; 116 if (!scaleEstimatedValues.Value) 117 scaled = estimatedValues.LimitToRange(estimationLimits.Lower, estimationLimits.Upper).ToArray(); 129 //GenealogyGraph.GetByContent(tree).Quality = r2; 118 130 119 131 if (variables.ContainsKey("EstimatedValues")) { 120 variables["EstimatedValues"].Value = new DoubleArray(scaled );132 variables["EstimatedValues"].Value = new DoubleArray(scaled.ToArray()); 121 133 } else { 122 variables.Add(new Core.Variable("EstimatedValues", new DoubleArray(scaled )));134 variables.Add(new Core.Variable("EstimatedValues", new DoubleArray(scaled.ToArray()))); 123 135 } 124 136 return base.Apply(); 125 137 } 126 127 private static void FixParentLinks(ISymbolicExpressionTree tree) {128 foreach (var node in tree.IterateNodesPrefix().Where(x => x.SubtreeCount > 0)) {129 foreach (var s in node.Subtrees) {130 if (s.Parent != node)131 s.Parent = node;132 }133 }134 }135 138 } 136 139 }
Note: See TracChangeset
for help on using the changeset viewer.