Changeset 17946


Ignore:
Timestamp:
04/16/21 16:04:02 (5 months ago)
Author:
dpiringe
Message:

#3119

  • added a threshold in interval format for soft constraint evaluation
Location:
branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraint.cs

    r17937 r17946  
    106106    }
    107107
     108    [Storable]
     109    private Interval threshold;
     110    public Interval Threshold {
     111      get => threshold;
     112      set {
     113        if (threshold == value)
     114          return;
     115        threshold = value;
     116        OnToStringChanged();
     117        OnChanged();
     118      }
     119    }
     120
    108121    [StorableConstructor]
    109122    private ShapeConstraint(StorableConstructorFlag _) : base(_) { }
     
    115128
    116129    // without derivation
    117     public ShapeConstraint(Interval interval, double weight)
     130    public ShapeConstraint(Interval interval, double weight, Interval threshold)
    118131      : this(string.Empty, 0,
    119          interval, new IntervalCollection(), weight) { }
    120 
    121     public ShapeConstraint(Interval interval, IntervalCollection regions, double weight)
     132         interval, new IntervalCollection(), weight, threshold) { }
     133
     134    public ShapeConstraint(Interval interval, IntervalCollection regions, double weight, Interval threshold)
    122135      : this(string.Empty, 0,
    123          interval, regions, weight) { }
     136         interval, regions, weight, threshold) { }
    124137
    125138    public ShapeConstraint(string variable, int numberOfDerivations,
    126                               Interval interval, double weight)
     139                              Interval interval, double weight, Interval threshold)
    127140      : this(variable, numberOfDerivations,
    128              interval, new IntervalCollection(), weight) { }
     141             interval, new IntervalCollection(), weight, threshold) { }
    129142
    130143    public ShapeConstraint(string variable, int numberOfDerivations,
    131                               Interval interval, IntervalCollection regions, double weight) {
     144                              Interval interval, IntervalCollection regions, double weight, Interval threshold) {
    132145      Variable = variable;
    133146      NumberOfDerivations = numberOfDerivations;
     
    135148      Regions = regions;
    136149      Weight = weight;
     150      Threshold = threshold;
    137151    }
    138152
     
    175189      if (!IsDerivative) {
    176190        expression = string.Format($"f in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]");
    177         if (Regions != null) {
    178           foreach (var region in Regions.GetReadonlyDictionary())
    179             expression += $", {region.Key} in [{write(region.Value.LowerBound)} .. {write(region.Value.UpperBound)}]";
     191      } else {
     192        var derivationString = string.Empty;
     193        switch (numberOfDerivations) {
     194          case 1:
     195            derivationString = ""; break;
     196          case 2:
     197            derivationString = "²"; break;
     198          case 3:
     199            derivationString = "³"; break;
    180200        }
    181         if (Weight != 1.0) {
    182           expression += $" weight: {weight}";
    183         }
    184 
    185         return expression;
    186       }
    187 
    188       var derivationString = string.Empty;
    189       switch (numberOfDerivations) {
    190         case 1:
    191           derivationString = ""; break;
    192         case 2:
    193           derivationString = "²"; break;
    194         case 3:
    195           derivationString = "³"; break;
    196       }
    197       expression = string.Format($"∂{derivationString}f/∂{Variable}{derivationString} in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]");
     201        expression = string.Format($"∂{derivationString}f/∂{Variable}{derivationString} in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]");
     202      }
     203
    198204      if (Regions != null) {
    199205        foreach (var region in Regions.GetReadonlyDictionary())
     
    203209        expression += $" weight: {weight}";
    204210      }
     211      if (!double.IsNegativeInfinity(Threshold.LowerBound) || !double.IsPositiveInfinity(Threshold.UpperBound))
     212        expression += $" threshold: [{write(Threshold.LowerBound)} .. {write(Threshold.UpperBound)}]";
     213
    205214      return expression;
    206215    }
  • branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraintsParser.cs

    r17911 r17946  
    7575    private const string variableRegex = @"(['](?<varName>.*)[']|(?<varName>[^\s²³]+))\s*";
    7676    private const string weightRegex = @"\s*(weight:\s*(?<weight>\S*))?";
     77    private const string thresholdRegex = @"\s*(threshold\s*in\s*(?<threshold> "+ intervalRegex + @"))?";
    7778    public static ShapeConstraint ParseFunctionRangeConstraint(string expr) {
    7879      if (!expr.StartsWith("f")) throw new ArgumentException($"Invalid function range constraint {expr} (e.g. f in [1..2])");
     
    9091      // df / d'x' in [0..10], 'x' in [1 .. 3]
    9192      // df / d'x' in [0..10], 'x' in [1 .. 3], y in [10..30] weight: 1.2
    92 
     93      // df / d'x' in [0..10], 'x' in [1 .. 3], y in [10..30] weight: 1.2 threshold in [-10 .. 10]
    9394      var match = Regex.Match(targetConstraint,
    9495                    @"\s*\bin\b" +
     
    99100                      intervalRegex +
    100101                    @")*" +
    101                     weightRegex
     102                    weightRegex +
     103                    thresholdRegex
    102104                    );
    103105
     
    110112        var interval = new Interval(lowerBound, upperBound);
    111113        var weight = 1.0;
     114        var threshold = new Interval(double.NegativeInfinity, double.PositiveInfinity);
    112115
    113116        if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value))
    114117          weight = ParseAndValidateDouble(match.Groups["weight"].Value);
     118
     119        if(match.Groups["threshold"].Success) {
     120          var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
     121          var upperboundCount = match.Groups["upperBound"].Captures.Count;
     122          var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - 1].Value);
     123          var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - 1].Value);
     124          threshold = new Interval(thresholdLb, thresholdUb);
     125        }
    115126
    116127        if (match.Groups["varName"].Success) {
     
    127138              throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable.");
    128139          }
    129           return new ShapeConstraint(interval, regions, weight);
     140          return new ShapeConstraint(interval, regions, weight, threshold);
    130141        } else
    131           return new ShapeConstraint(interval, weight);
     142          return new ShapeConstraint(interval, weight, threshold);
    132143      } else
    133144        throw new ArgumentException($"The target constraint {expr} is not valid.");
     
    148159                                  intervalRegex +
    149160                                  @")*" +
    150                                 weightRegex
     161                                weightRegex +
     162                                thresholdRegex
    151163                                );
    152164
     
    172184        var interval = new Interval(lowerBound, upperBound);
    173185        var weight = 1.0;
     186        var threshold = new Interval(double.NegativeInfinity, double.PositiveInfinity);
    174187
    175188        if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value))
    176189          weight = ParseAndValidateDouble(match.Groups["weight"].Value);
     190
     191        if (match.Groups["threshold"].Success) {
     192          var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
     193          var upperboundCount = match.Groups["upperBound"].Captures.Count;
     194          var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - 1].Value);
     195          var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - 1].Value);
     196          threshold = new Interval(thresholdLb, thresholdUb);
     197        }
    177198
    178199        if (match.Groups["varName"].Captures.Count > 1) {
     
    189210              throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable.");
    190211          }
    191           return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight);
     212          return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight, threshold);
    192213        } else
    193           return new ShapeConstraint(variable, numberOfDerivation, interval, weight);
     214          return new ShapeConstraint(variable, numberOfDerivation, interval, weight, threshold);
    194215      } else
    195216        throw new ArgumentException($"The derivation constraint {expr} is not valid.");
Note: See TracChangeset for help on using the changeset viewer.