Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs @ 5717

Last change on this file since 5717 was 5717, checked in by gkronber, 13 years ago

#1418 Implemented interactive simplifier views for symbolic classification and regression.

File size: 8.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
30using HeuristicLab.MainForm.WindowsForms;
31using HeuristicLab.Problems.DataAnalysis.Symbolic;
32
33namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
34  public abstract partial class InteractiveSymbolicDataAnalysisSolutionSimplifierView : AsynchronousContentView {
35    private ISymbolicExpressionTree simplifiedExpressionTree;
36    private Dictionary<ISymbolicExpressionTreeNode, ConstantTreeNode> replacementNodes;
37    private Dictionary<ISymbolicExpressionTreeNode, double> nodeImpacts;
38
39    public InteractiveSymbolicDataAnalysisSolutionSimplifierView() {
40      InitializeComponent();
41      this.replacementNodes = new Dictionary<ISymbolicExpressionTreeNode, ConstantTreeNode>();
42      this.nodeImpacts = new Dictionary<ISymbolicExpressionTreeNode, double>();
43      this.simplifiedExpressionTree = null;
44      this.Caption = "Interactive Solution Simplifier";
45    }
46
47    public new ISymbolicDataAnalysisSolution Content {
48      get { return (ISymbolicDataAnalysisSolution)base.Content; }
49      set { base.Content = value; }
50    }
51
52    protected override void RegisterContentEvents() {
53      base.RegisterContentEvents();
54      Content.ModelChanged += new EventHandler(Content_ModelChanged);
55      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
56    }
57    protected override void DeregisterContentEvents() {
58      base.DeregisterContentEvents();
59      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
60      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
61    }
62
63    private void Content_ModelChanged(object sender, EventArgs e) {
64      OnModelChanged();
65    }
66    private void Content_ProblemDataChanged(object sender, EventArgs e) {
67      OnProblemDataChanged();
68    }
69
70    protected virtual void OnModelChanged() {
71      this.CalculateReplacementNodesAndNodeImpacts();
72    }
73
74    protected virtual void OnProblemDataChanged() {
75      this.CalculateReplacementNodesAndNodeImpacts();
76    }
77
78    protected override void OnContentChanged() {
79      base.OnContentChanged();
80      this.CalculateReplacementNodesAndNodeImpacts();
81      this.viewHost.Content = this.Content;
82    }
83
84    private void CalculateReplacementNodesAndNodeImpacts() {
85      replacementNodes.Clear();
86      if (Content != null && Content.Model != null && Content.ProblemData != null) {
87        SymbolicDataAnalysisExpressionTreeSimplifier simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier();
88        simplifiedExpressionTree = simplifier.Simplify(Content.Model.SymbolicExpressionTree);
89
90        var replacementValues = CalculateReplacementValues(simplifiedExpressionTree);
91        foreach (var pair in replacementValues) {
92          replacementNodes.Add(pair.Key, MakeConstantTreeNode(pair.Value));
93        }
94        nodeImpacts = CalculateImpactValues(simplifiedExpressionTree);
95
96        // automatically fold all branches with impact = 1
97        List<ISymbolicExpressionTreeNode> nodeList = simplifiedExpressionTree.Root.GetSubTree(0).IterateNodesPrefix().ToList();
98        foreach (var parent in nodeList) {
99          for (int subTreeIndex = 0; subTreeIndex < parent.SubTrees.Count(); subTreeIndex++) {
100            var child = parent.GetSubTree(subTreeIndex);
101            if (!(child.Symbol is Constant) && nodeImpacts[child].IsAlmost(1.0)) {
102              ReplaceNodeWithConstant(parent, subTreeIndex);
103            }
104          }
105        }
106        // show only interesting part of solution
107        this.treeChart.Tree = new SymbolicExpressionTree(simplifiedExpressionTree.Root.GetSubTree(0).GetSubTree(0));
108        this.PaintNodeImpacts();
109      }
110    }
111
112    protected abstract Dictionary<ISymbolicExpressionTreeNode, double> CalculateReplacementValues(ISymbolicExpressionTree tree);
113    protected abstract Dictionary<ISymbolicExpressionTreeNode, double> CalculateImpactValues(ISymbolicExpressionTree tree);
114    protected abstract void UpdateModel(ISymbolicExpressionTree tree);
115
116    private ConstantTreeNode MakeConstantTreeNode(double value) {
117      Constant constant = new Constant();
118      constant.MinValue = value - 1;
119      constant.MaxValue = value + 1;
120      ConstantTreeNode constantTreeNode = (ConstantTreeNode)constant.CreateTreeNode();
121      constantTreeNode.Value = value;
122      return constantTreeNode;
123    }
124
125    private void treeChart_SymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) {
126      VisualSymbolicExpressionTreeNode visualTreeNode = (VisualSymbolicExpressionTreeNode)sender;
127      foreach (SymbolicExpressionTreeNode treeNode in simplifiedExpressionTree.IterateNodesPostfix()) {
128        for (int i = 0; i < treeNode.SubTrees.Count(); i++) {
129          ISymbolicExpressionTreeNode subTree = treeNode.GetSubTree(i);
130          if (subTree == visualTreeNode.SymbolicExpressionTreeNode) {
131            ReplaceNodeWithConstant(treeNode, i);
132          }
133        }
134      }
135
136      // show only interesting part of solution
137      this.treeChart.Tree = new SymbolicExpressionTree(simplifiedExpressionTree.Root.GetSubTree(0).GetSubTree(0));
138
139      SymbolicExpressionTree tree = (SymbolicExpressionTree)simplifiedExpressionTree.Clone();
140      UpdateModel(tree);
141      this.PaintNodeImpacts();
142    }
143
144    private void ReplaceNodeWithConstant(ISymbolicExpressionTreeNode parent, int subTreeIndex) {
145      ISymbolicExpressionTreeNode subTree = parent.GetSubTree(subTreeIndex);
146      parent.RemoveSubTree(subTreeIndex);
147      if (replacementNodes.ContainsKey(subTree))
148        parent.InsertSubTree(subTreeIndex, replacementNodes[subTree]);
149      else if (subTree is ConstantTreeNode && replacementNodes.ContainsValue((ConstantTreeNode)subTree))
150        parent.InsertSubTree(subTreeIndex, replacementNodes.Where(v => v.Value == subTree).Single().Key);
151      else if (!(subTree is ConstantTreeNode))
152        throw new InvalidOperationException("Could not find replacement value.");
153    }
154
155    private void PaintNodeImpacts() {
156      var impacts = nodeImpacts.Values;
157      double max = impacts.Max();
158      double min = impacts.Min();
159      foreach (ISymbolicExpressionTreeNode treeNode in simplifiedExpressionTree.IterateNodesPostfix()) {
160        if (!(treeNode is ConstantTreeNode) && nodeImpacts.ContainsKey(treeNode)) {
161          double impact = this.nodeImpacts[treeNode];
162          double replacementValue = this.replacementNodes[treeNode].Value;
163          VisualSymbolicExpressionTreeNode visualTree = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
164         
165          // impact = 0 if no change
166          // impact < 0 if new solution is better
167          // impact > 0 if new solution is worse
168          if (impact < 0.0) {
169            visualTree.FillColor = Color.FromArgb((int)(impact / min * 255), Color.Red);
170          } else {
171            visualTree.FillColor = Color.FromArgb((int)(impact / max * 255), Color.Green);
172          }
173          visualTree.ToolTip += Environment.NewLine + "Node impact: " + impact;
174          visualTree.ToolTip += Environment.NewLine + "Replacement value: " + replacementValue;
175        }
176      }
177      this.PaintCollapsedNodes();
178      this.treeChart.Repaint();
179    }
180
181    private void PaintCollapsedNodes() {
182      foreach (ISymbolicExpressionTreeNode treeNode in simplifiedExpressionTree.IterateNodesPostfix()) {
183        if (treeNode is ConstantTreeNode && replacementNodes.ContainsValue((ConstantTreeNode)treeNode))
184          this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = Color.DarkOrange;
185        else {
186          VisualSymbolicExpressionTreeNode visNode = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
187          if (visNode != null)
188            visNode.LineColor = Color.Black;
189        }
190      }
191    }
192
193    private void btnSimplify_Click(object sender, EventArgs e) {
194      this.CalculateReplacementNodesAndNodeImpacts();
195    }
196  }
197}
Note: See TracBrowser for help on using the repository browser.