Free cookie consent management tool by TermsFeed Policy Generator

source: branches/1614_GeneralizedQAP/HeuristicLab.OptimizationExpertSystem/3.3/Views/KnowledgeCenterAllinOneView.cs

Last change on this file was 16728, checked in by abeham, 6 years ago

#1614: updated to new persistence and .NET 4.6.1

File size: 25.6 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 System;
23using System.Collections.Generic;
24using System.ComponentModel;
25using System.Linq;
26using System.Text.RegularExpressions;
27using System.Windows.Forms;
28using System.Windows.Forms.DataVisualization.Charting;
29using HeuristicLab.Analysis;
30using HeuristicLab.Analysis.QualityAnalysis;
31using HeuristicLab.Clients.OKB.RunCreation;
32using HeuristicLab.Common;
33using HeuristicLab.Common.Resources;
34using HeuristicLab.Core;
35using HeuristicLab.Core.Views;
36using HeuristicLab.Data;
37using HeuristicLab.Data.Views;
38using HeuristicLab.MainForm;
39using HeuristicLab.MainForm.WindowsForms;
40using HeuristicLab.Optimization;
41using HeuristicLab.Optimization.Views;
42using HeuristicLab.OptimizationExpertSystem.Common;
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 = Progress.ShowOnControl(progressPanel, "");
224      progress.ProgressStateChanged += OkbDownloadProgressOnStateChanged;
225      Content.UpdateKnowledgeBaseAsync(progress);
226      progressPanel.Visible = true;
227      SetEnabledStateOfControls();
228    }
229
230    private void OkbDownloadProgressOnStateChanged(object sender, EventArgs e) {
231      if (InvokeRequired) { Invoke((Action<object, EventArgs>)OkbDownloadProgressOnStateChanged, sender, e); return; }
232      var progress = (IProgress)sender;
233      okbDownloadInProgress = progress.ProgressState == ProgressState.Started;
234      SetEnabledStateOfControls();
235      if (!okbDownloadInProgress) {
236        progressPanel.Visible = false;
237        progress.ProgressStateChanged -= OkbDownloadProgressOnStateChanged;
238      }
239    }
240
241    private async void AlgorithmStartButtonOnClick(object sender, EventArgs e) {
242      if (suggestedInstancesComboBox.SelectedIndex >= 0) {
243        solverResultsView.Content = await Content.StartAlgorithmAsync(suggestedInstancesComboBox.SelectedIndex);
244      }
245    }
246
247    private void AlgorithmCloneButtonOnClick(object sender, EventArgs e) {
248      if (suggestedInstancesComboBox.SelectedIndex >= 0)
249        MainFormManager.MainForm.ShowContent((IAlgorithm)Content.AlgorithmInstances[suggestedInstancesComboBox.SelectedIndex].Clone());
250    }
251
252    private void ProjectionComboBoxOnSelectedIndexChanged(object sender, EventArgs e) {
253      if (InvokeRequired) { Invoke((Action<object, EventArgs>)ProjectionComboBoxOnSelectedIndexChanged, sender, e); return; }
254      if (projectionComboBox.SelectedIndex < 0) return;
255      var projection = (string)projectionComboBox.SelectedItem;
256      var instancesSeries = instanceMapChart.Series["InstancesSeries"];
257      var currentInstanceSeries = instanceMapChart.Series["CurrentInstanceSeries"];
258
259      instancesSeries.Points.Clear();
260      currentInstanceSeries.Points.Clear();
261
262      foreach (var run in Content.ProblemInstances) {
263        var xKey = "Projection." + projection + ".X";
264        var yKey = "Projection." + projection + ".Y";
265        if (!run.Results.ContainsKey(xKey) || !run.Results.ContainsKey(yKey)
266          || !(run.Results[xKey] is Data.DoubleValue) || !(run.Results[yKey] is Data.DoubleValue)) continue;
267        var x = ((Data.DoubleValue)run.Results[xKey]).Value;
268        var y = ((Data.DoubleValue)run.Results[yKey]).Value;
269        var dataPoint = new DataPoint(x, y) {
270          Label = run.Name
271        };
272        if (!Content.IsCurrentInstance(run)) instancesSeries.Points.Add(dataPoint);
273        else currentInstanceSeries.Points.Add(dataPoint);
274      }
275    }
276
277    private void SuggestedInstancesComboBoxOnSelectedIndexChanged(object sender, EventArgs e) {
278      if (InvokeRequired) { Invoke((Action<object, EventArgs>)SuggestedInstancesComboBoxOnSelectedIndexChanged, sender, e); return; }
279      if (suggestedInstancesComboBox.SelectedIndex >= 0) {
280        var alg = Content.AlgorithmInstances[suggestedInstancesComboBox.SelectedIndex];
281        solverParametersView.Content = alg.Parameters;
282        var engineAlg = alg as EngineAlgorithm;
283        if (engineAlg != null) operatorGraphViewHost.Content = engineAlg.OperatorGraph;
284        else operatorGraphViewHost.Content = new Data.StringValue("Algorithm is not modeled as an operator graph.");
285      } else {
286        solverParametersView.Content = null;
287        operatorGraphViewHost.Content = null;
288      }
289      SetEnabledStateOfControls();
290    }
291
292    private void SimilarityComboBoxOnSelectedIndexChanged(object sender, EventArgs e) {
293      if (InvokeRequired) { Invoke((Action<object, EventArgs>)SimilarityComboBoxOnSelectedIndexChanged, sender, e); return; }
294      var calculator = (ISolutionSimilarityCalculator)similarityComboBox.SelectedItem;
295      if (calculator != null) {
296        calculator.SolutionVariableName = (string)solutionNameComboBox.SelectedItem;
297        calculator.QualityVariableName = Content.Problem.Problem.Evaluator.QualityParameter.ActualName;
298      }
299      UpdateSolutionDiversityAnalysis(calculator);
300      UpdateSolutionFdcAnalysis(calculator, fdcBetweenBestCheckBox.Checked);
301      UpdateSolutionLengthScaleAnalysis(calculator);
302      UpdateSolutionNetworkAnalysis(calculator);
303    }
304
305    private void FdcBetweenBestCheckBoxOnCheckedChanged(object sender, EventArgs e) {
306      if (InvokeRequired) { Invoke((Action<object, EventArgs>)FdcBetweenBestCheckBoxOnCheckedChanged, sender, e); return; }
307      UpdateSolutionFdcAnalysis((ISolutionSimilarityCalculator)similarityComboBox.SelectedItem, fdcBetweenBestCheckBox.Checked);
308    }
309
310    private void SolutionsNetworkChartOnMouseClick(object sender, MouseEventArgs e) {
311      var result = solutionsNetworkChart.HitTest(e.X, e.Y);
312      if (result.ChartElementType == ChartElementType.DataPoint) {
313        var point = (DataPoint)result.Object;
314        var solutionScope = point.Tag as IScope;
315        if (solutionScope == null || !Content.SolutionSeedingPool.Contains(solutionScope)) return;
316        Content.SolutionSeedingPool.SetItemCheckedState(solutionScope, !Content.SolutionSeedingPool.ItemChecked(solutionScope));
317      }
318    }
319    #endregion
320    #endregion
321
322    #region Control Configuration
323    private void UpdateSuggestedInstancesCombobox() {
324      var prevSelection = (IAlgorithm)suggestedInstancesComboBox.SelectedItem;
325      var prevNewIndex = -1;
326      suggestedInstancesComboBox.Items.Clear();
327      if (Content == null) return;
328
329      for (var i = 0; i < Content.AlgorithmInstances.Count; i++) {
330        suggestedInstancesComboBox.Items.Add(Content.AlgorithmInstances[i]);
331        if (prevSelection == null || Content.AlgorithmInstances[i].Name == prevSelection.Name)
332          prevNewIndex = prevSelection == null ? 0 : i;
333      }
334      if (prevNewIndex >= 0) {
335        suggestedInstancesComboBox.SelectedIndex = prevNewIndex;
336      }
337    }
338
339    private void UpdateSimilarityCalculators() {
340      var selected = (ISolutionSimilarityCalculator)(similarityComboBox.SelectedIndex >= 0 ? similarityComboBox.SelectedItem : null);
341      similarityComboBox.Items.Clear();
342
343      if (Content == null || Content.Problem == null) return;
344
345      foreach (var calc in Content.Problem.Operators.OfType<ISolutionSimilarityCalculator>()) {
346        similarityComboBox.Items.Add(calc);
347        if (selected != null && calc.ItemName == selected.ItemName) similarityComboBox.SelectedItem = calc;
348      }
349      if (selected == null && similarityComboBox.Items.Count > 0)
350        similarityComboBox.SelectedIndex = 0;
351    }
352
353    private void UpdateNamesComboboxes() {
354      var selectedSolutionName = solutionNameComboBox.SelectedIndex >= 0 ? (string)solutionNameComboBox.SelectedItem : string.Empty;
355
356      solutionNameComboBox.Items.Clear();
357      if (Content == null) return;
358      var solutionNames = Content.Problem.Solutions.Select(x => x.Solution).OfType<IScope>().SelectMany(x => x.Variables);
359
360      foreach (var sn in solutionNames.GroupBy(x => x.Name).OrderBy(x => x.Key)) {
361        solutionNameComboBox.Items.Add(sn.Key);
362        // either it was previously selected, or the variable value is defined in the HeuristicLab.Encodings sub-namespace
363        if (sn.Key == selectedSolutionName || (string.IsNullOrEmpty(selectedSolutionName) && sn.All(x => x.Value != null && x.Value.GetType().FullName.StartsWith("HeuristicLab.Encodings."))))
364          solutionNameComboBox.SelectedItem = sn.Key;
365      }
366    }
367   
368    private void UpdateProjectionComboBox() {
369      projectionComboBox.Items.Clear();
370      var projStrings = Content.ProblemInstances
371        .SelectMany(x => x.Results.Where(y => Regex.IsMatch(y.Key, "^Projection[.].*[.][XY]$")))
372        .Select(x => Regex.Match(x.Key, "Projection[.](?<g>.*)[.][XY]").Groups["g"].Value)
373        .Distinct();
374      foreach (var str in projStrings) {
375        projectionComboBox.Items.Add(str);
376      }
377    }
378    #endregion
379
380    #region Visualization
381    #region Solution Visualization
382    public void UpdateSolutionVisualization() {
383      if (InvokeRequired) { Invoke((Action)UpdateSolutionVisualization); return;  }
384      var qualityName = Content.Problem.Problem.Evaluator.QualityParameter.ActualName;
385      UpdateSolutionQualityAnalysis(qualityName);
386      if (similarityComboBox.SelectedIndex >= 0) {
387        var calculator = (ISolutionSimilarityCalculator)similarityComboBox.SelectedItem;
388        UpdateSolutionDiversityAnalysis(calculator);
389        UpdateSolutionFdcAnalysis(calculator, fdcBetweenBestCheckBox.Checked);
390        UpdateSolutionLengthScaleAnalysis(calculator);
391        UpdateSolutionNetworkAnalysis(calculator);
392      } else {
393        solutionsDiversityViewHost.Content = null;
394        solutionsFdcViewHost.Content = null;
395        solutionsLengthScaleViewHost.Content = null;
396        solutionsNetworkChart.Series.First().Points.Clear();
397      }
398    }
399    private void UpdateSolutionQualityAnalysis(string qualityName) {
400      var dt = solutionsQualityViewHost.Content as DataTable;
401      if (dt == null) {
402        dt = QualityDistributionAnalyzer.PrepareTable(qualityName);
403        dt.VisualProperties.Title = "Quality Distribution";
404        solutionsQualityViewHost.Content = dt;
405      }
406      QualityDistributionAnalyzer.UpdateTable(dt, GetSolutionScopes().Select(x => GetQuality(x, qualityName) ?? double.NaN).Where(x => !double.IsNaN(x)));
407    }
408
409    private void UpdateSolutionDiversityAnalysis(ISolutionSimilarityCalculator calculator) {
410      try {
411        solutionsDiversityViewHost.Content = null;
412        var solutionScopes = GetSolutionScopes();
413        var similarities = new double[solutionScopes.Count, solutionScopes.Count];
414        for (var i = 0; i < solutionScopes.Count; i++) {
415          for (var j = 0; j < solutionScopes.Count; j++)
416            similarities[i, j] = calculator.CalculateSolutionSimilarity(solutionScopes[i], solutionScopes[j]);
417        }
418        var hm = new HeatMap(similarities, "Solution Similarities", 0.0, 1.0);
419        solutionsDiversityViewHost.Content = hm;
420      } catch { }
421    }
422
423    private void UpdateSolutionFdcAnalysis(ISolutionSimilarityCalculator calculator, bool distanceToBest) {
424      try {
425        solutionsFdcViewHost.Content = null;
426        var solutionScopes = GetSolutionScopes();
427        var points = new List<Point2D<double>>();
428        if (distanceToBest) {
429          var maximization = ((IValueParameter<Data.BoolValue>)Content.Problem.MaximizationParameter).Value.Value;
430          var bestSolutions = (maximization ? solutionScopes.MaxItems(x => GetQuality(x, calculator.QualityVariableName) ?? double.NegativeInfinity)
431                                            : solutionScopes.MinItems(x => GetQuality(x, calculator.QualityVariableName) ?? double.PositiveInfinity)).ToList();
432          foreach (var solScope in solutionScopes.Except(bestSolutions)) {
433            var maxSimilarity = bestSolutions.Max(x => calculator.CalculateSolutionSimilarity(solScope, x));
434            var qDiff = (GetQuality(solScope, calculator.QualityVariableName) ?? double.NaN)
435                      - (GetQuality(bestSolutions[0], calculator.QualityVariableName) ?? double.NaN);
436            points.Add(new Point2D<double>(Math.Abs(qDiff), 1.0 - maxSimilarity));
437          }
438        } else {
439          for (int i = 0; i < solutionScopes.Count; i++) {
440            for (int j = 0; j < solutionScopes.Count; j++) {
441              if (i == j) continue;
442              var qDiff = (GetQuality(solutionScopes[i], calculator.QualityVariableName) ?? double.NaN)
443                          - (GetQuality(solutionScopes[j], calculator.QualityVariableName) ?? double.NaN);
444              if (double.IsNaN(qDiff)) continue;
445              points.Add(new Point2D<double>(Math.Abs(qDiff), 1.0 - calculator.CalculateSolutionSimilarity(solutionScopes[i], solutionScopes[j])));
446            }
447          }
448        }
449        var splot = new ScatterPlot("Fitness-Distance", "");
450        splot.VisualProperties.XAxisTitle = "Absolute Fitness Difference";
451        splot.VisualProperties.XAxisMinimumFixedValue = 0.0;
452        splot.VisualProperties.XAxisMinimumAuto = false;
453        splot.VisualProperties.YAxisTitle = "Solution Distance";
454        splot.VisualProperties.YAxisMinimumFixedValue = 0.0;
455        splot.VisualProperties.YAxisMinimumAuto = false;
456        splot.VisualProperties.YAxisMaximumFixedValue = 1.0;
457        splot.VisualProperties.YAxisMaximumAuto = false;
458        var row = new ScatterPlotDataRow("Fdc", "", points);
459        row.VisualProperties.PointSize = 7;
460        splot.Rows.Add(row);
461        solutionsFdcViewHost.Content = splot;
462      } catch { }
463    }
464
465    private void UpdateSolutionLengthScaleAnalysis(ISolutionSimilarityCalculator calculator) {
466      try {
467        solutionsLengthScaleViewHost.Content = null;
468        var dt = solutionsLengthScaleViewHost.Content as DataTable;
469        if (dt == null) {
470          dt = QualityDistributionAnalyzer.PrepareTable("Length Scale");
471          solutionsLengthScaleViewHost.Content = dt;
472        }
473        QualityDistributionAnalyzer.UpdateTable(dt, CalculateLengthScale(calculator));
474      } catch {
475        solutionsLengthScaleViewHost.Content = null;
476      }
477    }
478
479    private IEnumerable<double> CalculateLengthScale(ISolutionSimilarityCalculator calculator) {
480      var solutionScopes = GetSolutionScopes();
481      for (var i = 0; i < solutionScopes.Count; i++) {
482        for (var j = 0; j < solutionScopes.Count; j++) {
483          if (i == j) continue;
484          var sim = calculator.CalculateSolutionSimilarity(solutionScopes[i], solutionScopes[j]);
485          if (sim.IsAlmost(0)) continue;
486          var qDiff = (GetQuality(solutionScopes[i], calculator.QualityVariableName) ?? double.NaN)
487                    - (GetQuality(solutionScopes[j], calculator.QualityVariableName) ?? double.NaN);
488          if (!double.IsNaN(qDiff)) yield return Math.Abs(qDiff) / sim;
489        }
490      }
491    }
492
493    private void UpdateSolutionNetworkAnalysis(ISolutionSimilarityCalculator calculator) {
494      var series = solutionsNetworkChart.Series["SolutionSeries"];
495      var seedingSeries = solutionsNetworkChart.Series["SeedingSolutionSeries"];
496      try {
497        series.Points.Clear();
498        seedingSeries.Points.Clear();
499        var solutionScopes = GetSolutionScopes();
500        var dissimilarities = new DoubleMatrix(solutionScopes.Count, solutionScopes.Count);
501        for (var i = 0; i < solutionScopes.Count; i++) {
502          for (var j = 0; j < solutionScopes.Count; j++) {
503            if (i == j) continue;
504            dissimilarities[i, j] = 1.0 - calculator.CalculateSolutionSimilarity(solutionScopes[i], solutionScopes[j]);
505          }
506        }
507        var coords = MultidimensionalScaling.KruskalShepard(dissimilarities);
508        for (var i = 0; i < coords.Rows; i++) {
509          var quality = GetQuality(solutionScopes[i], calculator.QualityVariableName) ?? double.NaN;
510          var dataPoint = new DataPoint() {
511            Name = (i + 1).ToString(),
512            XValue = coords[i, 0],
513            YValues = new[] {coords[i, 1], quality},
514            Label = i + ": " + quality,
515            Tag = solutionScopes[i]
516          };
517          if (Content.SolutionSeedingPool.Contains(solutionScopes[i]) && Content.SolutionSeedingPool.ItemChecked(solutionScopes[i]))
518            seedingSeries.Points.Add(dataPoint);
519          else series.Points.Add(dataPoint);
520        }
521      } catch {
522        // problems in calculating the similarity
523        series.Points.Clear();
524        seedingSeries.Points.Clear();
525      }
526    }
527    #endregion
528    #endregion
529
530    private List<IScope> GetSolutionScopes() {
531      return Content.Problem.Solutions.Select(x => x.Solution).OfType<IScope>().ToList();
532    }
533
534    private double? GetQuality(IScope scope, string qualityName) {
535      IVariable v;
536      if (!scope.Variables.TryGetValue(qualityName, out v)) return null;
537      var dval = v.Value as Data.DoubleValue;
538      if (dval == null) return null;
539      return dval.Value;
540    }
541  }
542}
Note: See TracBrowser for help on using the repository browser.