Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs @ 6108

Last change on this file since 6108 was 6108, checked in by mkommend, 13 years ago

#1504: Corrected bug in symbolic simplifier view.

File size: 9.4 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;
31
32namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
33  public abstract partial class InteractiveSymbolicDataAnalysisSolutionSimplifierView : AsynchronousContentView {
34    private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> replacementNodes;
35    private Dictionary<ISymbolicExpressionTreeNode, double> nodeImpacts;
36
37    public InteractiveSymbolicDataAnalysisSolutionSimplifierView() {
38      InitializeComponent();
39      this.replacementNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>();
40      this.nodeImpacts = new Dictionary<ISymbolicExpressionTreeNode, double>();
41      this.Caption = "Interactive Solution Simplifier";
42    }
43
44    public new ISymbolicDataAnalysisSolution Content {
45      get { return (ISymbolicDataAnalysisSolution)base.Content; }
46      set { base.Content = value; }
47    }
48
49    protected override void RegisterContentEvents() {
50      base.RegisterContentEvents();
51      Content.ModelChanged += new EventHandler(Content_ModelChanged);
52      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
53    }
54    protected override void DeregisterContentEvents() {
55      base.DeregisterContentEvents();
56      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
57      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
58    }
59
60    private void Content_ModelChanged(object sender, EventArgs e) {
61      OnModelChanged();
62    }
63    private void Content_ProblemDataChanged(object sender, EventArgs e) {
64      OnProblemDataChanged();
65    }
66
67    protected virtual void OnModelChanged() {
68      this.CalculateReplacementNodesAndNodeImpacts();
69    }
70
71    protected virtual void OnProblemDataChanged() {
72      this.CalculateReplacementNodesAndNodeImpacts();
73    }
74
75    protected override void OnContentChanged() {
76      base.OnContentChanged();
77      this.CalculateReplacementNodesAndNodeImpacts();
78      this.viewHost.Content = this.Content;
79    }
80
81    private void CalculateReplacementNodesAndNodeImpacts() {
82      if (Content != null && Content.Model != null && Content.ProblemData != null) {
83        var tree = Content.Model.SymbolicExpressionTree;
84        var replacementValues = CalculateReplacementValues(tree);
85        foreach (var pair in replacementValues) {
86          if (!(pair.Key is ConstantTreeNode)) {
87            replacementNodes[pair.Key] = MakeConstantTreeNode(pair.Value);
88          }
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.SubtreesCount; subTreeIndex++) {
96            var child = parent.GetSubtree(subTreeIndex);
97            if (!(child.Symbol is Constant) && nodeImpacts[child].IsAlmost(0.0)) {
98              SwitchNodeWithReplacementNode(parent, subTreeIndex);
99            }
100          }
101        }
102        // show only interesting part of solution
103        if (tree.Root.SubtreesCount > 1)
104          this.treeChart.Tree = new SymbolicExpressionTree(tree.Root); // RPB + ADFs
105        else
106          this.treeChart.Tree = new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0)); // 1st child of RPB
107        this.PaintNodeImpacts();
108      }
109    }
110
111    protected abstract Dictionary<ISymbolicExpressionTreeNode, double> CalculateReplacementValues(ISymbolicExpressionTree tree);
112    protected abstract Dictionary<ISymbolicExpressionTreeNode, double> CalculateImpactValues(ISymbolicExpressionTree tree);
113    protected abstract void UpdateModel(ISymbolicExpressionTree tree);
114
115    private ConstantTreeNode MakeConstantTreeNode(double value) {
116      Constant constant = new Constant();
117      constant.MinValue = value - 1;
118      constant.MaxValue = value + 1;
119      ConstantTreeNode constantTreeNode = (ConstantTreeNode)constant.CreateTreeNode();
120      constantTreeNode.Value = value;
121      return constantTreeNode;
122    }
123
124    private void treeChart_SymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) {
125      VisualSymbolicExpressionTreeNode visualTreeNode = (VisualSymbolicExpressionTreeNode)sender;
126      var tree = Content.Model.SymbolicExpressionTree;
127      foreach (SymbolicExpressionTreeNode treeNode in tree.IterateNodesPostfix()) {
128        for (int i = 0; i < treeNode.SubtreesCount; i++) {
129          ISymbolicExpressionTreeNode subTree = treeNode.GetSubtree(i);
130          // only allow to replace nodes for which a replacement value is known (replacement value for ADF nodes are not available)
131          if (subTree == visualTreeNode.SymbolicExpressionTreeNode && replacementNodes.ContainsKey(subTree)) {
132            SwitchNodeWithReplacementNode(treeNode, i);
133
134            // show only interesting part of solution
135            if (tree.Root.SubtreesCount > 1)
136              this.treeChart.Tree = new SymbolicExpressionTree(tree.Root); // RPB + ADFs
137            else
138              this.treeChart.Tree = new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0)); // 1st child of RPB
139
140            UpdateModel(tree);
141            return; // break all loops
142          }
143        }
144      }
145    }
146
147    private void SwitchNodeWithReplacementNode(ISymbolicExpressionTreeNode parent, int subTreeIndex) {
148      ISymbolicExpressionTreeNode subTree = parent.GetSubtree(subTreeIndex);
149      parent.RemoveSubtree(subTreeIndex);
150      if (replacementNodes.ContainsKey(subTree)) {
151        var replacementNode = replacementNodes[subTree];
152        parent.InsertSubtree(subTreeIndex, replacementNode);
153        // exchange key and value
154        replacementNodes.Remove(subTree);
155        replacementNodes.Add(replacementNode, subTree);
156      }
157    }
158
159    private void PaintNodeImpacts() {
160      var impacts = nodeImpacts.Values;
161      double max = impacts.Max();
162      double min = impacts.Min();
163      foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
164        if (!(treeNode is ConstantTreeNode) && nodeImpacts.ContainsKey(treeNode)) {
165          double impact = nodeImpacts[treeNode];
166          VisualSymbolicExpressionTreeNode visualTree = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
167
168          // impact = 0 if no change
169          // impact < 0 if new solution is better
170          // impact > 0 if new solution is worse
171          if (impact < 0.0) {
172            // min is guaranteed to be < 0
173            visualTree.FillColor = Color.FromArgb((int)(impact / min * 255), Color.Red);
174          } else if (impact.IsAlmost(0.0)) {
175            visualTree.FillColor = Color.White;
176          } else {
177            // max is guaranteed to be > 0
178            visualTree.FillColor = Color.FromArgb((int)(impact / max * 255), Color.Green);
179          }
180          visualTree.ToolTip += Environment.NewLine + "Node impact: " + impact;
181          var constantReplacementNode = replacementNodes[treeNode] as ConstantTreeNode;
182          if (constantReplacementNode != null) {
183            visualTree.ToolTip += Environment.NewLine + "Replacement value: " + constantReplacementNode.Value;
184          }
185        }
186      }
187      this.PaintCollapsedNodes();
188      this.treeChart.Repaint();
189    }
190
191    private void PaintCollapsedNodes() {
192      foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
193        if (treeNode is ConstantTreeNode && replacementNodes.ContainsKey(treeNode))
194          this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = Color.DarkOrange;
195        else {
196          VisualSymbolicExpressionTreeNode visNode = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
197          if (visNode != null)
198            visNode.LineColor = Color.Black;
199        }
200      }
201    }
202
203    private void btnSimplify_Click(object sender, EventArgs e) {
204      SymbolicDataAnalysisExpressionTreeSimplifier simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier();
205      var simplifiedExpressionTree = simplifier.Simplify(Content.Model.SymbolicExpressionTree);
206      UpdateModel(simplifiedExpressionTree);
207    }
208  }
209}
Note: See TracBrowser for help on using the repository browser.