Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
01/25/12 17:26:29 (12 years ago)
Author:
bburlacu
Message:

#1763: Improved ValueChangeDialog and overall behavior. Implemented pruning operation on background thread. TODO: Test, improve. This is a work-in-progress.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.TreeSimplifierView/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs

    r7388 r7411  
    2222using System;
    2323using System.Collections.Generic;
     24using System.ComponentModel;
    2425using System.Drawing;
    2526using System.Linq;
     
    3637    private Dictionary<ISymbolicExpressionTreeNode, double> originalValues;
    3738    private bool updateInProgress = false;
     39    private VisualSymbolicExpressionTreeNode visualTreeNode; // need some kind of state for correctly handling events
    3840
    3941    public InteractiveSymbolicDataAnalysisSolutionSimplifierView() {
     
    129131
    130132    private void treeChart_SymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) {
    131       VisualSymbolicExpressionTreeNode visualTreeNode = (VisualSymbolicExpressionTreeNode)sender;
     133      visualTreeNode = (VisualSymbolicExpressionTreeNode)sender;
    132134      var tree = Content.Model.SymbolicExpressionTree;
    133135      // check if the node value/weight has been altered
     
    189191
    190192    private void treeChart_SymbolicExpressionTreeNodeChanged(object sender, EventArgs e) {
    191       var tree = Content.Model.SymbolicExpressionTree;
    192       var visualTreeNode = sender as VisualSymbolicExpressionTreeNode;
     193      visualTreeNode = sender as VisualSymbolicExpressionTreeNode;
    193194      var subTree = visualTreeNode.SymbolicExpressionTreeNode;
    194195      string title = String.Empty;
     
    203204      }
    204205
     206      double originalValue = value;
     207
    205208      if (!originalValues.ContainsKey(subTree))
    206209        originalValues.Add(subTree, value);
    207       var dialog = new ValueChangeDialog(title, Math.Round(value,4).ToString());
     210      else originalValue = originalValues[subTree];
     211
     212      var dialog = new ValueChangeDialog(title, Math.Round(originalValue, 4).ToString(), Math.Round(value, 4).ToString());
     213      dialog.NewValueTextBox.Validated += OnNewValueValidated;
    208214      dialog.ShowDialog(this);
    209       if (dialog.DialogResult == DialogResult.OK) {
    210         value = double.Parse(dialog.NewValue);
    211         if (subTree.Symbol is Constant)
    212           (subTree as ConstantTreeNode).Value = value;
    213         else if (subTree.Symbol is Variable)
    214           (subTree as VariableTreeNode).Weight = value;
    215         // show only interesting part of solution
    216         treeChart.Tree = tree.Root.SubtreeCount > 1 ? new SymbolicExpressionTree(tree.Root) : new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0));
    217         updateInProgress = true;
    218         UpdateModel(tree);
    219         updateInProgress = false;
    220       }
     215    }
     216
     217    private void OnNewValueValidated(object sender, EventArgs e) {
     218      var textBox = sender as TextBox;
     219      var value = double.Parse(textBox.Text);
     220      var subTree = visualTreeNode.SymbolicExpressionTreeNode;
     221      var tree = Content.Model.SymbolicExpressionTree;
     222
     223      if (subTree.Symbol is Constant)
     224        (subTree as ConstantTreeNode).Value = value;
     225      else if (subTree.Symbol is Variable)
     226        (subTree as VariableTreeNode).Weight = value;
     227
     228      // show only interesting part of solution
     229      treeChart.Tree = tree.Root.SubtreeCount > 1 ? new SymbolicExpressionTree(tree.Root) : new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0));
     230      updateInProgress = true;
     231      UpdateModel(tree);
     232      updateInProgress = false;
    221233    }
    222234
     
    238250      double min = impacts.Min();
    239251      foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
     252        VisualSymbolicExpressionTreeNode visualTree = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
     253        bool flag1 = replacementNodes.ContainsKey(treeNode);
     254        bool flag2 = originalValues.ContainsKey(treeNode);
     255        bool flag3 = treeNode is ConstantTreeNode;
     256
     257        if (flag2) // constant or variable node was changed
     258          visualTree.ToolTip += Environment.NewLine + "Original value: " + originalValues[treeNode];
     259        else if (flag1 && flag3) // node was folded to a constant
     260          visualTree.ToolTip += Environment.NewLine + "Original node: " + replacementNodes[treeNode];
     261
    240262        if (!(treeNode is ConstantTreeNode) && nodeImpacts.ContainsKey(treeNode)) {
    241263          double impact = nodeImpacts[treeNode];
    242           VisualSymbolicExpressionTreeNode visualTree = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
    243264
    244265          // impact = 0 if no change
     
    267288    private void PaintCollapsedNodes() {
    268289      foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
    269         if (originalValues.ContainsKey(treeNode))
    270           this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = Color.Blue;
    271         else if (treeNode is ConstantTreeNode && replacementNodes.ContainsKey(treeNode))
    272           this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = Color.DarkOrange;
    273         else {
    274           VisualSymbolicExpressionTreeNode visNode = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
    275           if (visNode != null)
    276             visNode.LineColor = Color.Black;
     290        bool flag1 = replacementNodes.ContainsKey(treeNode);
     291        bool flag2 = originalValues.ContainsKey(treeNode);
     292        if (flag1 && treeNode is ConstantTreeNode) {
     293          this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = flag2 ? Color.DarkViolet : Color.DarkOrange;
     294        } else if (flag2) {
     295          this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = Color.DodgerBlue;
    277296        }
    278297      }
     
    285304    }
    286305
     306    private void btnPrune_Click(object sender, EventArgs e) {
     307      backgroundWorker1.RunWorkerAsync();
     308    }
     309
     310    private static IEnumerable<ISymbolicExpressionTreeNode> GetNodesAtDepth(ISymbolicExpressionTreeNode root, Data.IntRange range) {
     311      var list = new List<Tuple<ISymbolicExpressionTreeNode, int>> { new Tuple<ISymbolicExpressionTreeNode, int>(root, 0) };
     312      int offset = 0;
     313      int level = 0;
     314      while (level < range.End) {
     315        ++level;
     316        int count = list.Count;
     317        for (int i = offset; i != count; ++i) {
     318          if (list[i].Item1.Subtrees.Any())
     319            list.AddRange(from s in list[i].Item1.Subtrees select new Tuple<ISymbolicExpressionTreeNode, int>(s, level));
     320        }
     321        offset = count;
     322      }
     323      // taking advantage of the fact that the list is already sorted by level
     324      for (int i = list.Count - 1; i >= 0; --i) {
     325        if (list[i].Item2 >= range.Start)
     326          yield return list[i].Item1;
     327        else break;
     328      }
     329    }
     330
    287331    protected abstract void btnOptimizeConstants_Click(object sender, EventArgs e);
     332
     333    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
     334      BackgroundWorker worker = sender as BackgroundWorker;
     335      PruneTree(worker);
     336
     337    }
     338
     339    private void PruneTree(BackgroundWorker worker) {
     340      var tree = Content.Model.SymbolicExpressionTree;
     341      // get all tree nodes
     342      foreach (var node in GetNodesAtDepth(tree.Root, new Data.IntRange(2, tree.Depth))) {
     343        if (worker.CancellationPending)
     344          break; // pruning cancelled
     345        if (!(node.Symbol is Constant) && nodeImpacts.ContainsKey(node) && nodeImpacts[node] < 0.001) {
     346          SwitchNodeWithReplacementNode(node.Parent, node.Parent.IndexOfSubtree(node));
     347          CalculateReplacementNodesAndNodeImpacts();
     348        }
     349      }
     350    }
     351
     352    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
     353      if (e.Cancelled) {
     354        // The user canceled the operation.
     355      } else if (e.Error != null) {
     356        // There was an error during the operation.
     357        // Error-handling
     358      } else {
     359        // The operation completed normally. We can update the model
     360        UpdateModel(Content.Model.SymbolicExpressionTree);
     361      }
     362    }
    288363  }
    289364}
Note: See TracChangeset for help on using the changeset viewer.