source: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/LineageExplorerView.cs @ 9963

Last change on this file since 9963 was 9963, checked in by bburlacu, 8 years ago

#1772: Merged changes from the trunk and other branches. Added new ExtendedSymbolicExpressionTreeCanvas control for the visual exploration of tree genealogies. Reorganized some files and folders.

File size: 11.8 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Drawing;
4using System.Linq;
5using System.Windows.Forms;
6using HeuristicLab.Common;
7using HeuristicLab.Core.Views;
8using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
9using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
10using HeuristicLab.MainForm;
11using HeuristicLab.Problems.DataAnalysis.Symbolic;
12
13namespace HeuristicLab.EvolutionaryTracking.Views {
14  [View("LineageExplorerView")]
15  [Content(typeof(LineageExplorer), IsDefaultView = false)]
16  public sealed partial class LineageExplorerView : ItemView {
17    private Dictionary<TreeNode, ISymbolicExpressionTree> treeMap;
18    private List<SymbolicExpressionTreeGenealogyGraphNode> lineage;
19
20    private Dictionary<ISymbolicExpressionTree, Dictionary<ISymbolicExpressionTreeNode, double>> fragmentFrequencies;
21
22    public new LineageExplorer Content {
23      get { return (LineageExplorer)base.Content; }
24      set { base.Content = value; }
25    }
26
27    public LineageExplorerView() {
28      InitializeComponent();
29      treeMap = new Dictionary<TreeNode, ISymbolicExpressionTree>();
30    }
31
32    protected override void DeregisterContentEvents() {
33      // TODO: Deregister your event handlers here
34      base.DeregisterContentEvents();
35    }
36
37    protected override void RegisterContentEvents() {
38      base.RegisterContentEvents();
39      // TODO: Register your event handlers here
40    }
41
42    #region Event Handlers (Content)
43    // TODO: Put event handlers of the content here
44    #endregion
45
46    protected override void OnContentChanged() {
47      base.OnContentChanged();
48      if (Content == null) {
49      } else {
50        var tuples = Content.Trees.OrderByDescending(x => x.Item2).ToList();
51        scopeListTreeView.Nodes.AddRange(tuples.Select(x => new TreeNode(x.Item2.ToString())).ToArray());
52
53        for (int i = 0; i != tuples.Count; ++i) {
54          treeMap.Add(scopeListTreeView.Nodes[i], tuples[i].Item1);
55          double quality = tuples[i].Item2;
56          int colorIndex = (int)Math.Floor(quality * ColorGradient.Colors.Count);
57          var color = ColorGradient.Colors[colorIndex];
58          scopeListTreeView.Nodes[i].ForeColor = color;
59        }
60      }
61    }
62
63    protected override void SetEnabledStateOfControls() {
64      base.SetEnabledStateOfControls();
65      // TODO: Enable or disable controls based on whether the content is null or the view is set readonly
66    }
67
68    private void scopeListTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
69      var treeNode = scopeListTreeView.SelectedNode;
70      var symbExprTree = treeMap[treeNode];
71
72      fragmentFrequencies = fragmentFrequencies ?? new Dictionary<ISymbolicExpressionTree, Dictionary<ISymbolicExpressionTreeNode, double>>();
73
74      if (fragmentFrequencies.ContainsKey(symbExprTree) && false) {
75        // colorize tree nodes according to fragment frequencies
76        symbolicExpressionTreeChart.SuspendRepaint = true;
77        var frequencies = fragmentFrequencies[symbExprTree];
78
79        foreach (var node in symbExprTree.IterateNodesBreadth()) {
80          double freq = frequencies[node];
81          int index = (int)Math.Floor(freq * ColorGradient.Colors.Count / scopeListTreeView.GetNodeCount(false));
82          if (index == ColorGradient.Colors.Count) index--;
83          var color = ColorGradient.Colors[index];
84          var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
85          visualNode.FillColor = Color.FromArgb(200, color);
86        }
87        symbolicExpressionTreeChart.SuspendRepaint = false;
88        symbolicExpressionTreeChart.Repaint();
89      }
90      // highlight crossover fragment
91      HighlightFragment(symbExprTree);
92
93      var graphNode = Content.GenealogyGraph.GetGraphNodes(symbExprTree).Last();
94      lineage = lineage ?? new List<SymbolicExpressionTreeGenealogyGraphNode>();
95      lineage.Clear();
96      lineage.Add(graphNode);
97
98      var gn = graphNode;
99      while (gn.InEdges != null && gn.InEdges.Count != 0) {
100        gn = (SymbolicExpressionTreeGenealogyGraphNode)gn.InEdges[0].Source;
101        lineage.Add(gn);
102      }
103      lineage.Reverse(); // increasing order by generation
104
105      // update the righthand side tree view
106      qualityImprovementTreeView.Nodes.Clear();
107      for (int i = 0; i != lineage.Count; ++i) {
108        var node = new TreeNode(string.Format("Generation {0}", lineage[i].Rank));
109        qualityImprovementTreeView.Nodes.Add(node);
110        var quality = lineage[i].Quality;
111        int colorIndex = (int)Math.Floor(quality * ColorGradient.Colors.Count);
112        var color = ColorGradient.Colors[colorIndex];
113        node.ForeColor = color;
114      }
115    }
116
117    /// <summary>
118    /// Given a symbolic expression tree, find the corresponding vertex in the genealogy graph, and highlight the fragment
119    /// that is saved as a data member in the incoming arc from the parent in the previous generation
120    /// </summary>
121    /// <param name="symbExprTree"></param>
122    private void HighlightFragment(ISymbolicExpressionTree symbExprTree) {
123      // update the symbolic expression tree chart with the new selected tree:
124      symbolicExpressionTreeChart.SuspendRepaint = true;
125      symbolicExpressionTreeChart.Tree = symbExprTree;
126      var matchingNodes = Content.GenealogyGraph.GetGraphNodes(symbExprTree);
127      SymbolicExpressionTreeGenealogyGraphNode graphNode = matchingNodes.First();
128      if (graphNode.InEdges == null) {
129        symbolicExpressionTreeChart.SuspendRepaint = false;
130        symbolicExpressionTreeChart.Repaint();
131        return;
132      }
133      var fragment = graphNode.InEdges.Count == 1 ? (IFragment)graphNode.InEdges[0].Data : (IFragment)graphNode.InEdges[1].Data;
134      if (fragment.Root == null) {
135        symbolicExpressionTreeChart.SuspendRepaint = false;
136        symbolicExpressionTreeChart.Repaint();
137        return;
138      }
139      foreach (var node in fragment.Root.IterateNodesBreadth()) {
140        var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
141        visualNode.LineColor = Color.DodgerBlue;
142      }
143      symbolicExpressionTreeChart.SuspendRepaint = false;
144      symbolicExpressionTreeChart.Repaint();
145    }
146
147    private void qualityImprovementTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
148      var tree = lineage[qualityImprovementTreeView.SelectedNode.Index].SymbolicExpressionTree;
149      HighlightFragment(tree);
150    }
151
152    private void calculateFragmentFrequencyButton_Click(object sender, EventArgs e) {
153      // the individual can occur multiple times in the graph if it is(was) elite. we take the first occurence.
154      var graphNode = Content.GenealogyGraph.GetGraphNodes(symbolicExpressionTreeChart.Tree).First();
155      var trees = Content.GenealogyGraph.Nodes.Where(x => x.Rank.IsAlmost(graphNode.Rank)).Select(x => x.SymbolicExpressionTree).ToList();
156
157      var fragments = graphNode.SymbolicExpressionTree.IterateNodesBreadth().Select(n => new Fragment { Root = n });
158
159      var similarityComparer = new SymbolicExpressionTreeNodeSimilarityComparer {
160        MatchConstantValues = false,
161        MatchVariableNames = true,
162        MatchVariableWeights = false
163      };
164
165      var canonicalSorter = new SymbolicExpressionTreeCanonicalSorter();
166
167      fragmentFrequencies = fragmentFrequencies ?? new Dictionary<ISymbolicExpressionTree, Dictionary<ISymbolicExpressionTreeNode, double>>();
168
169      if (!fragmentFrequencies.ContainsKey(graphNode.SymbolicExpressionTree)) {
170        fragmentFrequencies[graphNode.SymbolicExpressionTree] = new Dictionary<ISymbolicExpressionTreeNode, double>();
171      }
172
173      fragmentFrequencies[graphNode.SymbolicExpressionTree].Clear();
174
175      symbolicExpressionTreeChart.SuspendRepaint = true;
176      foreach (var f in fragments) {
177        double freq = 0;
178
179        foreach (var t in trees) {
180          if (t.Root.ContainsFragment(f, similarityComparer)) ++freq;
181        }
182
183        fragmentFrequencies[graphNode.SymbolicExpressionTree].Add(f.Root, freq);
184
185        // colorize tree nodes according to fragment frequencies
186        int index = (int)Math.Floor(freq * ColorGradient.Colors.Count / trees.Count);
187        if (index == ColorGradient.Colors.Count) index--;
188        var color = ColorGradient.Colors[index];
189        foreach (var node in f.Root.IterateNodesBreadth()) {
190          var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
191          visualNode.FillColor = Color.FromArgb(200, color);
192        }
193      }
194
195      symbolicExpressionTreeChart.SuspendRepaint = false;
196      symbolicExpressionTreeChart.Repaint();
197    }
198
199    private void symbolicExpressionTreeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) {
200    }
201
202    private void showGenealogyButton_Click(object sender, EventArgs e) {
203      var tree = symbolicExpressionTreeChart.Tree;
204      if (tree == null) return;
205      var graphNode = Content.GenealogyGraph.GetGraphNodes(tree).First();
206
207      var graph = new SymbolicExpressionTreeGenealogyGraph();
208      var ancestors = graphNode.Ancestors();
209      foreach (var ancestorNode in ancestors) {
210        graph.AddNode(ancestorNode);
211      }
212      using (var dialog = new GenealogyGraphDialog { Graph = graph }) {
213        dialog.ShowDialog(this);
214      }
215    }
216
217    private void button1_Click(object sender, EventArgs e) {
218      using (var dialog = new FrequentFragmentsDialog()) {
219        var panel = new Panel { Dock = DockStyle.Left, Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom };
220
221        panel.Controls.Add(new SymbolicExpressionTreeChart() { Tree = treeMap.Values.First() });
222        panel.Controls.Add(new Label { Text = "Fragment frequency." });
223
224        dialog.fragmentsPanel.Controls.Add(panel);
225
226        dialog.ShowDialog(this);
227      }
228    }
229
230    private void showFrequentFragmentsButton_Click(object sender, EventArgs e) {
231      int bestN;
232      bool success = int.TryParse(bestNTextBox.Text, out bestN);
233      if (!success) bestN = 10;
234      var tuples = Content.Trees.Select(t => new { Tree = t.Item1, Quality = t.Item2 }).OrderByDescending(x => x.Quality).ToList();
235      var bestTrees = tuples.Take(bestN).Select(x => x.Tree).ToList();
236
237      var similarityComparer = new SymbolicExpressionTreeNodeSimilarityComparer {
238        MatchConstantValues = false,
239        MatchVariableNames = true,
240        MatchVariableWeights = false
241      };
242
243      var fragments = bestTrees.SelectMany(t => t.IterateNodesBreadth()).Where(n => n.GetLength() >= 3).Distinct(similarityComparer).Select(n => new Fragment { Root = n });
244
245      double bestNQuality = tuples.Take(bestN).Sum(x => x.Quality); // average quality of best N individuals in the population
246
247      using (var dialog = new FrequentFragmentsDialog()) {
248        foreach (var fragment in fragments.Take(20)) {
249          double avgQuality = bestNQuality;
250          double frequency = bestN;
251          foreach (var t in tuples.Skip(bestN)) {
252            var tree = t.Tree;
253            if (tree.Root.ContainsFragment(fragment, similarityComparer)) {
254              avgQuality += t.Quality;
255              frequency++;
256            }
257          }
258          if (frequency > 0.2) {
259            var panel = new Panel {
260              Dock = DockStyle.Left,
261              Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom
262            };
263
264            panel.Controls.Add(new SymbolicExpressionTreeChart() { Tree = treeMap.Values.First() });
265            panel.Controls.Add(new Label { Text = "Fragment frequency." });
266
267            dialog.fragmentsPanel.Controls.Add(panel);
268          }
269        }
270        dialog.ShowDialog(this);
271      }
272    }
273
274    #region Event Handlers (child controls)
275    // TODO: Put event handlers of child controls here.
276    #endregion
277  }
278}
Note: See TracBrowser for help on using the repository browser.