Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs @ 7603

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

#1081: merged r7214:7266 from trunk into time series branch.

File size: 10.0 KB
RevLine 
[3915]1#region License Information
2/* HeuristicLab
[7268]3 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[3915]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;
[4068]29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
[3915]30using HeuristicLab.MainForm.WindowsForms;
31
[5699]32namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
33  public abstract partial class InteractiveSymbolicDataAnalysisSolutionSimplifierView : AsynchronousContentView {
[5729]34    private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> replacementNodes;
[5699]35    private Dictionary<ISymbolicExpressionTreeNode, double> nodeImpacts;
[6113]36    private bool updateInProgress = false;
[3915]37
[5699]38    public InteractiveSymbolicDataAnalysisSolutionSimplifierView() {
[3915]39      InitializeComponent();
[5729]40      this.replacementNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>();
[5699]41      this.nodeImpacts = new Dictionary<ISymbolicExpressionTreeNode, double>();
[3915]42      this.Caption = "Interactive Solution Simplifier";
43    }
44
[5699]45    public new ISymbolicDataAnalysisSolution Content {
46      get { return (ISymbolicDataAnalysisSolution)base.Content; }
[3915]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) {
[5699]62      OnModelChanged();
[3915]63    }
64    private void Content_ProblemDataChanged(object sender, EventArgs e) {
[5699]65      OnProblemDataChanged();
66    }
67
68    protected virtual void OnModelChanged() {
[3915]69      this.CalculateReplacementNodesAndNodeImpacts();
70    }
71
[5699]72    protected virtual void OnProblemDataChanged() {
73      this.CalculateReplacementNodesAndNodeImpacts();
74    }
75
[3915]76    protected override void OnContentChanged() {
77      base.OnContentChanged();
78      this.CalculateReplacementNodesAndNodeImpacts();
79      this.viewHost.Content = this.Content;
80    }
81
82    private void CalculateReplacementNodesAndNodeImpacts() {
83      if (Content != null && Content.Model != null && Content.ProblemData != null) {
[5722]84        var tree = Content.Model.SymbolicExpressionTree;
85        var replacementValues = CalculateReplacementValues(tree);
[5699]86        foreach (var pair in replacementValues) {
[5729]87          if (!(pair.Key is ConstantTreeNode)) {
88            replacementNodes[pair.Key] = MakeConstantTreeNode(pair.Value);
89          }
[5699]90        }
[5722]91        nodeImpacts = CalculateImpactValues(Content.Model.SymbolicExpressionTree);
[3915]92
[6113]93        if (!updateInProgress) {
94          // automatically fold all branches with impact = 1
95          List<ISymbolicExpressionTreeNode> nodeList = Content.Model.SymbolicExpressionTree.Root.GetSubtree(0).IterateNodesPrefix().ToList();
96          foreach (var parent in nodeList) {
[6803]97            for (int subTreeIndex = 0; subTreeIndex < parent.SubtreeCount; subTreeIndex++) {
[6113]98              var child = parent.GetSubtree(subTreeIndex);
99              if (!(child.Symbol is Constant) && nodeImpacts[child].IsAlmost(0.0)) {
100                SwitchNodeWithReplacementNode(parent, subTreeIndex);
101              }
[5455]102            }
103          }
104        }
[6113]105
[5993]106        // show only interesting part of solution
[6803]107        if (tree.Root.SubtreeCount > 1)
[5993]108          this.treeChart.Tree = new SymbolicExpressionTree(tree.Root); // RPB + ADFs
[7183]109        else if (tree.Root.GetSubtree(0).SubtreeCount > 1)
110          this.treeChart.Tree = new SymbolicExpressionTree(tree.Root); // RPB
[5993]111        else
112          this.treeChart.Tree = new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0)); // 1st child of RPB
[3915]113        this.PaintNodeImpacts();
114      }
115    }
116
[5717]117    protected abstract Dictionary<ISymbolicExpressionTreeNode, double> CalculateReplacementValues(ISymbolicExpressionTree tree);
118    protected abstract Dictionary<ISymbolicExpressionTreeNode, double> CalculateImpactValues(ISymbolicExpressionTree tree);
119    protected abstract void UpdateModel(ISymbolicExpressionTree tree);
[3915]120
121    private ConstantTreeNode MakeConstantTreeNode(double value) {
122      Constant constant = new Constant();
123      constant.MinValue = value - 1;
124      constant.MaxValue = value + 1;
125      ConstantTreeNode constantTreeNode = (ConstantTreeNode)constant.CreateTreeNode();
126      constantTreeNode.Value = value;
127      return constantTreeNode;
128    }
129
130    private void treeChart_SymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) {
131      VisualSymbolicExpressionTreeNode visualTreeNode = (VisualSymbolicExpressionTreeNode)sender;
[5722]132      var tree = Content.Model.SymbolicExpressionTree;
133      foreach (SymbolicExpressionTreeNode treeNode in tree.IterateNodesPostfix()) {
[6803]134        for (int i = 0; i < treeNode.SubtreeCount; i++) {
[5736]135          ISymbolicExpressionTreeNode subTree = treeNode.GetSubtree(i);
[5993]136          // only allow to replace nodes for which a replacement value is known (replacement value for ADF nodes are not available)
137          if (subTree == visualTreeNode.SymbolicExpressionTreeNode && replacementNodes.ContainsKey(subTree)) {
[5729]138            SwitchNodeWithReplacementNode(treeNode, i);
[5993]139
140            // show only interesting part of solution
[6803]141            if (tree.Root.SubtreeCount > 1)
[5993]142              this.treeChart.Tree = new SymbolicExpressionTree(tree.Root); // RPB + ADFs
[7183]143            else if (tree.Root.GetSubtree(0).SubtreeCount > 1)
144              this.treeChart.Tree = new SymbolicExpressionTree(tree.Root); // RPB
[5993]145            else
146              this.treeChart.Tree = new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0)); // 1st child of RPB
[6108]147
[6113]148            updateInProgress = true;
[6108]149            UpdateModel(tree);
[6113]150            updateInProgress = false;
[5993]151            return; // break all loops
[3915]152          }
153        }
154      }
155    }
156
[5729]157    private void SwitchNodeWithReplacementNode(ISymbolicExpressionTreeNode parent, int subTreeIndex) {
[5736]158      ISymbolicExpressionTreeNode subTree = parent.GetSubtree(subTreeIndex);
159      parent.RemoveSubtree(subTreeIndex);
[5729]160      if (replacementNodes.ContainsKey(subTree)) {
161        var replacementNode = replacementNodes[subTree];
[5736]162        parent.InsertSubtree(subTreeIndex, replacementNode);
[5729]163        // exchange key and value
164        replacementNodes.Remove(subTree);
165        replacementNodes.Add(replacementNode, subTree);
166      }
[5455]167    }
168
[3915]169    private void PaintNodeImpacts() {
170      var impacts = nodeImpacts.Values;
171      double max = impacts.Max();
172      double min = impacts.Min();
[5722]173      foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
[4477]174        if (!(treeNode is ConstantTreeNode) && nodeImpacts.ContainsKey(treeNode)) {
[5729]175          double impact = nodeImpacts[treeNode];
[3915]176          VisualSymbolicExpressionTreeNode visualTree = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
[5722]177
[5717]178          // impact = 0 if no change
179          // impact < 0 if new solution is better
180          // impact > 0 if new solution is worse
181          if (impact < 0.0) {
[5729]182            // min is guaranteed to be < 0
[5717]183            visualTree.FillColor = Color.FromArgb((int)(impact / min * 255), Color.Red);
[5729]184          } else if (impact.IsAlmost(0.0)) {
185            visualTree.FillColor = Color.White;
[5717]186          } else {
[5729]187            // max is guaranteed to be > 0
[5717]188            visualTree.FillColor = Color.FromArgb((int)(impact / max * 255), Color.Green);
189          }
[3915]190          visualTree.ToolTip += Environment.NewLine + "Node impact: " + impact;
[5729]191          var constantReplacementNode = replacementNodes[treeNode] as ConstantTreeNode;
192          if (constantReplacementNode != null) {
193            visualTree.ToolTip += Environment.NewLine + "Replacement value: " + constantReplacementNode.Value;
194          }
[6108]195        }
[3915]196      }
197      this.PaintCollapsedNodes();
198      this.treeChart.Repaint();
199    }
200
201    private void PaintCollapsedNodes() {
[5722]202      foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
[5729]203        if (treeNode is ConstantTreeNode && replacementNodes.ContainsKey(treeNode))
[3915]204          this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = Color.DarkOrange;
[4477]205        else {
206          VisualSymbolicExpressionTreeNode visNode = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
207          if (visNode != null)
208            visNode.LineColor = Color.Black;
209        }
[3915]210      }
211    }
[3927]212
213    private void btnSimplify_Click(object sender, EventArgs e) {
[5722]214      SymbolicDataAnalysisExpressionTreeSimplifier simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier();
215      var simplifiedExpressionTree = simplifier.Simplify(Content.Model.SymbolicExpressionTree);
216      UpdateModel(simplifiedExpressionTree);
[3927]217    }
[6256]218
219    protected abstract void btnOptimizeConstants_Click(object sender, EventArgs e);
[3915]220  }
221}
Note: See TracBrowser for help on using the repository browser.