Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1418 fixed evaluator call from validation analyzers, fixed bugs in interactive simplifier view and added apply linear scaling flag to analyzers.

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