Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Tracking/SymbolicDataAnalysisGenealogyGraphView.cs @ 11927

Last change on this file since 11927 was 11927, checked in by bburlacu, 9 years ago

#1772: Fixed compilation errors and removed leftover similarity calculators, re-added ISymbolicExpressionTreeNodeSimilarityComparer interface and PhenotypicSimilarityCalculator.

File size: 10.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 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.Drawing;
25using System.Linq;
26using System.Windows.Forms;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
30using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
31using HeuristicLab.EvolutionTracking;
32using HeuristicLab.EvolutionTracking.Views;
33using HeuristicLab.MainForm;
34
35namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
36  [View("SymbolicDataAnalysisGenealogyGraphView")]
37  [Content(typeof(IGenealogyGraph<ISymbolicExpressionTree>), IsDefaultView = true)]
38  public partial class SymbolicDataAnalysisGenealogyGraphView : SymbolicDataAnalysisGenealogyGraphViewDesignable {
39    private readonly ISymbolicExpressionTreeNodeEqualityComparer comparer;
40
41    public SymbolicDataAnalysisGenealogyGraphView() {
42      InitializeComponent();
43      comparer = new SymbolicExpressionTreeNodeEqualityComparer();
44      viewHost.ViewType = typeof(GraphicalSymbolicExpressionTreeView);
45    }
46    #region event handlers
47    protected override void OnContentChanged() {
48      base.OnContentChanged();
49      if (Content != null) { genealogyGraphChart.GenealogyGraph = Content; }
50    }
51    #endregion
52
53    public SymbolicExpressionTreeChart SymbolicExpressionTreeChart {
54      get {
55        var view = (GraphicalSymbolicExpressionTreeView)base.viewHost.ActiveView;
56        return view == null ? null : view.SymbolicExpressionTreeChart;
57      }
58    }
59
60    protected override void RegisterContentEvents() {
61      base.RegisterContentEvents();
62      if (SymbolicExpressionTreeChart != null)
63        SymbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked += treeChart_SymbolicExpressionTreeNodeClicked;
64    }
65
66    protected override void DeregisterContentEvents() {
67      if (SymbolicExpressionTreeChart != null)
68        SymbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked -= treeChart_SymbolicExpressionTreeNodeClicked;
69      base.DeregisterContentEvents();
70    }
71
72    public override void graphChart_GenealogyGraphNodeClicked(object sender, MouseEventArgs args) {
73      base.graphChart_GenealogyGraphNodeClicked(sender, args);
74      var visualNode = (VisualGenealogyGraphNode)sender;
75      var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)visualNode.Data;
76
77      nodeQualityLabel.Text = String.Format("{0:0.000}", graphNode.Quality);
78      nodeRankLabel.Text = String.Format("{0:0.0}", graphNode.Rank);
79      nodeDegreeLabel.Text = String.Format("{0} / {1}", graphNode.InDegree, graphNode.OutDegree);
80
81      if (openNew_CheckBox.Checked) {
82        // get the ancestors into a new view
83        var cloner = new Cloner();
84        // clone arcs and vertices and use them to create a new graph
85        // that will include just the individual and its ancestors
86        var graph = new GenealogyGraph<ISymbolicExpressionTree>();
87        var ancestors = new[] { graphNode }.Concat(graphNode.Ancestors).ToList();
88        graph.AddVertices(ancestors.Select(cloner.Clone));
89        graph.AddArcs(ancestors.SelectMany(x => x.InArcs).Select(cloner.Clone));
90        MainFormManager.MainForm.ShowContent(graph);
91      }
92
93      if (graphNode.InArcs.Any()) {
94        var data = graphNode.InArcs.Last().Data;
95        var fragment = data as IFragment<ISymbolicExpressionTreeNode>;
96        var td = data as TraceData;
97        if (fragment != null) {
98          treeChart_HighlightSubtree(graphNode.Data.NodeAt(fragment.Index1));
99        } else if (td != null) {
100          var nodes = graphNode.Data.IterateNodesPrefix().ToList();
101          treeChart_HighlightSubtree(nodes[td.LastSubtreeIndex], Color.Orange);
102          treeChart_HighlightSubtree(nodes[td.LastFragmentIndex], Color.DodgerBlue);
103        }
104      }
105    }
106
107    public void treeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs args) {
108      var visualNode = (VisualTreeNode<ISymbolicExpressionTreeNode>)sender;
109      var subtree = visualNode.Content;
110      // highlight the selected subtree inside the displayed tree on the right hand side
111      treeChart_ClearColors();
112      treeChart_HighlightSubtree(subtree);
113
114      bool trace = genealogyGraphChart.TraceFragments; // check whether we are in 'trace' or 'match' mode
115
116      if (trace) {
117        // perform fragment tracing
118        var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
119        var subtreeIndex = graphNode.Data.IterateNodesPrefix().ToList().IndexOf(subtree);
120        var traceGraph = TraceCalculator.TraceSubtree(graphNode, subtreeIndex);
121        if (traceGraph.Vertices.Any()) {
122          genealogyGraphChart.UpdateEnabled = false;
123          genealogyGraphChart.ClearArcs();
124          var genealogyNodes = traceGraph.Vertices.Select(v => Content.GetByContent(v.Data));
125          genealogyGraphChart.HighlightNodes(genealogyNodes, Color.Black, false);
126          genealogyGraphChart.UpdateEnabled = true;
127          genealogyGraphChart.EnforceUpdate();
128          MainFormManager.MainForm.ShowContent(traceGraph); // display the fragment graph on the screen
129        }
130      } else {
131        // perform matching like it was done before
132        // currently there is no possibility to specify the subtree matching criteria
133        var trees = Content.Vertices.Select(x => x.Data);
134        var matchingTrees = trees.Where(x => x.Root.ContainsSubtree(subtree, comparer));
135
136        var matchingVertices = matchingTrees.Select(x => Content.GetByContent(x));
137        graphChart_HighlightMatchingVertices(matchingVertices);
138      }
139    }
140
141    private void graphChart_HighlightMatchingVertices(IEnumerable<IGenealogyGraphNode> vertices) {
142      genealogyGraphChart.Chart.UpdateEnabled = false;
143      genealogyGraphChart.ClearPrimitives();
144      genealogyGraphChart.HighlightNodes(vertices);
145      genealogyGraphChart.Chart.UpdateEnabled = true;
146      genealogyGraphChart.Chart.EnforceUpdate();
147    }
148
149    private void treeChart_ClearColors() {
150      foreach (var node in SymbolicExpressionTreeChart.Tree.IterateNodesPrefix()) {
151        var visualNode = SymbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
152        if (visualNode != null) {
153          visualNode.LineColor = Color.Black;
154          visualNode.FillColor = Color.Transparent;
155        }
156      }
157      SymbolicExpressionTreeChart.RepaintNodes();
158    }
159
160    private void treeChart_HighlightSubtree(ISymbolicExpressionTreeNode subtree, Color? color = null) {
161      Color myColor = color ?? Color.RoyalBlue;
162      foreach (var s in subtree.IterateNodesPrefix()) {
163        var visualNode = SymbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(s);
164        visualNode.LineColor = myColor;
165
166        foreach (var c in s.Subtrees) {
167          var visualArc = SymbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(s, c);
168          visualArc.LineColor = myColor;
169        }
170      }
171      SymbolicExpressionTreeChart.RepaintNodes();
172    }
173
174    private void navigateLeftButton_Click(object sender, EventArgs e) {
175      var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
176      var inArcs = (List<IArc>)((IVertex)graphNode).InArcs;
177      if (inArcs.Count > 0) {
178        genealogyGraphChart.SelectedGraphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs[0].Source;
179      }
180    }
181
182    private void navigateRightButton_Click(object sender, EventArgs e) {
183      var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
184      var inArcs = graphNode.InArcs.ToList();
185      if (inArcs.Count > 0) {
186        var data = inArcs.Last().Data;
187        var fragment = (data as IFragment<ISymbolicExpressionTreeNode>);
188        var td = data as TraceData;
189        if (fragment != null) {
190          genealogyGraphChart.SelectedGraphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs.Last().Source;
191        } else if (td != null) {
192          if (inArcs.Count == 1) {
193            genealogyGraphChart.SelectedGraphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs[0].Source;
194            return;
195          }
196          // the first arc from inArcs will always represent the connection to the root parent
197          // (tracing the body of the traced subtree)
198          // therefore, in order to follow the correct non-root parent, we have to find the correct arc
199          // But, the FragmentIndex recorded in the TraceData of the first arc has to match the SubtreeIndex recorded in the TraceData of the searched arc
200          td = (TraceData)inArcs[0].Data;
201          var f1 = (graphNode.Data).NodeAt(td.LastFragmentIndex);
202          for (int i = 1; i < inArcs.Count; ++i) {
203            td = (TraceData)inArcs[i].Data;
204            var f2 = ((IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs[i].Source).Data.NodeAt(td.SubtreeIndex);
205            // if the subtrees are the same we have found a match
206            // note: this is not necessarily 100% correct if in the trace graph we have identical fragments on different arcs
207            if (f1.Difference(f2) == null) {
208              genealogyGraphChart.SelectedGraphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs[i].Source;
209              return;
210            }
211          }
212          throw new InvalidOperationException("Error calculating the next step.");
213        }
214      }
215    }
216  }
217  public class SymbolicDataAnalysisGenealogyGraphViewDesignable : GenealogyGraphView<ISymbolicExpressionTree> { }
218
219  internal static class Util {
220    internal static ISymbolicExpressionTreeNode NodeAt(this ISymbolicExpressionTree tree, int position) {
221      return NodeAt(tree.Root, position);
222    }
223    internal static ISymbolicExpressionTreeNode NodeAt(this ISymbolicExpressionTreeNode root, int position) {
224      return root.IterateNodesPrefix().ElementAt(position);
225    }
226  }
227}
Note: See TracBrowser for help on using the repository browser.