Changeset 9126 for branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs
- Timestamp:
- 01/08/13 15:36:13 (12 years ago)
- Location:
- branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views
- Property svn:mergeinfo changed
-
branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4
- Property svn:ignore
-
old new 2 2 obj 3 3 *.user 4 HeuristicLabProblemsDataAnalysisSymbolicViewsPlugin.cs5 4 *.vs10x 6 5 Plugin.cs
-
- Property svn:ignore
-
branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs
r7259 r9126 32 32 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views { 33 33 public abstract partial class InteractiveSymbolicDataAnalysisSolutionSimplifierView : AsynchronousContentView { 34 private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> replacementNodes; 34 private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> foldedNodes; 35 private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> changedNodes; 35 36 private Dictionary<ISymbolicExpressionTreeNode, double> nodeImpacts; 36 private bool updateInProgress = false; 37 private enum TreeState { Valid, Invalid } 38 private TreeState treeState; 37 39 38 40 public InteractiveSymbolicDataAnalysisSolutionSimplifierView() { 39 41 InitializeComponent(); 40 this.replacementNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); 41 this.nodeImpacts = new Dictionary<ISymbolicExpressionTreeNode, double>(); 42 foldedNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); 43 changedNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); 44 nodeImpacts = new Dictionary<ISymbolicExpressionTreeNode, double>(); 42 45 this.Caption = "Interactive Solution Simplifier"; 46 47 // initialize the tree modifier that will be used to perform edit operations over the tree 48 treeChart.ModifyTree = Modify; 49 } 50 51 /// <summary> 52 /// Remove, Replace or Insert subtrees 53 /// </summary> 54 /// <param name="tree">The symbolic expression tree</param> 55 /// <param name="node">The insertion point (ie, the parent node who will receive a new child)</param> 56 /// <param name="oldChild">The subtree to be replaced</param> 57 /// <param name="newChild">The replacement subtree</param> 58 /// <param name="removeSubtree">Flag used to indicate if whole subtrees should be removed (default behavior), or just the subtree root</param> 59 private void Modify(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode node, ISymbolicExpressionTreeNode oldChild, ISymbolicExpressionTreeNode newChild, bool removeSubtree = true) { 60 if (oldChild == null && newChild == null) throw new ArgumentException(); 61 if (oldChild == null) { // insertion operation 62 node.AddSubtree(newChild); 63 newChild.Parent = node; 64 } else if (newChild == null) { // removal operation 65 node.RemoveSubtree(node.IndexOfSubtree(oldChild)); 66 changedNodes.Remove(oldChild); 67 foldedNodes.Remove(oldChild); 68 if (removeSubtree) { 69 foreach (var subtree in oldChild.IterateNodesPrefix()) { 70 changedNodes.Remove(subtree); 71 foldedNodes.Remove(subtree); 72 } 73 } else { 74 for (int i = oldChild.SubtreeCount - 1; i >= 0; --i) { 75 var subtree = oldChild.GetSubtree(i); 76 oldChild.RemoveSubtree(i); 77 node.AddSubtree(subtree); 78 } 79 } 80 } else { // replacement operation 81 var replacementIndex = node.IndexOfSubtree(oldChild); 82 node.RemoveSubtree(replacementIndex); 83 node.InsertSubtree(replacementIndex, newChild); 84 newChild.Parent = node; 85 if (changedNodes.ContainsKey(oldChild)) { 86 changedNodes.Add(newChild, changedNodes[oldChild]); // so that on double click the original node is restored 87 changedNodes.Remove(oldChild); 88 } else { 89 changedNodes.Add(newChild, oldChild); 90 } 91 } 92 if (IsValid(tree)) { 93 treeState = TreeState.Valid; 94 UpdateModel(Content.Model.SymbolicExpressionTree); 95 } else { 96 treeState = TreeState.Invalid; 97 } 98 } 99 100 private bool IsValid(ISymbolicExpressionTree tree) { 101 treeChart.Tree = tree; 102 treeChart.Repaint(); 103 bool valid = !tree.IterateNodesPostfix().Any(node => node.SubtreeCount < node.Symbol.MinimumArity || node.SubtreeCount > node.Symbol.MaximumArity); 104 if (valid) { 105 btnOptimizeConstants.Enabled = true; 106 btnSimplify.Enabled = true; 107 treeStatusValue.Text = "Valid"; 108 treeStatusValue.ForeColor = Color.Green; 109 } else { 110 btnOptimizeConstants.Enabled = false; 111 btnSimplify.Enabled = false; 112 treeStatusValue.Text = "Invalid"; 113 treeStatusValue.ForeColor = Color.Red; 114 } 115 this.Refresh(); 116 return valid; 43 117 } 44 118 … … 50 124 protected override void RegisterContentEvents() { 51 125 base.RegisterContentEvents(); 52 Content.ModelChanged += new EventHandler(Content_ModelChanged);53 Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);126 Content.ModelChanged += Content_Changed; 127 Content.ProblemDataChanged += Content_Changed; 54 128 } 55 129 protected override void DeregisterContentEvents() { 56 130 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(); 131 Content.ModelChanged -= Content_Changed; 132 Content.ProblemDataChanged -= Content_Changed; 133 } 134 135 private void Content_Changed(object sender, EventArgs e) { 136 UpdateView(); 74 137 } 75 138 76 139 protected override void OnContentChanged() { 77 140 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) { 84 var tree = Content.Model.SymbolicExpressionTree; 85 var replacementValues = CalculateReplacementValues(tree); 86 foreach (var pair in replacementValues) { 87 if (!(pair.Key is ConstantTreeNode)) { 88 replacementNodes[pair.Key] = MakeConstantTreeNode(pair.Value); 89 } 90 } 91 nodeImpacts = CalculateImpactValues(Content.Model.SymbolicExpressionTree); 92 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) { 97 for (int subTreeIndex = 0; subTreeIndex < parent.SubtreeCount; subTreeIndex++) { 98 var child = parent.GetSubtree(subTreeIndex); 99 if (!(child.Symbol is Constant) && nodeImpacts[child].IsAlmost(0.0)) { 100 SwitchNodeWithReplacementNode(parent, subTreeIndex); 101 } 102 } 103 } 104 } 105 106 // show only interesting part of solution 107 if (tree.Root.SubtreeCount > 1) 108 this.treeChart.Tree = new SymbolicExpressionTree(tree.Root); // RPB + ADFs 109 else 110 this.treeChart.Tree = new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0)); // 1st child of RPB 111 this.PaintNodeImpacts(); 112 } 141 foldedNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); 142 UpdateView(); 143 viewHost.Content = this.Content; 144 } 145 146 private void UpdateView() { 147 if (Content == null || Content.Model == null || Content.ProblemData == null) return; 148 var tree = Content.Model.SymbolicExpressionTree; 149 treeChart.Tree = tree.Root.SubtreeCount > 1 ? new SymbolicExpressionTree(tree.Root) : new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0)); 150 151 var replacementValues = CalculateReplacementValues(tree); 152 foreach (var pair in replacementValues.Where(pair => !(pair.Key is ConstantTreeNode))) { 153 foldedNodes[pair.Key] = MakeConstantTreeNode(pair.Value); 154 } 155 156 nodeImpacts = CalculateImpactValues(tree); 157 PaintNodeImpacts(); 113 158 } 114 159 … … 117 162 protected abstract void UpdateModel(ISymbolicExpressionTree tree); 118 163 119 private ConstantTreeNode MakeConstantTreeNode(double value) { 120 Constant constant = new Constant(); 121 constant.MinValue = value - 1; 122 constant.MaxValue = value + 1; 123 ConstantTreeNode constantTreeNode = (ConstantTreeNode)constant.CreateTreeNode(); 164 private static ConstantTreeNode MakeConstantTreeNode(double value) { 165 var constant = new Constant { MinValue = value - 1, MaxValue = value + 1 }; 166 var constantTreeNode = (ConstantTreeNode)constant.CreateTreeNode(); 124 167 constantTreeNode.Value = value; 125 168 return constantTreeNode; … … 127 170 128 171 private void treeChart_SymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) { 129 VisualSymbolicExpressionTreeNode visualTreeNode = (VisualSymbolicExpressionTreeNode)sender; 172 if (treeState == TreeState.Invalid) return; 173 var visualNode = (VisualSymbolicExpressionTreeNode)sender; 174 var symbExprTreeNode = (SymbolicExpressionTreeNode)visualNode.SymbolicExpressionTreeNode; 175 if (symbExprTreeNode == null) return; 130 176 var tree = Content.Model.SymbolicExpressionTree; 131 foreach (SymbolicExpressionTreeNode treeNode in tree.IterateNodesPostfix()) { 132 for (int i = 0; i < treeNode.SubtreeCount; i++) { 133 ISymbolicExpressionTreeNode subTree = treeNode.GetSubtree(i); 134 // only allow to replace nodes for which a replacement value is known (replacement value for ADF nodes are not available) 135 if (subTree == visualTreeNode.SymbolicExpressionTreeNode && replacementNodes.ContainsKey(subTree)) { 136 SwitchNodeWithReplacementNode(treeNode, i); 137 138 // show only interesting part of solution 139 if (tree.Root.SubtreeCount > 1) 140 this.treeChart.Tree = new SymbolicExpressionTree(tree.Root); // RPB + ADFs 141 else 142 this.treeChart.Tree = new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0)); // 1st child of RPB 143 144 updateInProgress = true; 145 UpdateModel(tree); 146 updateInProgress = false; 147 return; // break all loops 148 } 149 } 150 } 177 var parent = symbExprTreeNode.Parent; 178 int indexOfSubtree = parent.IndexOfSubtree(symbExprTreeNode); 179 if (changedNodes.ContainsKey(symbExprTreeNode)) { 180 // undo node change 181 parent.RemoveSubtree(indexOfSubtree); 182 var originalNode = changedNodes[symbExprTreeNode]; 183 parent.InsertSubtree(indexOfSubtree, originalNode); 184 changedNodes.Remove(symbExprTreeNode); 185 } else if (foldedNodes.ContainsKey(symbExprTreeNode)) { 186 // undo node folding 187 SwitchNodeWithReplacementNode(parent, indexOfSubtree); 188 } 189 UpdateModel(tree); 151 190 } 152 191 … … 154 193 ISymbolicExpressionTreeNode subTree = parent.GetSubtree(subTreeIndex); 155 194 parent.RemoveSubtree(subTreeIndex); 156 if ( replacementNodes.ContainsKey(subTree)) {157 var replacementNode = replacementNodes[subTree];195 if (foldedNodes.ContainsKey(subTree)) { 196 var replacementNode = foldedNodes[subTree]; 158 197 parent.InsertSubtree(subTreeIndex, replacementNode); 159 198 // exchange key and value 160 replacementNodes.Remove(subTree);161 replacementNodes.Add(replacementNode, subTree);199 foldedNodes.Remove(subTree); 200 foldedNodes.Add(replacementNode, subTree); 162 201 } 163 202 } … … 168 207 double min = impacts.Min(); 169 208 foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) { 209 VisualSymbolicExpressionTreeNode visualTree = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode); 210 170 211 if (!(treeNode is ConstantTreeNode) && nodeImpacts.ContainsKey(treeNode)) { 171 212 double impact = nodeImpacts[treeNode]; 172 VisualSymbolicExpressionTreeNode visualTree = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);173 213 174 214 // impact = 0 if no change … … 185 225 } 186 226 visualTree.ToolTip += Environment.NewLine + "Node impact: " + impact; 187 var constantReplacementNode = replacementNodes[treeNode] as ConstantTreeNode;227 var constantReplacementNode = foldedNodes[treeNode] as ConstantTreeNode; 188 228 if (constantReplacementNode != null) { 189 229 visualTree.ToolTip += Environment.NewLine + "Replacement value: " + constantReplacementNode.Value; 190 230 } 191 231 } 192 } 193 this.PaintCollapsedNodes(); 194 this.treeChart.Repaint(); 195 } 196 197 private void PaintCollapsedNodes() { 198 foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) { 199 if (treeNode is ConstantTreeNode && replacementNodes.ContainsKey(treeNode)) 200 this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = Color.DarkOrange; 201 else { 202 VisualSymbolicExpressionTreeNode visNode = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode); 203 if (visNode != null) 204 visNode.LineColor = Color.Black; 205 } 206 } 232 if (visualTree != null) 233 if (changedNodes.ContainsKey(treeNode)) { 234 visualTree.LineColor = Color.DodgerBlue; 235 } else if (treeNode is ConstantTreeNode && foldedNodes.ContainsKey(treeNode)) { 236 visualTree.LineColor = Color.DarkOrange; 237 } 238 } 239 treeChart.RepaintNodes(); 207 240 } 208 241 209 242 private void btnSimplify_Click(object sender, EventArgs e) { 210 SymbolicDataAnalysisExpressionTreeSimplifier simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier();243 var simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier(); 211 244 var simplifiedExpressionTree = simplifier.Simplify(Content.Model.SymbolicExpressionTree); 212 245 UpdateModel(simplifiedExpressionTree);
Note: See TracChangeset
for help on using the changeset viewer.