Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/19/15 19:39:07 (9 years ago)
Author:
mkommend
Message:

#2175: Merged r13241, r13300, r13307, r13308 into stable.

Location:
stable
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • stable

  • stable/HeuristicLab.Problems.DataAnalysis.Symbolic

  • stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer.cs

    r12009 r13310  
    2020#endregion
    2121
    22 using System;
    2322using System.Collections.Generic;
    2423using System.Linq;
     
    4241    private const string TrainingBestSolutionQualitiesParameterName = "Best training solution qualities";
    4342    private const string UpdateAlwaysParameterName = "Always update best solutions";
     43    private const string TrainingBestSolutionParameterName = "Best training solution";
    4444
    4545    #region parameter properties
     
    5555    #endregion
    5656    #region properties
    57     public ItemList<T> TrainingBestSolutions {
     57    private ItemList<T> TrainingBestSolutions {
    5858      get { return TrainingBestSolutionsParameter.ActualValue; }
    5959      set { TrainingBestSolutionsParameter.ActualValue = value; }
    6060    }
    61     public ItemList<DoubleArray> TrainingBestSolutionQualities {
     61    private ItemList<DoubleArray> TrainingBestSolutionQualities {
    6262      get { return TrainingBestSolutionQualitiesParameter.ActualValue; }
    6363      set { TrainingBestSolutionQualitiesParameter.ActualValue = value; }
    6464    }
    65     public BoolValue UpdateAlways {
    66       get { return UpdateAlwaysParameter.Value; }
     65    public bool UpdateAlways {
     66      get { return UpdateAlwaysParameter.Value.Value; }
     67      set { UpdateAlwaysParameter.Value.Value = value; }
    6768    }
    6869    #endregion
     
    9798      }
    9899
     100      if (!results.ContainsKey(TrainingBestSolutionParameterName)) {
     101        results.Add(new Result(TrainingBestSolutionParameterName, "", typeof(ISymbolicDataAnalysisSolution)));
     102      }
     103
    99104      //if the pareto front of best solutions shall be updated regardless of the quality, the list initialized empty to discard old solutions
    100       IList<double[]> trainingBestQualities;
    101       if (UpdateAlways.Value) {
     105      List<double[]> trainingBestQualities;
     106      if (UpdateAlways) {
    102107        trainingBestQualities = new List<double[]>();
    103108      } else {
     
    105110      }
    106111
    107       #region find best trees
    108       IList<int> nonDominatedIndexes = new List<int>();
    109       ISymbolicExpressionTree[] tree = SymbolicExpressionTree.ToArray();
     112      ISymbolicExpressionTree[] trees = SymbolicExpressionTree.ToArray();
    110113      List<double[]> qualities = Qualities.Select(x => x.ToArray()).ToList();
    111114      bool[] maximization = Maximization.ToArray();
    112       List<double[]> newNonDominatedQualities = new List<double[]>();
    113       for (int i = 0; i < tree.Length; i++) {
    114         if (IsNonDominated(qualities[i], trainingBestQualities, maximization) &&
    115           IsNonDominated(qualities[i], qualities, maximization)) {
    116           if (!newNonDominatedQualities.Contains(qualities[i], new DoubleArrayComparer())) {
    117             newNonDominatedQualities.Add(qualities[i]);
    118             nonDominatedIndexes.Add(i);
     115
     116      var nonDominatedIndividuals = new[] { new { Tree = default(ISymbolicExpressionTree), Qualities = default(double[]) } }.ToList();
     117      nonDominatedIndividuals.Clear();
     118
     119      // build list of new non-dominated solutions
     120      for (int i = 0; i < trees.Length; i++) {
     121        if (IsNonDominated(qualities[i], nonDominatedIndividuals.Select(ind => ind.Qualities), maximization) &&
     122            IsNonDominated(qualities[i], trainingBestQualities, maximization)) {
     123          for (int j = nonDominatedIndividuals.Count - 1; j >= 0; j--) {
     124            if (IsBetterOrEqual(qualities[i], nonDominatedIndividuals[j].Qualities, maximization)) {
     125              nonDominatedIndividuals.RemoveAt(j);
     126            }
    119127          }
     128          nonDominatedIndividuals.Add(new { Tree = trees[i], Qualities = qualities[i] });
    120129        }
    121130      }
    122       #endregion
     131
     132      var nonDominatedSolutions = nonDominatedIndividuals.Select(x => new { Solution = CreateSolution(x.Tree, x.Qualities), Qualities = x.Qualities }).ToList();
     133      nonDominatedSolutions.ForEach(s => s.Solution.Name = string.Join(",", s.Qualities.Select(q => q.ToString())));
     134
    123135      #region update Pareto-optimal solution archive
    124       if (nonDominatedIndexes.Count > 0) {
    125         ItemList<DoubleArray> nonDominatedQualities = new ItemList<DoubleArray>();
    126         ItemList<T> nonDominatedSolutions = new ItemList<T>();
    127         // add all new non-dominated solutions to the archive
    128         foreach (var index in nonDominatedIndexes) {
    129           T solution = CreateSolution(tree[index], qualities[index]);
    130           nonDominatedSolutions.Add(solution);
    131           nonDominatedQualities.Add(new DoubleArray(qualities[index]));
    132         }
    133         // add old non-dominated solutions only if they are not dominated by one of the new solutions
     136      if (nonDominatedSolutions.Count > 0) {
     137        //add old non-dominated solutions only if they are not dominated by one of the new solutions
    134138        for (int i = 0; i < trainingBestQualities.Count; i++) {
    135           if (IsNonDominated(trainingBestQualities[i], newNonDominatedQualities, maximization)) {
    136             if (!newNonDominatedQualities.Contains(trainingBestQualities[i], new DoubleArrayComparer())) {
    137               nonDominatedSolutions.Add(TrainingBestSolutions[i]);
    138               nonDominatedQualities.Add(TrainingBestSolutionQualities[i]);
    139             }
     139          if (IsNonDominated(trainingBestQualities[i], nonDominatedSolutions.Select(x => x.Qualities), maximization)) {
     140            nonDominatedSolutions.Add(new { Solution = TrainingBestSolutions[i], Qualities = TrainingBestSolutionQualities[i].ToArray() });
    140141          }
    141142        }
    142143
    143         results[TrainingBestSolutionsParameter.Name].Value = nonDominatedSolutions;
    144         results[TrainingBestSolutionQualitiesParameter.Name].Value = nonDominatedQualities;
     144        //assumes the the first objective is always the accuracy
     145        var sortedNonDominatedSolutions = maximization[0]
     146          ? nonDominatedSolutions.OrderByDescending(x => x.Qualities[0])
     147          : nonDominatedSolutions.OrderBy(x => x.Qualities[0]);
     148        var trainingBestSolution = sortedNonDominatedSolutions.Select(s => s.Solution).First();
     149        results[TrainingBestSolutionParameterName].Value = trainingBestSolution;
     150        TrainingBestSolutions = new ItemList<T>(sortedNonDominatedSolutions.Select(x => x.Solution));
     151        results[TrainingBestSolutionsParameter.Name].Value = TrainingBestSolutions;
     152        TrainingBestSolutionQualities = new ItemList<DoubleArray>(sortedNonDominatedSolutions.Select(x => new DoubleArray(x.Qualities)));
     153        results[TrainingBestSolutionQualitiesParameter.Name].Value = TrainingBestSolutionQualities;
    145154      }
    146155      #endregion
     
    148157    }
    149158
    150     private class DoubleArrayComparer : IEqualityComparer<double[]> {
    151       public bool Equals(double[] x, double[] y) {
    152         if (y.Length != x.Length) throw new ArgumentException();
    153         for (int i = 0; i < x.Length; i++) {
    154           if (!x[i].IsAlmost(y[i])) return false;
    155         }
    156         return true;
    157       }
    158 
    159       public int GetHashCode(double[] obj) {
    160         int c = obj.Length;
    161         for (int i = 0; i < obj.Length; i++)
    162           c ^= obj[i].GetHashCode();
    163         return c;
    164       }
    165     }
    166 
    167159    protected abstract T CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQuality);
    168160
    169     private bool IsNonDominated(double[] point, IList<double[]> points, bool[] maximization) {
     161    private bool IsNonDominated(double[] point, IEnumerable<double[]> points, bool[] maximization) {
    170162      foreach (var refPoint in points) {
    171         bool refPointDominatesPoint = true;
    172         for (int i = 0; i < point.Length; i++) {
    173           refPointDominatesPoint &= IsBetterOrEqual(refPoint[i], point[i], maximization[i]);
    174         }
     163        bool refPointDominatesPoint = IsBetterOrEqual(refPoint, point, maximization);
    175164        if (refPointDominatesPoint) return false;
    176165      }
    177166      return true;
    178167    }
     168
     169    private bool IsBetterOrEqual(double[] lhs, double[] rhs, bool[] maximization) {
     170      for (int i = 0; i < lhs.Length; i++) {
     171        var result = IsBetterOrEqual(lhs[i], rhs[i], maximization[i]);
     172        if (!result) return false;
     173      }
     174      return true;
     175    }
     176
    179177    private bool IsBetterOrEqual(double lhs, double rhs, bool maximization) {
    180       if (maximization) return lhs > rhs;
    181       else return lhs < rhs;
     178      if (maximization) return lhs >= rhs;
     179      else return lhs <= rhs;
    182180    }
    183181  }
Note: See TracChangeset for help on using the changeset viewer.