Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystemView.cs @ 13720

Last change on this file since 13720 was 13720, checked in by abeham, 8 years ago

#2457: worked on expert-system

File size: 26.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using HeuristicLab.Analysis;
23using HeuristicLab.Analysis.QualityAnalysis;
24using HeuristicLab.Clients.OKB.RunCreation;
25using HeuristicLab.Common;
26using HeuristicLab.Common.Resources;
27using HeuristicLab.Core;
28using HeuristicLab.Core.Views;
29using HeuristicLab.Data;
30using HeuristicLab.Data.Views;
31using HeuristicLab.MainForm;
32using HeuristicLab.Optimization;
33using HeuristicLab.Optimization.Views;
34using HeuristicLab.OptimizationExpertSystem.Common;
35using System;
36using System.Collections.Generic;
37using System.ComponentModel;
38using System.Linq;
39using System.Text.RegularExpressions;
40using System.Windows.Forms;
41using System.Windows.Forms.DataVisualization.Charting;
42
43namespace HeuristicLab.OptimizationExpertSystem {
44  [View("Knowledge Center (all-in-one view)")]
45  [Content(typeof(ExpertSystem), IsDefaultView = true)]
46  public partial class ExpertSystemView : ItemView {
47    private EnumValueView<SeedingStrategyTypes> seedingStrategyView;
48    private CheckedItemListView<IScope> seedingSolutionsView;
49    protected virtual bool SuppressEvents { get; set; }
50    private bool okbDownloadInProgress;
51
52    public new ExpertSystem Content {
53      get { return (ExpertSystem)base.Content; }
54      set { base.Content = value; }
55    }
56
57    public ExpertSystemView() {
58      InitializeComponent();
59      // brings progress panel to front (it is not visible by default, but obstructs other elements in designer)
60      this.Controls.SetChildIndex(this.progressPanel, 0);
61      algorithmStartButton.Text = string.Empty;
62      algorithmStartButton.Image = VSImageLibrary.Play;
63      algorithmCloneButton.Text = string.Empty;
64      algorithmCloneButton.Image = VSImageLibrary.Clone;
65      refreshMapButton.Text = string.Empty;
66      refreshMapButton.Image = VSImageLibrary.Refresh;
67      seedingStrategyView = new EnumValueView<SeedingStrategyTypes>() {
68        Dock = DockStyle.Fill
69      };
70      seedingSolutionsView = new CheckedItemListView<IScope>() {
71        Dock = DockStyle.Fill
72      };
73      seedingStrategyPanel.Controls.Add(seedingStrategyView);
74      solutionSeedingTabPage.Controls.Add(seedingSolutionsView);
75    }
76
77    #region Event Registration
78    protected override void DeregisterContentEvents() {
79      Content.PropertyChanged -= ContentOnPropertyChanged;
80      Content.SuggestedInstances.CollectionReset -= SuggestedInstancesOnChanged;
81      Content.SuggestedInstances.ItemsAdded -= SuggestedInstancesOnChanged;
82      Content.SuggestedInstances.ItemsMoved -= SuggestedInstancesOnChanged;
83      Content.SuggestedInstances.ItemsRemoved -= SuggestedInstancesOnChanged;
84      Content.SuggestedInstances.ItemsReplaced -= SuggestedInstancesOnChanged;
85      Content.SolutionSeedingPool.CollectionReset -= SeedingPoolOnChanged;
86      Content.SolutionSeedingPool.ItemsAdded -= SeedingPoolOnChanged;
87      Content.SolutionSeedingPool.ItemsRemoved -= SeedingPoolOnChanged;
88      Content.SolutionSeedingPool.ItemsReplaced -= SeedingPoolOnChanged;
89      Content.SolutionSeedingPool.CheckedItemsChanged -= SeedingPoolOnChanged;
90      DeregisterProblemEvents(Content.Problem);
91      base.DeregisterContentEvents();
92    }
93
94    protected override void RegisterContentEvents() {
95      base.RegisterContentEvents();
96      Content.PropertyChanged += ContentOnPropertyChanged;
97      Content.SuggestedInstances.CollectionReset += SuggestedInstancesOnChanged;
98      Content.SuggestedInstances.ItemsAdded += SuggestedInstancesOnChanged;
99      Content.SuggestedInstances.ItemsMoved += SuggestedInstancesOnChanged;
100      Content.SuggestedInstances.ItemsRemoved += SuggestedInstancesOnChanged;
101      Content.SuggestedInstances.ItemsReplaced += SuggestedInstancesOnChanged;
102      Content.SolutionSeedingPool.CollectionReset += SeedingPoolOnChanged;
103      Content.SolutionSeedingPool.ItemsAdded += SeedingPoolOnChanged;
104      Content.SolutionSeedingPool.ItemsRemoved += SeedingPoolOnChanged;
105      Content.SolutionSeedingPool.ItemsReplaced += SeedingPoolOnChanged;
106      Content.SolutionSeedingPool.CheckedItemsChanged += SeedingPoolOnChanged;
107      RegisterProblemEvents(Content.Problem);
108    }
109
110    private void DeregisterProblemEvents(OKBProblem problem) {
111      if (problem == null) return;
112      problem.Solutions.ItemsAdded -= SolutionsOnChanged;
113      problem.Solutions.ItemsRemoved -= SolutionsOnChanged;
114      problem.Solutions.ItemsReplaced -= SolutionsOnChanged;
115      problem.Solutions.CollectionReset -= SolutionsOnChanged;
116      problem.ProblemChanged -= ContentOnProblemChanged;
117    }
118
119    private void RegisterProblemEvents(OKBProblem problem) {
120      if (problem == null) return;
121      problem.Solutions.ItemsAdded += SolutionsOnChanged;
122      problem.Solutions.ItemsRemoved += SolutionsOnChanged;
123      problem.Solutions.ItemsReplaced += SolutionsOnChanged;
124      problem.Solutions.CollectionReset += SolutionsOnChanged;
125      problem.ProblemChanged += ContentOnProblemChanged;
126    }
127    #endregion
128
129    protected override void OnContentChanged() {
130      base.OnContentChanged();
131      SuppressEvents = true;
132      okbDownloadInProgress = false;
133      try {
134        if (Content == null) {
135          maxEvaluationsTextBox.Text = String.Empty;
136          problemViewHost.Content = null;
137          solverParametersView.Content = null;
138          solverResultsView.Content = null;
139          runsView.Content = null;
140          kbViewHost.Content = null;
141          problemInstancesView.Content = null;
142          seedingStrategyView.Content = null;
143          seedingSolutionsView.Content = null;
144        } else {
145          maxEvaluationsTextBox.Text = Content.MaximumEvaluations.ToString();
146          problemViewHost.Content = Content.Problem;
147          runsView.Content = Content.Runs;
148          kbViewHost.ViewType = typeof(RunCollectionRLDView);
149          kbViewHost.Content = Content.KnowledgeBase;
150          problemInstancesView.Content = Content.ProblemInstances;
151          solverResultsView.Content = Content.CurrentResult;
152          seedingStrategyView.Content = Content.SeedingStrategy;
153          seedingSolutionsView.Content = Content.SolutionSeedingPool;
154        }
155      } finally { SuppressEvents = false; }
156      UpdateSuggestedInstancesCombobox();
157      UpdateSimilarityCalculators();
158      UpdateNamesComboboxes();
159    }
160
161    protected override void SetEnabledStateOfControls() {
162      base.SetEnabledStateOfControls();
163      maxEvaluationsTextBox.Enabled = Content != null && !ReadOnly && !Locked;
164      problemViewHost.Enabled = Content != null && !ReadOnly && !Locked && !okbDownloadInProgress;
165      suggestedInstancesComboBox.Enabled = Content != null && !ReadOnly && !Locked && !okbDownloadInProgress;
166      algorithmStartButton.Enabled = Content != null && !ReadOnly && !Locked && suggestedInstancesComboBox.SelectedIndex >= 0;
167      algorithmCloneButton.Enabled = Content != null && !ReadOnly && !Locked && suggestedInstancesComboBox.SelectedIndex >= 0;
168      runsView.Enabled = Content != null;
169      kbViewHost.Enabled = Content != null && !okbDownloadInProgress;
170      problemInstancesView.Enabled = Content != null && !okbDownloadInProgress;
171      refreshMapButton.Enabled = Content != null;
172      okbDownloadButton.Enabled = Content != null && Content.Problem != null && Content.Problem.ProblemId >= 0 && !ReadOnly && !Locked && !okbDownloadInProgress;
173    }
174
175    #region Event Handlers
176    #region Content events
177    private void ContentOnProblemChanged(object sender, EventArgs eventArgs) {
178      UpdateSuggestedInstancesCombobox();
179      UpdateSimilarityCalculators();
180      SetEnabledStateOfControls();
181    }
182
183    private void ContentOnPropertyChanged(object sender, PropertyChangedEventArgs e) {
184      if (InvokeRequired) {
185        Invoke((Action<object, PropertyChangedEventArgs>)ContentOnPropertyChanged, sender, e);
186        return;
187      }
188      SuppressEvents = true;
189      try {
190        switch (e.PropertyName) {
191          case "KnowledgeBase": kbViewHost.Content = Content.KnowledgeBase; break;
192          case "MaximumEvaluations": maxEvaluationsTextBox.Text = Content.MaximumEvaluations.ToString(); break;
193          case "Problem":
194            DeregisterProblemEvents(problemViewHost.Content as OKBProblem);
195            problemViewHost.Content = Content.Problem;
196            RegisterProblemEvents(Content.Problem);
197            UpdateNamesComboboxes();
198            break;
199          case "ProblemInstances": problemInstancesView.Content = Content.ProblemInstances; break;
200          case "CurrentResult": solverResultsView.Content = Content.CurrentResult; break;
201        }
202      } finally { SuppressEvents = false; }
203      SetEnabledStateOfControls();
204    }
205
206    private void SuggestedInstancesOnChanged(object sender, EventArgs e) {
207      UpdateSuggestedInstancesCombobox();
208    }
209
210    private void SeedingPoolOnChanged(object sender, EventArgs e) {
211      UpdateSolutionVisualization();
212    }
213
214    private void SolutionsOnChanged(object sender, EventArgs e) {
215      UpdateNamesComboboxes();
216      UpdateSolutionVisualization();
217    }
218    #endregion
219
220    #region Control events
221    private void MaxEvaluationsTextBoxOnValidating(object sender, CancelEventArgs e) {
222      if (SuppressEvents) return;
223      if (InvokeRequired) {
224        Invoke((Action<object, CancelEventArgs>)MaxEvaluationsTextBoxOnValidating, sender, e);
225        return;
226      }
227      int value;
228      if (!int.TryParse(maxEvaluationsTextBox.Text, out value)) {
229        e.Cancel = !maxEvaluationsTextBox.ReadOnly && maxEvaluationsTextBox.Enabled;
230        //errorProvider.SetError(maxEvaluationsTextBox, "Please enter a valid integer number.");
231      } else {
232        Content.MaximumEvaluations = value;
233        e.Cancel = false;
234        //errorProvider.SetError(maxEvaluationsTextBox, null);
235      }
236    }
237
238    private void RefreshMapButtonOnClick(object sender, EventArgs e) {
239      UpdateProjectionComboBox();
240    }
241
242    private void OkbDownloadButtonOnClick(object sender, EventArgs e) {
243      if (Content.Problem.ProblemId == -1) {
244        MessageBox.Show("Please select a problem instance first.");
245        return;
246      }
247      var progress = new Progress();
248      progress.ProgressStateChanged += OkbDownloadProgressOnStateChanged;
249      Content.UpdateKnowledgeBaseAsync(progress);
250      MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().AddOperationProgressToView(progressPanel, progress);
251      progressPanel.Visible = true;
252      SetEnabledStateOfControls();
253    }
254
255    private void OkbDownloadProgressOnStateChanged(object sender, EventArgs e) {
256      if (InvokeRequired) { Invoke((Action<object, EventArgs>)OkbDownloadProgressOnStateChanged, sender, e); return; }
257      var progress = (IProgress)sender;
258      okbDownloadInProgress = progress.ProgressState == ProgressState.Started;
259      SetEnabledStateOfControls();
260      if (!okbDownloadInProgress) {
261        progressPanel.Visible = false;
262        progress.ProgressStateChanged -= OkbDownloadProgressOnStateChanged;
263      }
264    }
265
266    private void AlgorithmStartButtonOnClick(object sender, EventArgs e) {
267      if (suggestedInstancesComboBox.SelectedIndex >= 0)
268        Content.StartAlgorithmAsync(suggestedInstancesComboBox.SelectedIndex);
269    }
270
271    private void AlgorithmCloneButtonOnClick(object sender, EventArgs e) {
272      if (suggestedInstancesComboBox.SelectedIndex >= 0)
273        MainFormManager.MainForm.ShowContent((IAlgorithm)Content.SuggestedInstances[suggestedInstancesComboBox.SelectedIndex].Clone());
274    }
275
276    private void ProjectionComboBoxOnSelectedIndexChanged(object sender, EventArgs e) {
277      if (InvokeRequired) { Invoke((Action<object, EventArgs>)ProjectionComboBoxOnSelectedIndexChanged, sender, e); return; }
278      if (projectionComboBox.SelectedIndex < 0) return;
279      var projection = (string)projectionComboBox.SelectedItem;
280      var instancesSeries = instanceMapChart.Series["InstancesSeries"];
281      var currentInstanceSeries = instanceMapChart.Series["CurrentInstanceSeries"];
282
283      instancesSeries.Points.Clear();
284      currentInstanceSeries.Points.Clear();
285
286      foreach (var run in Content.ProblemInstances) {
287        var xKey = "Projection." + projection + ".X";
288        var yKey = "Projection." + projection + ".Y";
289        if (!run.Results.ContainsKey(xKey) || !run.Results.ContainsKey(yKey)
290          || !(run.Results[xKey] is Data.DoubleValue) || !(run.Results[yKey] is Data.DoubleValue)) continue;
291        var x = ((Data.DoubleValue)run.Results[xKey]).Value;
292        var y = ((Data.DoubleValue)run.Results[yKey]).Value;
293        var dataPoint = new DataPoint(x, y) {
294          Label = run.Name
295        };
296        instancesSeries.Points.Add(dataPoint);
297      }
298
299      var curPoint = Content.ProjectCurrentInstance(projection);
300      if (curPoint != null) {
301        var dp = new DataPoint(curPoint.Item1, curPoint.Item2) {
302          Label = Content.Problem.Problem.Name
303        };
304        currentInstanceSeries.Points.Add(dp);
305      }
306    }
307
308    private void SuggestedInstancesComboBoxOnSelectedIndexChanged(object sender, EventArgs e) {
309      if (InvokeRequired) { Invoke((Action<object, EventArgs>)SuggestedInstancesComboBoxOnSelectedIndexChanged, sender, e); return; }
310      if (suggestedInstancesComboBox.SelectedIndex >= 0) {
311        var alg = Content.SuggestedInstances[suggestedInstancesComboBox.SelectedIndex];
312        solverParametersView.Content = alg.Parameters;
313        var engineAlg = alg as EngineAlgorithm;
314        if (engineAlg != null) operatorGraphViewHost.Content = engineAlg.OperatorGraph;
315        else operatorGraphViewHost.Content = new Data.StringValue("Algorithm is not modeled as an operator graph.");
316      } else {
317        solverParametersView.Content = null;
318        operatorGraphViewHost.Content = null;
319      }
320      SetEnabledStateOfControls();
321    }
322
323    private void SimilarityComboBoxOnSelectedIndexChanged(object sender, EventArgs e) {
324      if (InvokeRequired) { Invoke((Action<object, EventArgs>)SimilarityComboBoxOnSelectedIndexChanged, sender, e); return; }
325      var calculator = (ISolutionSimilarityCalculator)similarityComboBox.SelectedItem;
326      if (calculator != null) {
327        calculator.SolutionVariableName = (string)solutionNameComboBox.SelectedItem;
328        calculator.QualityVariableName = Content.Problem.Problem.Evaluator.QualityParameter.ActualName;
329      }
330      UpdateSolutionDiversityAnalysis(calculator);
331      UpdateSolutionFdcAnalysis(calculator, fdcBetweenBestCheckBox.Checked);
332      UpdateSolutionLengthScaleAnalysis(calculator);
333      UpdateSolutionNetworkAnalysis(calculator);
334    }
335
336    private void FdcBetweenBestCheckBoxOnCheckedChanged(object sender, EventArgs e) {
337      if (InvokeRequired) { Invoke((Action<object, EventArgs>)FdcBetweenBestCheckBoxOnCheckedChanged, sender, e); return; }
338      UpdateSolutionFdcAnalysis((ISolutionSimilarityCalculator)similarityComboBox.SelectedItem, fdcBetweenBestCheckBox.Checked);
339    }
340
341    private void SolutionsNetworkChartOnMouseClick(object sender, MouseEventArgs e) {
342      var result = solutionsNetworkChart.HitTest(e.X, e.Y);
343      if (result.ChartElementType == ChartElementType.DataPoint) {
344        var point = (DataPoint)result.Object;
345        var solutionScope = point.Tag as IScope;
346        if (solutionScope == null || !Content.SolutionSeedingPool.Contains(solutionScope)) return;
347        Content.SolutionSeedingPool.SetItemCheckedState(solutionScope, !Content.SolutionSeedingPool.ItemChecked(solutionScope));
348      }
349    }
350    #endregion
351    #endregion
352
353    #region Control Configuration
354    private void UpdateSuggestedInstancesCombobox() {
355      var prevSelection = (IAlgorithm)suggestedInstancesComboBox.SelectedItem;
356      var prevNewIndex = -1;
357      suggestedInstancesComboBox.Items.Clear();
358      if (Content == null) return;
359
360      for (var i = 0; i < Content.SuggestedInstances.Count; i++) {
361        suggestedInstancesComboBox.Items.Add(Content.SuggestedInstances[i]);
362        if (prevSelection == null || Content.SuggestedInstances[i].Name == prevSelection.Name)
363          prevNewIndex = prevSelection == null ? 0 : i;
364      }
365      if (prevNewIndex >= 0) {
366        suggestedInstancesComboBox.SelectedIndex = prevNewIndex;
367      }
368    }
369
370    private void UpdateSimilarityCalculators() {
371      var selected = (ISolutionSimilarityCalculator)(similarityComboBox.SelectedIndex >= 0 ? similarityComboBox.SelectedItem : null);
372      similarityComboBox.Items.Clear();
373
374      if (Content == null || Content.Problem == null) return;
375
376      foreach (var calc in Content.Problem.Operators.OfType<ISolutionSimilarityCalculator>()) {
377        similarityComboBox.Items.Add(calc);
378        if (selected != null && calc.ItemName == selected.ItemName) similarityComboBox.SelectedItem = calc;
379      }
380      if (selected == null && similarityComboBox.Items.Count > 0)
381        similarityComboBox.SelectedIndex = 0;
382    }
383
384    private void UpdateNamesComboboxes() {
385      var selectedSolutionName = solutionNameComboBox.SelectedIndex >= 0 ? (string)solutionNameComboBox.SelectedItem : string.Empty;
386
387      solutionNameComboBox.Items.Clear();
388      if (Content == null) return;
389      var solutionNames = Content.Problem.Solutions.Select(x => x.Solution).OfType<IScope>().SelectMany(x => x.Variables);
390
391      foreach (var sn in solutionNames.GroupBy(x => x.Name).OrderBy(x => x.Key)) {
392        solutionNameComboBox.Items.Add(sn.Key);
393        // either it was previously selected, or the variable value is defined in the HeuristicLab.Encodings sub-namespace
394        if (sn.Key == selectedSolutionName || (string.IsNullOrEmpty(selectedSolutionName) && sn.All(x => x.Value != null && x.Value.GetType().FullName.StartsWith("HeuristicLab.Encodings."))))
395          solutionNameComboBox.SelectedItem = sn.Key;
396      }
397    }
398   
399    private void UpdateProjectionComboBox() {
400      projectionComboBox.Items.Clear();
401      var projStrings = Content.ProblemInstances
402        .SelectMany(x => x.Results.Where(y => Regex.IsMatch(y.Key, "^Projection[.].*[.][XY]$")))
403        .Select(x => Regex.Match(x.Key, "Projection[.](?<g>.*)[.][XY]").Groups["g"].Value)
404        .Distinct();
405      foreach (var str in projStrings) {
406        projectionComboBox.Items.Add(str);
407      }
408    }
409    #endregion
410
411    #region Visualization
412    #region Solution Visualization
413    public void UpdateSolutionVisualization() {
414      if (InvokeRequired) { Invoke((Action)UpdateSolutionVisualization); return;  }
415      var qualityName = Content.Problem.Problem.Evaluator.QualityParameter.ActualName;
416      UpdateSolutionQualityAnalysis(qualityName);
417      if (similarityComboBox.SelectedIndex >= 0) {
418        var calculator = (ISolutionSimilarityCalculator)similarityComboBox.SelectedItem;
419        UpdateSolutionDiversityAnalysis(calculator);
420        UpdateSolutionFdcAnalysis(calculator, fdcBetweenBestCheckBox.Checked);
421        UpdateSolutionLengthScaleAnalysis(calculator);
422        UpdateSolutionNetworkAnalysis(calculator);
423      } else {
424        solutionsDiversityViewHost.Content = null;
425        solutionsFdcViewHost.Content = null;
426        solutionsLengthScaleViewHost.Content = null;
427        solutionsNetworkChart.Series.First().Points.Clear();
428      }
429    }
430    private void UpdateSolutionQualityAnalysis(string qualityName) {
431      var dt = solutionsQualityViewHost.Content as DataTable;
432      if (dt == null) {
433        dt = QualityDistributionAnalyzer.PrepareTable(qualityName);
434        dt.VisualProperties.Title = "Quality Distribution";
435        solutionsQualityViewHost.Content = dt;
436      }
437      QualityDistributionAnalyzer.UpdateTable(dt, GetSolutionScopes().Select(x => GetQuality(x, qualityName) ?? double.NaN).Where(x => !double.IsNaN(x)));
438    }
439
440    private void UpdateSolutionDiversityAnalysis(ISolutionSimilarityCalculator calculator) {
441      try {
442        solutionsDiversityViewHost.Content = null;
443        var solutionScopes = GetSolutionScopes();
444        var similarities = new double[solutionScopes.Count, solutionScopes.Count];
445        for (var i = 0; i < solutionScopes.Count; i++) {
446          for (var j = 0; j < solutionScopes.Count; j++)
447            similarities[i, j] = calculator.CalculateSolutionSimilarity(solutionScopes[i], solutionScopes[j]);
448        }
449        var hm = new HeatMap(similarities, "Solution Similarities", 0.0, 1.0);
450        solutionsDiversityViewHost.Content = hm;
451      } catch { }
452    }
453
454    private void UpdateSolutionFdcAnalysis(ISolutionSimilarityCalculator calculator, bool distanceToBest) {
455      try {
456        solutionsFdcViewHost.Content = null;
457        var solutionScopes = GetSolutionScopes();
458        var points = new List<Point2D<double>>();
459        if (distanceToBest) {
460          var maximization = ((IValueParameter<Data.BoolValue>)Content.Problem.MaximizationParameter).Value.Value;
461          var bestSolutions = (maximization ? solutionScopes.MaxItems(x => GetQuality(x, calculator.QualityVariableName) ?? double.NegativeInfinity)
462                                            : solutionScopes.MinItems(x => GetQuality(x, calculator.QualityVariableName) ?? double.PositiveInfinity)).ToList();
463          foreach (var solScope in solutionScopes.Except(bestSolutions)) {
464            var maxSimilarity = bestSolutions.Max(x => calculator.CalculateSolutionSimilarity(solScope, x));
465            var qDiff = (GetQuality(solScope, calculator.QualityVariableName) ?? double.NaN)
466                      - (GetQuality(bestSolutions[0], calculator.QualityVariableName) ?? double.NaN);
467            points.Add(new Point2D<double>(Math.Abs(qDiff), 1.0 - maxSimilarity));
468          }
469        } else {
470          for (int i = 0; i < solutionScopes.Count; i++) {
471            for (int j = 0; j < solutionScopes.Count; j++) {
472              if (i == j) continue;
473              var qDiff = (GetQuality(solutionScopes[i], calculator.QualityVariableName) ?? double.NaN)
474                          - (GetQuality(solutionScopes[j], calculator.QualityVariableName) ?? double.NaN);
475              if (double.IsNaN(qDiff)) continue;
476              points.Add(new Point2D<double>(Math.Abs(qDiff), 1.0 - calculator.CalculateSolutionSimilarity(solutionScopes[i], solutionScopes[j])));
477            }
478          }
479        }
480        var splot = new ScatterPlot("Fitness-Distance", "");
481        splot.VisualProperties.XAxisTitle = "Absolute Fitness Difference";
482        splot.VisualProperties.XAxisMinimumFixedValue = 0.0;
483        splot.VisualProperties.XAxisMinimumAuto = false;
484        splot.VisualProperties.YAxisTitle = "Solution Distance";
485        splot.VisualProperties.YAxisMinimumFixedValue = 0.0;
486        splot.VisualProperties.YAxisMinimumAuto = false;
487        splot.VisualProperties.YAxisMaximumFixedValue = 1.0;
488        splot.VisualProperties.YAxisMaximumAuto = false;
489        var row = new ScatterPlotDataRow("Fdc", "", points);
490        row.VisualProperties.PointSize = 7;
491        splot.Rows.Add(row);
492        solutionsFdcViewHost.Content = splot;
493      } catch { }
494    }
495
496    private void UpdateSolutionLengthScaleAnalysis(ISolutionSimilarityCalculator calculator) {
497      try {
498        solutionsLengthScaleViewHost.Content = null;
499        var dt = solutionsLengthScaleViewHost.Content as DataTable;
500        if (dt == null) {
501          dt = QualityDistributionAnalyzer.PrepareTable("Length Scale");
502          solutionsLengthScaleViewHost.Content = dt;
503        }
504        QualityDistributionAnalyzer.UpdateTable(dt, CalculateLengthScale(calculator));
505      } catch {
506        solutionsLengthScaleViewHost.Content = null;
507      }
508    }
509
510    private IEnumerable<double> CalculateLengthScale(ISolutionSimilarityCalculator calculator) {
511      var solutionScopes = GetSolutionScopes();
512      for (var i = 0; i < solutionScopes.Count; i++) {
513        for (var j = 0; j < solutionScopes.Count; j++) {
514          if (i == j) continue;
515          var sim = calculator.CalculateSolutionSimilarity(solutionScopes[i], solutionScopes[j]);
516          if (sim.IsAlmost(0)) continue;
517          var qDiff = (GetQuality(solutionScopes[i], calculator.QualityVariableName) ?? double.NaN)
518                    - (GetQuality(solutionScopes[j], calculator.QualityVariableName) ?? double.NaN);
519          if (!double.IsNaN(qDiff)) yield return Math.Abs(qDiff) / sim;
520        }
521      }
522    }
523
524    private void UpdateSolutionNetworkAnalysis(ISolutionSimilarityCalculator calculator) {
525      var series = solutionsNetworkChart.Series["SolutionSeries"];
526      var seedingSeries = solutionsNetworkChart.Series["SeedingSolutionSeries"];
527      try {
528        series.Points.Clear();
529        seedingSeries.Points.Clear();
530        var solutionScopes = GetSolutionScopes();
531        var dissimilarities = new DoubleMatrix(solutionScopes.Count, solutionScopes.Count);
532        for (var i = 0; i < solutionScopes.Count; i++) {
533          for (var j = 0; j < solutionScopes.Count; j++) {
534            if (i == j) continue;
535            dissimilarities[i, j] = 1.0 - calculator.CalculateSolutionSimilarity(solutionScopes[i], solutionScopes[j]);
536          }
537        }
538        var coords = MultidimensionalScaling.KruskalShepard(dissimilarities);
539        for (var i = 0; i < coords.Rows; i++) {
540          var quality = GetQuality(solutionScopes[i], calculator.QualityVariableName) ?? double.NaN;
541          var dataPoint = new DataPoint() {
542            Name = (i + 1).ToString(),
543            XValue = coords[i, 0],
544            YValues = new[] {coords[i, 1], quality},
545            Label = i + ": " + quality,
546            Tag = solutionScopes[i]
547          };
548          if (Content.SolutionSeedingPool.Contains(solutionScopes[i]) && Content.SolutionSeedingPool.ItemChecked(solutionScopes[i]))
549            seedingSeries.Points.Add(dataPoint);
550          else series.Points.Add(dataPoint);
551        }
552      } catch {
553        // problems in calculating the similarity
554        series.Points.Clear();
555        seedingSeries.Points.Clear();
556      }
557    }
558    #endregion
559    #endregion
560
561    private List<IScope> GetSolutionScopes() {
562      return Content.Problem.Solutions.Select(x => x.Solution).OfType<IScope>().ToList();
563    }
564
565    private double? GetQuality(IScope scope, string qualityName) {
566      IVariable v;
567      if (!scope.Variables.TryGetValue(qualityName, out v)) return null;
568      var dval = v.Value as Data.DoubleValue;
569      if (dval == null) return null;
570      return dval.Value;
571    }
572  }
573}
Note: See TracBrowser for help on using the repository browser.