Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/Views/KnowledgeCenterAllinOneView.cs @ 13774

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

#2457: worked on recommendation algorithms

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