Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2457: worked on expert system

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