Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionConstraintAnalyzer.cs @ 17733

Last change on this file since 17733 was 17733, checked in by dpiringe, 4 years ago

#3076

  • modified SymbolicRegressionConstraintAnalyzer to calculate an error (as out parameter)
    • added an ILookupParameter to write a penality multiplier into the scope
  • changed a lot of evaluators to match the changed analyzer method
  • changed SymbolicRegressionSingleObjectiveConstraintConstOptNmseEvaluator to use a rising penality (instead of setting an unsatisfied solution to 1.0)
File size: 8.2 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Collections.ObjectModel;
4using System.Linq;
5using System.Threading;
6using HEAL.Attic;
7using HeuristicLab.Analysis;
8using HeuristicLab.Common;
9using HeuristicLab.Core;
10using HeuristicLab.Data;
11using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
12using HeuristicLab.Optimization;
13using HeuristicLab.Optimization.Operators;
14using HeuristicLab.Parameters;
15
16namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
17  [StorableType("4318C6BD-E0A1-45FE-AC30-96E7F73B51FB")]
18  public class SymbolicRegressionConstraintAnalyzer : SymbolicDataAnalysisAnalyzer, ISymbolicExpressionTreeAnalyzer {
19    private const string ConstraintViolationsResultName   = "Constraint Violations";
20    private const string ProblemDataParameterName         = "ProblemData";
21    private const string ConstraintViolationParameterName = "ConstraintViolations";
22    private const string PenalityMultiplierParameterName = "ConstraintsPenalityMultiplier";
23
24    #region parameter properties
25
26    public ILookupParameter<IRegressionProblemData> RegressionProblemDataParameter =>
27      (ILookupParameter<IRegressionProblemData>) Parameters[ProblemDataParameterName];
28
29    public IResultParameter<DataTable> ConstraintViolationParameter =>
30      (IResultParameter<DataTable>) Parameters[ConstraintViolationParameterName];
31
32    public ILookupParameter<DoubleValue> PenalityMultiplierParameter =>
33      (ILookupParameter<DoubleValue>)Parameters[PenalityMultiplierParameterName];
34
35    #endregion
36
37    public override bool EnabledByDefault => false;
38    public static int Iterations { get; set; } = 0;
39
40    [StorableConstructor]
41    protected SymbolicRegressionConstraintAnalyzer(StorableConstructorFlag _) : base(_) { }
42
43    protected SymbolicRegressionConstraintAnalyzer(SymbolicRegressionConstraintAnalyzer original, Cloner cloner) :
44      base(original, cloner) { }
45
46    public override IDeepCloneable Clone(Cloner cloner) {
47      return new SymbolicRegressionConstraintAnalyzer(this, cloner);
48    }
49
50    public SymbolicRegressionConstraintAnalyzer() {
51      Parameters.Add(new LookupParameter<IRegressionProblemData>(ProblemDataParameterName,
52        "The problem data of the symbolic data analysis problem."));
53      Parameters.Add(new ResultParameter<DataTable>(ConstraintViolationParameterName,
54        "Shows the number of constraint violations!"));
55      Parameters.Add(new LookupParameter<DoubleValue>(PenalityMultiplierParameterName,
56        "Lookup parameter for the penality multiplier.", "PenalityMultiplier"));
57
58      ConstraintViolationParameter.DefaultValue = new DataTable(ConstraintViolationParameterName) {
59        VisualProperties =
60          {
61            XAxisTitle = "Generations",
62            YAxisTitle = "Constraint Violations"
63          }
64      };
65    }
66
67    public override void InitializeState()
68    {
69      Iterations = 0;
70      base.InitializeState();
71    }
72
73    public override void ClearState()
74    {
75      Iterations = 0;
76      base.ClearState();
77    }
78
79
80    [StorableHook(HookType.AfterDeserialization)]
81    private void AfterDeserialization() {
82      if (!Parameters.ContainsKey(PenalityMultiplierParameterName))
83        Parameters.Add(new LookupParameter<DoubleValue>(PenalityMultiplierParameterName,
84        "Lookup parameter for the penality multiplier.", "PenalityMultiplier"));
85    }
86
87    public override IOperation Apply()
88    {
89      Iterations++;
90
91      PenalityMultiplierParameter.ActualValue = new DoubleValue(QuadraticDiscreteDoubleValueModifier.Calculate(0, 0.05, 1.0, Iterations, 0, 2000));
92      //GeneralizedExponentialDiscreteDoubleValueModifier
93
94      var problemData = RegressionProblemDataParameter.ActualValue;
95      var trees       = SymbolicExpressionTreeParameter.ActualValue;
96
97      var results        = ResultCollectionParameter.ActualValue;
98      var constraints    = problemData.IntervalConstraints.EnabledConstraints;
99      var variableRanges = problemData.VariableRanges.GetReadonlyDictionary();
100      var newDataTable   = ConstraintViolationParameter.ActualValue;
101
102      if (newDataTable.Rows.Count == 0)
103        foreach (var constraint in constraints)
104          newDataTable.Rows.Add(new DataRow(constraint.Expression));
105
106      var interpreter = new IntervalInterpreter();
107      foreach (var constraint in constraints) {
108        var violations = trees.Select(tree => ConstraintSatisfied(constraint, interpreter, variableRanges, tree, out double error))
109                              .Count(satisfied => !satisfied);
110        newDataTable.Rows[constraint.Expression].Values.Add(violations);
111      }
112
113      return base.Apply();
114    }
115
116    public static bool ConstraintSatisfied(IntervalConstraint constraint,
117                                           IntervalInterpreter intervalInterpreter,
118                                           IReadOnlyDictionary<string, Interval> variableRanges,
119                                           ISymbolicExpressionTree solution,
120                                           out double error) {
121      if (constraint.Variable != null && !variableRanges.ContainsKey(constraint.Variable))
122        throw new
123          ArgumentException($"The given variable {constraint.Variable} in the constraint does not exists in the model.",
124                            nameof(IntervalConstraintsParser));
125
126      Interval resultInterval;
127
128      // create new variable ranges for defined regions
129      IDictionary<string, Interval> regionRanges = new Dictionary<string, Interval>();
130      foreach (var kvp in variableRanges)
131      {
132        if (kvp.Key != constraint.Target && constraint.Regions.TryGetValue(kvp.Key, out Interval val))
133        {
134          regionRanges.Add(kvp.Key, val);
135        }
136        else
137        {
138          regionRanges.Add(kvp);
139        }
140      }
141
142      // calculate result interval
143      if (!constraint.IsDerivative) {
144        resultInterval = intervalInterpreter.GetSymbolicExpressionTreeInterval(solution, new ReadOnlyDictionary<string, Interval>(regionRanges));
145      }
146      else {
147        var tree = solution;
148        for (var i = 0; i < constraint.NumberOfDerivations; ++i) {
149          if (!IntervalInterpreter.IsCompatible(tree) || !DerivativeCalculator.IsCompatible(tree))
150            throw new ArgumentException("Cube, Root, Power Symbols are not supported.");
151          tree = DerivativeCalculator.Derive(tree, constraint.Variable);
152        }
153
154        resultInterval = intervalInterpreter.GetSymbolicExpressionTreeInterval(tree, new ReadOnlyDictionary<string, Interval>(regionRanges));
155      }
156
157      error = 0.0;
158      bool satisfied = true;
159      if(!constraint.Interval.Contains(resultInterval.LowerBound))
160      {
161        satisfied = false;
162        error += Math.Abs(resultInterval.LowerBound - constraint.Interval.LowerBound);
163      }
164
165      if (!constraint.Interval.Contains(resultInterval.UpperBound))
166      {
167        satisfied = false;
168        error += Math.Abs(resultInterval.UpperBound - constraint.Interval.UpperBound);
169      }
170
171      error *= constraint.Weight;
172
173      //var satisfied = constraint.Interval.Contains(resultInterval);
174      return satisfied;
175    }
176
177    public static bool ConstraintsSatisfied(IEnumerable<IntervalConstraint> constraints,
178                                            IReadOnlyDictionary<string, Interval> variableRanges,
179                                            ISymbolicExpressionTree solution,
180                                            out double error) {
181      var intervalInterpreter = new IntervalInterpreter();
182      error = 0.0;
183      var satisfied = true;
184      foreach (var constraint in constraints) {
185        if (constraint.Variable != null && !variableRanges.ContainsKey(constraint.Variable))
186          throw new
187            ArgumentException($"The given variable {constraint.Variable} in the constraint does not exists in the model.",
188                              nameof(IntervalConstraintsParser));
189
190        satisfied = ConstraintSatisfied(constraint, intervalInterpreter, variableRanges, solution, out double e) && satisfied;
191        error += e;
192        //if (!satisfied) return false;
193      }
194
195      return satisfied;
196    }
197  }
198}
Note: See TracBrowser for help on using the repository browser.