Changeset 14526


Ignore:
Timestamp:
12/22/16 16:52:32 (3 years ago)
Author:
bburlacu
Message:

#2679: Add analyzer for SingleObjectiveGoalSeekingProblem. Add result aggregation in the GoalSeekingOptimizer. Remove unused dataset parameter from the problems.

Location:
branches/HeuristicLab.GoalSeekingProblem
Files:
1 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalSeekingOptimizerView.cs

    r14380 r14526  
    5454      if (Content.ProblemData != null)
    5555        dataViewHost.Content = Content.ProblemData;
     56
     57      if (Content.Results != null)
     58        resultsViewHost.Content = Content.Results;
    5659    }
    5760
     
    6164      Content.ProblemChanged += (o, e) => { problemViewHost.Content = Content.Problem; };
    6265      Content.ProblemDataChanged += (o, e) => { dataViewHost.Content = Content.ProblemData; };
     66      Content.ResultsChanged += (o, e) => { resultsViewHost.Content = Content.Results; };
    6367    }
    6468
  • branches/HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalSeekingProblem.Views.csproj

    r14380 r14526  
    2222    <ErrorReport>prompt</ErrorReport>
    2323    <WarningLevel>4</WarningLevel>
     24    <LangVersion>4</LangVersion>
    2425  </PropertyGroup>
    2526  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     
    3233  </PropertyGroup>
    3334  <ItemGroup>
     35    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec" />
    3436    <Reference Include="HeuristicLab.Common-3.3">
    3537      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
  • branches/HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Analyzers/BestSolutionAnalyzer.cs

    r14324 r14526  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
  • branches/HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalSeekingOptimizer.cs

    r14383 r14526  
    2424using System.Drawing;
    2525using System.Linq;
     26using HeuristicLab.Analysis;
    2627using HeuristicLab.Common;
    2728using HeuristicLab.Core;
     29using HeuristicLab.Data;
    2830using HeuristicLab.Optimization;
    2931using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     
    6971
    7072        optimizer = value;
    71         optimizer.Problem = problem;
     73
     74        if (problem != null)
     75          optimizer.Problem = problem;
     76
    7277        RegisterOptimizerEvents();
    7378        OnAlgorithmChanged();
     
    9297    }
    9398
     99    [Storable]
     100    private ResultCollection results;
     101    public ResultCollection Results {
     102      get { return results; }
     103      private set {
     104        if (value != null)
     105          results = value;
     106        OnResultsChanged();
     107      }
     108    }
     109
    94110    private GoalSeekingOptimizerAction gsoAction;
    95111
     
    112128      this.Problem = (IGoalSeekingProblem)original.Problem.Clone(cloner);
    113129      this.ProblemData = (IRegressionProblemData)original.ProblemData.Clone(cloner);
     130      this.Results = (ResultCollection)original.Results.Clone();
    114131    }
    115132
     
    139156    }
    140157
     158    public EventHandler ResultsChanged;
     159    private void OnResultsChanged() {
     160      var changed = ResultsChanged;
     161      if (changed != null)
     162        changed(this, EventArgs.Empty);
     163    }
     164
    141165    private int calculatedRows;
     166    private int currentRow;
     167
    142168    public void Start() {
    143169      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
     
    148174        Optimizer.Prepare(clearRuns: true);
    149175        calculatedRows = 0;
    150 
    151         var row = problemData.TrainingIndices.Skip(calculatedRows).First();
    152         problem.Configure(problemData, row);
     176        currentRow = problemData.TrainingIndices.Skip(calculatedRows).First();
     177        problem.Configure(problemData, currentRow);
    153178        optimizer.Prepare();
    154179      }
     
    188213      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
    189214        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
     215
     216      if (Results != null)
     217        Results.Clear();
     218
    190219      if (optimizer != null) {
    191220        ExecutionTime = TimeSpan.Zero;
     
    223252    }
    224253
    225     public IEnumerable<IOptimizer> NestedOptimizers { get; }
     254    public IEnumerable<IOptimizer> NestedOptimizers { get; private set; }
    226255
    227256    public string Filename { get; set; }
     
    367396      var remainingRows = problemData.TrainingIndices.Skip(calculatedRows);
    368397
    369       if (gsoAction == GoalSeekingOptimizerAction.Stop) OnStopped();
    370       else if (!remainingRows.Any()) OnStopped();
    371       else if (gsoAction == GoalSeekingOptimizerAction.Pause) OnPaused();
    372       else if (gsoAction == GoalSeekingOptimizerAction.Start) {
    373         var row = remainingRows.First();
    374         problem.Configure(problemData, row);
    375         optimizer.Prepare();
    376         optimizer.Start();
    377       } else if (ExecutionState == ExecutionState.Started) {
    378         OnPaused();
    379       } else OnStopped();
     398      // extract results from the optimizer
     399      GetResults();
     400
     401      if (gsoAction == GoalSeekingOptimizerAction.Stop)
     402        OnStopped();
     403      else if (!remainingRows.Any()) {
     404        OnStopped();
     405      } else switch (gsoAction) {
     406          case GoalSeekingOptimizerAction.Pause:
     407            OnPaused();
     408            break;
     409          case GoalSeekingOptimizerAction.Start:
     410            currentRow = remainingRows.First();
     411            problem.Configure(problemData, currentRow);
     412            optimizer.Prepare();
     413            optimizer.Start();
     414            break;
     415          default:
     416            if (ExecutionState == ExecutionState.Started) {
     417              OnPaused();
     418            } else OnStopped();
     419            break;
     420        }
    380421    }
    381422    #endregion
     423    #endregion
     424
     425    #region aggregate results
     426    private void GetResults() {
     427      if (Problem is MultiObjectiveGoalSeekingProblem) {
     428        var m = (DoubleMatrix)optimizer.Results["Pareto Front Solutions"].Value;
     429        AggregateMultiObjectiveResults(m);
     430      } else if (Problem is SingleObjectiveGoalSeekingProblem) {
     431        var m = (DoubleMatrix)optimizer.Results["Best Solution"].Value;
     432        AggregateSingleObjectiveResults(m);
     433      }
     434    }
     435
     436    private void AggregateSingleObjectiveResults(DoubleMatrix solutions) {
     437      var indices = solutions.ColumnNames.Select((x, i) => Tuple.Create(x, i)).ToDictionary(x => x.Item1, x => x.Item2);
     438
     439      var goals = Problem.Goals.Where(x => x.Active).ToList();
     440      var inputs = Problem.Inputs.Where(x => x.Active).ToList();
     441
     442      if (Results == null)
     443        Results = new ResultCollection();
     444      // goals
     445      if (!Results.ContainsKey("Goals"))
     446        Results.Add(new Result("Goals", new ResultCollection()));
     447      var goalResults = (ResultCollection)Results["Goals"].Value;
     448      foreach (var goal in goals) {
     449        var estimatedGoalName = goal.Name + " (estimated)";
     450        if (!goalResults.ContainsKey(goal.Name)) {
     451          goalResults.Add(new Result(goal.Name, new ScatterPlot(goal.Name, "")));
     452        }
     453
     454        var plot = (ScatterPlot)goalResults[goal.Name].Value;
     455        if (!plot.Rows.ContainsKey(goal.Name)) {
     456          plot.Rows.Add(new ScatterPlotDataRow { Name = goal.Name });
     457          plot.Rows.Add(new ScatterPlotDataRow { Name = estimatedGoalName });
     458        }
     459
     460        plot.Rows[goal.Name].Points.Add(new Point2D<double>(currentRow, solutions[0, indices[goal.Name]]));
     461        plot.Rows[estimatedGoalName].Points.Add(new Point2D<double>(currentRow, solutions[0, indices[estimatedGoalName]]));
     462      }
     463
     464      // inputs
     465      if (!Results.ContainsKey("Inputs"))
     466        Results.Add(new Result("Inputs", new ResultCollection()));
     467      var inputResults = (ResultCollection)Results["Inputs"].Value;
     468      foreach (var input in inputs) {
     469        var estimatedInputName = input.Name + " (estimated)";
     470        if (!inputResults.ContainsKey(input.Name)) {
     471          inputResults.Add(new Result(input.Name, new ScatterPlot(input.Name, "")));
     472        }
     473
     474        var plot = (ScatterPlot)inputResults[input.Name].Value;
     475        if (!plot.Rows.ContainsKey(input.Name)) {
     476          plot.Rows.Add(new ScatterPlotDataRow { Name = input.Name });
     477          plot.Rows.Add(new ScatterPlotDataRow { Name = estimatedInputName });
     478        }
     479
     480        plot.Rows[input.Name].Points.Add(new Point2D<double>(currentRow, solutions[0, indices[input.Name]]));
     481        plot.Rows[estimatedInputName].Points.Add(new Point2D<double>(currentRow, solutions[0, indices[estimatedInputName]]));
     482      }
     483      // aggregate results as a matrix
     484      UpdateResultsMatrix(solutions);
     485    }
     486
     487    private void AggregateMultiObjectiveResults(DoubleMatrix solutions) {
     488      int maxSolutionsCount = Math.Min(solutions.Rows, 10);
     489
     490      var indices = solutions.ColumnNames.Select((x, i) => Tuple.Create(x, i)).ToDictionary(x => x.Item1, x => x.Item2);
     491
     492      var goals = Problem.Goals.Where(x => x.Active).ToList();
     493      var inputs = Problem.Inputs.Where(x => x.Active).ToList();
     494
     495      if (Results == null)
     496        Results = new ResultCollection();
     497      // goals
     498      if (!Results.ContainsKey("Goals"))
     499        Results.Add(new Result("Goals", new ResultCollection()));
     500      var goalResults = (ResultCollection)Results["Goals"].Value;
     501      foreach (var goal in goals) {
     502        var estimatedGoalName = goal.Name + " (estimated)";
     503        if (!goalResults.ContainsKey(goal.Name)) {
     504          goalResults.Add(new Result(goal.Name, new ScatterPlot(goal.Name, "")));
     505        }
     506
     507        var plot = (ScatterPlot)goalResults[goal.Name].Value;
     508        if (!plot.Rows.ContainsKey(goal.Name)) {
     509          plot.Rows.Add(new ScatterPlotDataRow { Name = goal.Name, VisualProperties = { PointSize = 5 } });
     510        }
     511
     512        plot.Rows[goal.Name].Points.Add(new Point2D<double>(currentRow, solutions[0, indices[goal.Name]]));
     513        for (int i = 0; i < maxSolutionsCount; ++i) {
     514          if (!plot.Rows.ContainsKey(estimatedGoalName + i))
     515            plot.Rows.Add(new ScatterPlotDataRow { Name = estimatedGoalName + i, VisualProperties = { PointSize = 5 } });
     516          plot.Rows[estimatedGoalName + i].Points.Add(new Point2D<double>(currentRow, solutions[i, indices[estimatedGoalName]]));
     517        }
     518      }
     519      // inputs
     520      if (!Results.ContainsKey("Inputs"))
     521        Results.Add(new Result("Inputs", new ResultCollection()));
     522      var inputResults = (ResultCollection)Results["Inputs"].Value;
     523      foreach (var input in inputs) {
     524        var estimatedInputName = input.Name + " (estimated)";
     525        if (!inputResults.ContainsKey(input.Name)) {
     526          inputResults.Add(new Result(input.Name, new ScatterPlot(input.Name, "")));
     527        }
     528
     529        var plot = (ScatterPlot)inputResults[input.Name].Value;
     530        if (!plot.Rows.ContainsKey(input.Name)) {
     531          plot.Rows.Add(new ScatterPlotDataRow { Name = input.Name, VisualProperties = { PointSize = 5 } });
     532        }
     533
     534        plot.Rows[input.Name].Points.Add(new Point2D<double>(currentRow, solutions[0, indices[input.Name]])); // it stays the same for all the rows
     535        for (int i = 0; i < maxSolutionsCount; ++i) {
     536          if (!plot.Rows.ContainsKey(estimatedInputName + i))
     537            plot.Rows.Add(new ScatterPlotDataRow { Name = estimatedInputName + i, VisualProperties = { PointSize = 5 } });
     538          plot.Rows[estimatedInputName + i].Points.Add(new Point2D<double>(currentRow, solutions[i, indices[estimatedInputName]]));
     539        }
     540      }
     541      // also add a matrix containing the whole solution data including the row
     542      UpdateResultsMatrix(solutions);
     543    }
     544
     545    private void UpdateResultsMatrix(DoubleMatrix solutions) {
     546      // also add a matrix containing the whole solution data including the row
     547      var rows = problemData.TrainingIndices.Take(calculatedRows).ToList();
     548      var m = new DoubleMatrix(calculatedRows, solutions.Columns + 1) {
     549        RowNames = rows.Select(x => x.ToString()),
     550        ColumnNames = new[] { "Row" }.Concat(solutions.ColumnNames)
     551      };
     552      DoubleMatrix old = null;
     553      if (Results.ContainsKey("Solutions"))
     554        old = (DoubleMatrix)Results["Solutions"].Value;
     555      else
     556        Results.Add(new Result("Solutions", m));
     557
     558      if (old != null && calculatedRows > 0) {
     559        for (int i = 0; i < old.Rows; ++i) {
     560          for (int j = 0; j < old.Columns; ++j) {
     561            m[i, j] = old[i, j];
     562          }
     563        }
     564      }
     565      m[rows.Count - 1, 0] = currentRow;
     566      for (int i = 1; i < m.Columns; ++i) {
     567        m[rows.Count - 1, i] = solutions[0, i - 1];
     568      }
     569      Results["Solutions"].Value = m;
     570    }
    382571    #endregion
    383572  }
  • branches/HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalSeekingProblem.csproj

    r14383 r14526  
    2525    <Prefer32Bit>false</Prefer32Bit>
    2626    <PlatformTarget>AnyCPU</PlatformTarget>
     27    <LangVersion>4</LangVersion>
    2728  </PropertyGroup>
    2829  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  • branches/HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/MultiObjectiveGoalSeekingProblem.cs

    r14379 r14526  
    3939  public sealed class MultiObjectiveGoalSeekingProblem : MultiObjectiveBasicProblem<RealVectorEncoding>, IGoalSeekingProblem {
    4040    #region parameter names
    41     private const string ModifiableDatasetParameterName = "Dataset";
    4241    private const string InputsParameterName = "Inputs";
    4342    private const string GoalsParameterName = "Goals";
     
    151150    public MultiObjectiveGoalSeekingProblem() {
    152151      dataset = new ModifiableDataset();
    153       Parameters.Add(new ValueParameter<IDataset>(ModifiableDatasetParameterName, dataset) { Hidden = true });
    154152      Parameters.Add(new ValueParameter<CheckedItemList<InputParameter>>(InputsParameterName));
    155153      Parameters.Add(new ValueParameter<CheckedItemList<GoalParameter>>(GoalsParameterName));
  • branches/HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Properties

    • Property svn:ignore set to
      AssemblyInfo.cs
  • branches/HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/SingleObjectiveGoalSeekingProblem.cs

    r14379 r14526  
    2626using HeuristicLab.Common;
    2727using HeuristicLab.Core;
     28using HeuristicLab.Data;
    2829using HeuristicLab.Encodings.RealVectorEncoding;
    2930using HeuristicLab.Optimization;
     
    3839  public sealed class SingleObjectiveGoalSeekingProblem : SingleObjectiveBasicProblem<RealVectorEncoding>, IGoalSeekingProblem {
    3940    #region parameter names
    40     private const string ModifiableDatasetParameterName = "Dataset";
    4141    private const string InputsParameterName = "Inputs";
    4242    private const string GoalsParameterName = "Goals";
     
    136136    public SingleObjectiveGoalSeekingProblem() {
    137137      dataset = new ModifiableDataset();
    138       Parameters.Add(new ValueParameter<IDataset>(ModifiableDatasetParameterName, dataset) { Hidden = true });
    139138      Parameters.Add(new ValueParameter<CheckedItemList<InputParameter>>(InputsParameterName));
    140139      Parameters.Add(new ValueParameter<CheckedItemList<GoalParameter>>(GoalsParameterName));
     
    161160      return quality;
    162161    }
     162
     163    public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
     164      var zipped = individuals.Zip(qualities, (ind, qual) => new { Individual = ind, Quality = qual }).OrderBy(x => x.Quality);
     165      var best = Maximization ? zipped.Last() : zipped.First();
     166      var realVector = best.Individual.RealVector();
     167      const string resultName = "Best Solution";
     168
     169      var columnNames = new List<string>();
     170      foreach (var goal in ActiveGoals) {
     171        columnNames.Add(goal.Name);
     172        columnNames.Add(goal.Name + " (estimated)");
     173      }
     174      foreach (var input in ActiveInputs) {
     175        columnNames.Add(input.Name);
     176        columnNames.Add(input.Name + " (estimated)");
     177        columnNames.Add(input.Name + " (deviation)");
     178      }
     179
     180      var m = new DoubleMatrix(1, columnNames.Count) { ColumnNames = columnNames };
     181      int i = 0;
     182
     183      var goals = ActiveGoals.Zip(GetEstimatedGoalValues(realVector, round: true),
     184        (goal, value) => new { TargetValue = goal.Goal, EstimatedValue = value });
     185
     186      foreach (var goal in goals) {
     187        m[0, i] = goal.TargetValue;
     188        m[0, i + 1] = goal.EstimatedValue;
     189        i += 2;
     190      }
     191
     192      var inputs = ActiveInputs.Zip(realVector,
     193        (input, value) => new { ActualValue = input.Value, EstimatedValue = value });
     194
     195      foreach (var input in inputs) {
     196        m[0, i] = input.ActualValue;
     197        m[0, i + 1] = input.EstimatedValue;
     198        m[0, i + 2] = m[0, i] - m[0, i + 1];
     199        i += 3;
     200      }
     201
     202      if (!results.ContainsKey(resultName)) {
     203        results.Add(new Result(resultName, m));
     204      } else {
     205        results[resultName].Value = m;
     206      }
     207
     208      base.Analyze(individuals, qualities, results, random);
     209    }
     210
    163211    #region event handlers
    164 
    165212    private void RegisterEvents() {
    166213      ModelsParameter.Value.ItemsAdded += ModelCollection_ItemsChanged;
Note: See TracChangeset for help on using the changeset viewer.