Free cookie consent management tool by TermsFeed Policy Generator

source: branches/SlaveShutdown/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs @ 8954

Last change on this file since 8954 was 8954, checked in by ascheibe, 12 years ago

#1986 merged trunk into SlaveShutdown branch

File size: 11.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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    private Dictionary<ISymbolicExpressionTreeNode, double> originalValues;
37    private Dictionary<ISymbolicExpressionTreeNode, string> originalVariableNames;
38
39    public InteractiveSymbolicDataAnalysisSolutionSimplifierView() {
40      InitializeComponent();
41      replacementNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>();
42      nodeImpacts = new Dictionary<ISymbolicExpressionTreeNode, double>();
43      originalValues = new Dictionary<ISymbolicExpressionTreeNode, double>();
44      originalVariableNames = new Dictionary<ISymbolicExpressionTreeNode, string>();
45
46      this.Caption = "Interactive Solution Simplifier";
47    }
48
49    public new ISymbolicDataAnalysisSolution Content {
50      get { return (ISymbolicDataAnalysisSolution)base.Content; }
51      set { base.Content = value; }
52    }
53
54    protected override void RegisterContentEvents() {
55      base.RegisterContentEvents();
56      Content.ModelChanged += Content_Changed;
57      Content.ProblemDataChanged += Content_Changed;
58    }
59    protected override void DeregisterContentEvents() {
60      base.DeregisterContentEvents();
61      Content.ModelChanged -= Content_Changed;
62      Content.ProblemDataChanged -= Content_Changed;
63    }
64
65    private void Content_Changed(object sender, EventArgs e) {
66      UpdateView();
67    }
68
69    protected override void OnContentChanged() {
70      base.OnContentChanged();
71      UpdateView();
72      viewHost.Content = this.Content;
73    }
74
75    private void UpdateView() {
76      if (Content == null || Content.Model == null || Content.ProblemData == null) return;
77      var tree = Content.Model.SymbolicExpressionTree;
78
79      var replacementValues = CalculateReplacementValues(tree);
80      foreach (var pair in replacementValues.Where(pair => !(pair.Key is ConstantTreeNode))) {
81        replacementNodes[pair.Key] = MakeConstantTreeNode(pair.Value);
82      }
83
84      nodeImpacts = CalculateImpactValues(tree);
85
86      var model = Content.Model.SymbolicExpressionTree;
87      treeChart.Tree = model.Root.SubtreeCount > 1 ? new SymbolicExpressionTree(model.Root) : new SymbolicExpressionTree(model.Root.GetSubtree(0).GetSubtree(0));
88      PaintNodeImpacts();
89    }
90
91    protected abstract Dictionary<ISymbolicExpressionTreeNode, double> CalculateReplacementValues(ISymbolicExpressionTree tree);
92    protected abstract Dictionary<ISymbolicExpressionTreeNode, double> CalculateImpactValues(ISymbolicExpressionTree tree);
93    protected abstract void UpdateModel(ISymbolicExpressionTree tree);
94
95    private static ConstantTreeNode MakeConstantTreeNode(double value) {
96      var constant = new Constant { MinValue = value - 1, MaxValue = value + 1 };
97      var constantTreeNode = (ConstantTreeNode)constant.CreateTreeNode();
98      constantTreeNode.Value = value;
99      return constantTreeNode;
100    }
101
102    private void treeChart_SymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) {
103      if (!treeChart.TreeValid) return;
104      var visualNode = (VisualSymbolicExpressionTreeNode)sender;
105      var symbExprTreeNode = (SymbolicExpressionTreeNode)visualNode.SymbolicExpressionTreeNode;
106      if (symbExprTreeNode == null) return;
107      var tree = Content.Model.SymbolicExpressionTree;
108
109      bool update = false;
110      // check if the node value/weight has been altered
111      // if so, the first double click will return the node to its original value/weight/variable name
112      // the next double click will replace the ConstantNode with the original SymbolicExpressionTreeNode
113      if (originalVariableNames.ContainsKey(symbExprTreeNode)) {
114        var variable = (VariableTreeNode)symbExprTreeNode;
115        variable.VariableName = originalVariableNames[symbExprTreeNode];
116        originalVariableNames.Remove(variable);
117        update = true;
118      } else if (originalValues.ContainsKey(symbExprTreeNode)) {
119        double value = originalValues[symbExprTreeNode];
120        if (symbExprTreeNode.Symbol is Constant) {
121          var constantTreeNode = (ConstantTreeNode)symbExprTreeNode;
122          constantTreeNode.Value = value;
123        } else if (symbExprTreeNode.Symbol is Variable) {
124          var variable = (VariableTreeNode)symbExprTreeNode;
125          variable.Weight = value;
126        }
127        originalValues.Remove(symbExprTreeNode);
128        update = true;
129      } else if (replacementNodes.ContainsKey(symbExprTreeNode)) {
130        foreach (var treeNode in tree.IterateNodesPostfix()) {
131          for (int i = 0; i < treeNode.SubtreeCount; i++) {
132            var subtree = treeNode.GetSubtree(i);
133            if (subtree == symbExprTreeNode) {
134              SwitchNodeWithReplacementNode(treeNode, i);
135              // show only interesting part of solution
136              treeChart.Tree = tree.Root.SubtreeCount > 1
137                                 ? new SymbolicExpressionTree(tree.Root)
138                                 : new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0));
139              update = true;
140            }
141          }
142          if (update) break;
143        }
144      }
145      if (update) UpdateModel(tree);
146    }
147
148    private void treeChart_SymbolicExpressionTreeChanged(object sender, EventArgs e) {
149      UpdateModel(Content.Model.SymbolicExpressionTree);
150      UpdateView();
151    }
152
153    private void treeChart_SymbolicExpressionTreeNodeChanged(object sender, EventArgs e) {
154      var dialog = (ValueChangeDialog)sender;
155      bool flag1 = false, flag2 = false;
156      var node = dialog.Content;
157
158      if (node is VariableTreeNode) {
159        var variable = (VariableTreeNode)node;
160        var weight = double.Parse(dialog.newValueTextBox.Text);
161        var name = (string)dialog.variableNamesCombo.SelectedItem;
162        if (!variable.Weight.Equals(weight)) {
163          flag1 = true;
164          originalValues[variable] = variable.Weight;
165          variable.Weight = weight;
166        }
167        if (!variable.VariableName.Equals(name)) {
168          flag2 = true;
169          originalVariableNames[variable] = variable.VariableName;
170          variable.VariableName = name;
171        }
172      } else if (node is ConstantTreeNode) {
173        var constant = (ConstantTreeNode)node;
174        var value = double.Parse(dialog.newValueTextBox.Text);
175        if (!constant.Value.Equals(value)) {
176          flag1 = true;
177          originalValues[constant] = constant.Value;
178          constant.Value = value;
179        }
180      }
181      if (flag1 || flag2) {
182        UpdateView();
183      }
184    }
185
186    private void SwitchNodeWithReplacementNode(ISymbolicExpressionTreeNode parent, int subTreeIndex) {
187      ISymbolicExpressionTreeNode subTree = parent.GetSubtree(subTreeIndex);
188      parent.RemoveSubtree(subTreeIndex);
189      if (replacementNodes.ContainsKey(subTree)) {
190        var replacementNode = replacementNodes[subTree];
191        parent.InsertSubtree(subTreeIndex, replacementNode);
192        // exchange key and value
193        replacementNodes.Remove(subTree);
194        replacementNodes.Add(replacementNode, subTree);
195      }
196    }
197
198    private void PaintNodeImpacts() {
199      var impacts = nodeImpacts.Values;
200      double max = impacts.Max();
201      double min = impacts.Min();
202      foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
203        VisualSymbolicExpressionTreeNode visualTree = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
204        bool flag1 = replacementNodes.ContainsKey(treeNode);
205        bool flag2 = originalValues.ContainsKey(treeNode);
206        bool flag3 = treeNode is ConstantTreeNode;
207
208        if (flag2) // constant or variable node was changed
209          visualTree.ToolTip += Environment.NewLine + "Original value: " + originalValues[treeNode];
210        else if (flag1 && flag3) // symbol node was folded to a constant
211          visualTree.ToolTip += Environment.NewLine + "Original node: " + replacementNodes[treeNode];
212
213        if (!(treeNode is ConstantTreeNode) && nodeImpacts.ContainsKey(treeNode)) {
214          double impact = nodeImpacts[treeNode];
215
216          // impact = 0 if no change
217          // impact < 0 if new solution is better
218          // impact > 0 if new solution is worse
219          if (impact < 0.0) {
220            // min is guaranteed to be < 0
221            visualTree.FillColor = Color.FromArgb((int)(impact / min * 255), Color.Red);
222          } else if (impact.IsAlmost(0.0)) {
223            visualTree.FillColor = Color.White;
224          } else {
225            // max is guaranteed to be > 0
226            visualTree.FillColor = Color.FromArgb((int)(impact / max * 255), Color.Green);
227          }
228          visualTree.ToolTip += Environment.NewLine + "Node impact: " + impact;
229          var constantReplacementNode = replacementNodes[treeNode] as ConstantTreeNode;
230          if (constantReplacementNode != null) {
231            visualTree.ToolTip += Environment.NewLine + "Replacement value: " + constantReplacementNode.Value;
232          }
233        }
234      }
235      this.PaintCollapsedNodes();
236      this.treeChart.Repaint();
237    }
238
239    private void PaintCollapsedNodes() {
240      foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
241        bool flag1 = replacementNodes.ContainsKey(treeNode);
242        bool flag2 = originalValues.ContainsKey(treeNode);
243        if (flag1 && treeNode is ConstantTreeNode) {
244          this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = flag2 ? Color.DarkViolet : Color.DarkOrange;
245        } else if (flag2) {
246          this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = Color.DodgerBlue;
247        }
248      }
249    }
250
251    private void btnSimplify_Click(object sender, EventArgs e) {
252      var simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier();
253      var simplifiedExpressionTree = simplifier.Simplify(Content.Model.SymbolicExpressionTree);
254      UpdateModel(simplifiedExpressionTree);
255    }
256
257    protected abstract void btnOptimizeConstants_Click(object sender, EventArgs e);
258  }
259}
Note: See TracBrowser for help on using the repository browser.