Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 17751 was 17751, checked in by chaider, 4 years ago

#3076 Added Splitting-Parameter

File size: 10.5 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    private const string PenalityMultiplierResultParameterName = "PenalityMultiplierResultParameter";
24    private const string StepSizeParameterName = "Step Size";
25
26    #region parameter properties
27
28    public ILookupParameter<IRegressionProblemData> RegressionProblemDataParameter =>
29      (ILookupParameter<IRegressionProblemData>) Parameters[ProblemDataParameterName];
30
31    public IResultParameter<DataTable> ConstraintViolationParameter =>
32      (IResultParameter<DataTable>) Parameters[ConstraintViolationParameterName];
33
34    public ILookupParameter<DoubleValue> PenalityMultiplierParameter =>
35      (ILookupParameter<DoubleValue>)Parameters[PenalityMultiplierParameterName];
36    public IValueParameter<IntValue> StepSizeParameter =>
37      (IValueParameter<IntValue>)Parameters[StepSizeParameterName];
38
39    public IResultParameter<DataTable> PenalityMultiplierResultParameter =>
40      (IResultParameter<DataTable>)Parameters[PenalityMultiplierResultParameterName];
41
42    #endregion
43
44    public override bool EnabledByDefault => false;
45    public static int Iterations { get; set; } = 0;
46
47    [StorableConstructor]
48    protected SymbolicRegressionConstraintAnalyzer(StorableConstructorFlag _) : base(_) { }
49
50    protected SymbolicRegressionConstraintAnalyzer(SymbolicRegressionConstraintAnalyzer original, Cloner cloner) :
51      base(original, cloner) { }
52
53    public override IDeepCloneable Clone(Cloner cloner) {
54      return new SymbolicRegressionConstraintAnalyzer(this, cloner);
55    }
56
57    public SymbolicRegressionConstraintAnalyzer() {
58      Parameters.Add(new LookupParameter<IRegressionProblemData>(ProblemDataParameterName,
59        "The problem data of the symbolic data analysis problem."));
60      Parameters.Add(new ResultParameter<DataTable>(ConstraintViolationParameterName,
61        "Shows the number of constraint violations!"));
62      Parameters.Add(new LookupParameter<DoubleValue>(PenalityMultiplierParameterName,
63        "Lookup parameter for the penality multiplier.", "PenalityMultiplier"));
64      Parameters.Add(new ResultParameter<DataTable>(PenalityMultiplierResultParameterName,
65        "Shows the behavior of the penality multiplier."));
66      Parameters.Add(new ValueParameter<IntValue>(StepSizeParameterName,
67        "Defines the step size for the increasing penality multiplier.", new IntValue(1)));
68
69      ConstraintViolationParameter.DefaultValue = new DataTable(ConstraintViolationParameterName) {
70        VisualProperties =
71          {
72            XAxisTitle = "Generations",
73            YAxisTitle = "Constraint Violations"
74          }
75      };
76
77      PenalityMultiplierResultParameter.DefaultValue = new DataTable(PenalityMultiplierResultParameterName)
78      {
79        VisualProperties =
80          {
81            XAxisTitle = "Generations",
82            YAxisTitle = "Penality Multiplier"
83          }
84      };
85    }
86
87    public override void InitializeState()
88    {
89      Iterations = 0;
90      base.InitializeState();
91    }
92
93    public override void ClearState()
94    {
95      Iterations = 0;
96      base.ClearState();
97    }
98
99
100    [StorableHook(HookType.AfterDeserialization)]
101    private void AfterDeserialization() {
102      if (!Parameters.ContainsKey(PenalityMultiplierParameterName))
103        Parameters.Add(new LookupParameter<DoubleValue>(PenalityMultiplierParameterName,
104        "Lookup parameter for the penality multiplier.", "PenalityMultiplier"));
105
106      if (!Parameters.ContainsKey(PenalityMultiplierResultParameterName))
107      {
108        Parameters.Add(new ResultParameter<DataTable>(PenalityMultiplierResultParameterName,
109        "Shows the behavior of the penality multiplier."));
110
111        PenalityMultiplierResultParameter.DefaultValue = new DataTable(PenalityMultiplierResultParameterName)
112        {
113          VisualProperties =
114          {
115            XAxisTitle = "Generations",
116            YAxisTitle = "Penality Multiplier"
117          }
118        };
119      }
120
121      if (!Parameters.ContainsKey(StepSizeParameterName))
122        Parameters.Add(new ValueParameter<IntValue>(StepSizeParameterName,
123        "Defines the step size for the increasing penality multiplier.", new IntValue(1)));
124
125    }
126
127    public override IOperation Apply()
128    {
129      Iterations++;
130      var rowName = "GeneralizedExponentialDiscreteDoubleValueModifier";
131      var stepSize = StepSizeParameter?.Value?.Value ?? 1;
132      var penalityMultiplier = new DoubleValue(LinearDiscreteDoubleValueModifier.Apply(0, 0.1, 1.0, (int)(Iterations / stepSize) * stepSize, 0, 1000));
133      PenalityMultiplierParameter.ActualValue = penalityMultiplier;
134      //GeneralizedExponentialDiscreteDoubleValueModifier
135      //QuadraticDiscreteDoubleValueModifier
136      //LinearDiscreteDoubleValueModifier
137
138      var problemData = RegressionProblemDataParameter.ActualValue;
139      var trees       = SymbolicExpressionTreeParameter.ActualValue;
140
141      var results        = ResultCollectionParameter.ActualValue;
142      var constraints    = problemData.IntervalConstraints.EnabledConstraints;
143      var variableRanges = problemData.VariableRanges.GetReadonlyDictionary();
144      var newDataTable   = ConstraintViolationParameter.ActualValue;
145
146      if (newDataTable.Rows.Count == 0)
147        foreach (var constraint in constraints)
148          newDataTable.Rows.Add(new DataRow(constraint.Expression));
149
150      var interpreter = new IntervalInterpreter();
151      foreach (var constraint in constraints) {
152        var violations = trees.Select(tree => ConstraintSatisfied(constraint, interpreter, variableRanges, tree, out double error))
153                              .Count(satisfied => !satisfied);
154        newDataTable.Rows[constraint.Expression].Values.Add(violations);
155      }
156
157      var penalityDataTable = PenalityMultiplierResultParameter.ActualValue;
158      if (penalityDataTable.Rows.Count == 0)
159        penalityDataTable.Rows.Add(new DataRow(rowName));
160      penalityDataTable.Rows[rowName].Values.Add(penalityMultiplier.Value);
161
162      return base.Apply();
163    }
164
165    public static bool ConstraintSatisfied(IntervalConstraint constraint,
166                                           IntervalInterpreter intervalInterpreter,
167                                           IReadOnlyDictionary<string, Interval> variableRanges,
168                                           ISymbolicExpressionTree solution,
169                                           out double error) {
170      if (constraint.Variable != null && !variableRanges.ContainsKey(constraint.Variable))
171        throw new
172          ArgumentException($"The given variable {constraint.Variable} in the constraint does not exists in the model.",
173                            nameof(IntervalConstraintsParser));
174
175      Interval resultInterval;
176
177      // create new variable ranges for defined regions
178      IDictionary<string, Interval> regionRanges = new Dictionary<string, Interval>();
179      foreach (var kvp in variableRanges)
180      {
181        if (kvp.Key != constraint.Target && constraint.Regions.TryGetValue(kvp.Key, out Interval val))
182        {
183          regionRanges.Add(kvp.Key, val);
184        }
185        else
186        {
187          regionRanges.Add(kvp);
188        }
189      }
190
191      // calculate result interval
192      if (!constraint.IsDerivative) {
193        resultInterval = intervalInterpreter.GetSymbolicExpressionTreeInterval(solution, new ReadOnlyDictionary<string, Interval>(regionRanges), 0);
194      }
195      else {
196        var tree = solution;
197        for (var i = 0; i < constraint.NumberOfDerivations; ++i) {
198          if (!IntervalInterpreter.IsCompatible(tree) || !DerivativeCalculator.IsCompatible(tree))
199            throw new ArgumentException("Cube, Root, Power Symbols are not supported.");
200          tree = DerivativeCalculator.Derive(tree, constraint.Variable);
201        }
202
203        resultInterval = intervalInterpreter.GetSymbolicExpressionTreeInterval(tree, new ReadOnlyDictionary<string, Interval>(regionRanges), 0);
204      }
205
206      error = 0.0;
207      bool satisfied = true;
208      if(!constraint.Interval.Contains(resultInterval.LowerBound))
209      {
210        satisfied = false;
211        error += Math.Abs(resultInterval.LowerBound - constraint.Interval.LowerBound);
212      }
213
214      if (!constraint.Interval.Contains(resultInterval.UpperBound))
215      {
216        satisfied = false;
217        error += Math.Abs(resultInterval.UpperBound - constraint.Interval.UpperBound);
218      }
219
220      error *= constraint.Weight;
221
222      //var satisfied = constraint.Interval.Contains(resultInterval);
223      return satisfied;
224    }
225
226    public static bool ConstraintsSatisfied(IEnumerable<IntervalConstraint> constraints,
227                                            IReadOnlyDictionary<string, Interval> variableRanges,
228                                            ISymbolicExpressionTree solution, bool useSplitting,
229                                            out double error) {
230      var intervalInterpreter = new IntervalInterpreter() {UseIntervalSplitting = useSplitting};
231      error = 0.0;
232      var satisfied = true;
233      foreach (var constraint in constraints) {
234        if (constraint.Variable != null && !variableRanges.ContainsKey(constraint.Variable))
235          throw new
236            ArgumentException($"The given variable {constraint.Variable} in the constraint does not exists in the model.",
237                              nameof(IntervalConstraintsParser));
238
239        satisfied = ConstraintSatisfied(constraint, intervalInterpreter, variableRanges, solution, out double e) && satisfied;
240        error += e;
241        //if (!satisfied) return false;
242      }
243
244      return satisfied;
245    }
246  }
247}
Note: See TracBrowser for help on using the repository browser.