Changeset 7411


Ignore:
Timestamp:
01/25/12 17:26:29 (9 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.

Location:
branches/HeuristicLab.TreeSimplifierView
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.TreeSimplifierView/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionTreeChart.cs

    r7388 r7411  
    3232    private Dictionary<ISymbolicExpressionTreeNode, VisualSymbolicExpressionTreeNode> visualTreeNodes;
    3333    private Dictionary<Tuple<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>, VisualSymbolicExpressionTreeNodeConnection> visualLines;
    34     private VisualSymbolicExpressionTreeNode selectedNode = null;
     34    private VisualSymbolicExpressionTreeNode selectedNode;
    3535
    3636    public SymbolicExpressionTreeChart() {
  • branches/HeuristicLab.TreeSimplifierView/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj

    r7388 r7411  
    217217    </BootstrapperPackage>
    218218  </ItemGroup>
     219  <ItemGroup>
     220    <EmbeddedResource Include="InteractiveSymbolicDataAnalysisSolutionSimplifierView.resx">
     221      <DependentUpon>InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs</DependentUpon>
     222    </EmbeddedResource>
     223    <EmbeddedResource Include="SymbolicExpressionTreeNodeChangeValueDialog.resx">
     224      <DependentUpon>SymbolicExpressionTreeNodeChangeValueDialog.cs</DependentUpon>
     225    </EmbeddedResource>
     226  </ItemGroup>
    219227  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    220228  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
  • branches/HeuristicLab.TreeSimplifierView/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs

    r7388 r7411  
    5353      this.treeChart = new HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views.SymbolicExpressionTreeChart();
    5454      this.grpViewHost = new System.Windows.Forms.GroupBox();
     55      this.btnPrune = new System.Windows.Forms.Button();
     56      this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
    5557      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
    5658      this.splitContainer.Panel1.SuspendLayout();
     
    6466      // viewHost
    6567      //
    66       this.viewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
    67             | System.Windows.Forms.AnchorStyles.Left)
     68      this.viewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
     69            | System.Windows.Forms.AnchorStyles.Left) 
    6870            | System.Windows.Forms.AnchorStyles.Right)));
    6971      this.viewHost.Caption = "View";
     
    9799      // grpSimplify
    98100      //
     101      this.grpSimplify.AutoSize = true;
    99102      this.grpSimplify.Controls.Add(this.flowLayoutPanel);
    100103      this.grpSimplify.Controls.Add(this.treeChart);
     
    109112      // flowLayoutPanel
    110113      //
    111       this.flowLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
     114      this.flowLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
    112115            | System.Windows.Forms.AnchorStyles.Right)));
    113116      this.flowLayoutPanel.Controls.Add(this.btnSimplify);
     117      this.flowLayoutPanel.Controls.Add(this.btnPrune);
    114118      this.flowLayoutPanel.Controls.Add(this.btnOptimizeConstants);
    115119      this.flowLayoutPanel.Location = new System.Drawing.Point(6, 313);
     
    133137      this.btnOptimizeConstants.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
    134138      this.btnOptimizeConstants.Enabled = false;
    135       this.btnOptimizeConstants.Location = new System.Drawing.Point(104, 3);
     139      this.btnOptimizeConstants.Location = new System.Drawing.Point(205, 3);
    136140      this.btnOptimizeConstants.Name = "btnOptimizeConstants";
    137141      this.btnOptimizeConstants.Size = new System.Drawing.Size(97, 23);
     
    143147      // treeChart
    144148      //
    145       this.treeChart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
    146             | System.Windows.Forms.AnchorStyles.Left)
     149      this.treeChart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
     150            | System.Windows.Forms.AnchorStyles.Left) 
    147151            | System.Windows.Forms.AnchorStyles.Right)));
    148152      this.treeChart.BackgroundColor = System.Drawing.Color.White;
     
    171175      this.grpViewHost.Text = "Details";
    172176      //
     177      // btnPrune
     178      //
     179      this.btnPrune.Location = new System.Drawing.Point(104, 3);
     180      this.btnPrune.Name = "btnPrune";
     181      this.btnPrune.Size = new System.Drawing.Size(95, 23);
     182      this.btnPrune.TabIndex = 3;
     183      this.btnPrune.Text = "Prune";
     184      this.btnPrune.UseVisualStyleBackColor = true;
     185      this.btnPrune.Click += new System.EventHandler(this.btnPrune_Click);
     186      //
     187      // backgroundWorker1
     188      //
     189      this.backgroundWorker1.WorkerSupportsCancellation = true;
     190      this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
     191      this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
     192      //
    173193      // InteractiveSymbolicDataAnalysisSolutionSimplifierView
    174194      //
     
    179199      this.Size = new System.Drawing.Size(564, 348);
    180200      this.splitContainer.Panel1.ResumeLayout(false);
     201      this.splitContainer.Panel1.PerformLayout();
    181202      this.splitContainer.Panel2.ResumeLayout(false);
    182203      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
     
    199220    private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel;
    200221    protected System.Windows.Forms.Button btnOptimizeConstants;
     222    private System.Windows.Forms.Button btnPrune;
     223    private System.ComponentModel.BackgroundWorker backgroundWorker1;
    201224  }
    202225}
  • 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}
  • branches/HeuristicLab.TreeSimplifierView/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SymbolicExpressionTreeNodeChangeValueDialog.Designer.cs

    r7388 r7411  
    4646    private void InitializeComponent() {
    4747      this.components = new System.ComponentModel.Container();
    48       this.okButton = new System.Windows.Forms.Button();
    49       this.oldValueLabel = new System.Windows.Forms.Label();
    50       this.oldValueTextBox = new System.Windows.Forms.TextBox();
     48      this.originalValueLabel = new System.Windows.Forms.Label();
     49      this.originalValueTextBox = new System.Windows.Forms.TextBox();
    5150      this.newValueTextBox = new System.Windows.Forms.TextBox();
    5251      this.newValueLabel = new System.Windows.Forms.Label();
     
    5554      this.SuspendLayout();
    5655      //
    57       // okButton
     56      // originalValueLabel
    5857      //
    59       this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
    60       this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
    61       this.okButton.Enabled = false;
    62       this.okButton.Location = new System.Drawing.Point(66, 74);
    63       this.okButton.Name = "okButton";
    64       this.okButton.Size = new System.Drawing.Size(75, 23);
    65       this.okButton.TabIndex = 0;
    66       this.okButton.Text = "&OK";
    67       this.okButton.UseVisualStyleBackColor = true;
    68       this.okButton.Click += new System.EventHandler(this.okButton_Click);
     58      this.originalValueLabel.AutoSize = true;
     59      this.originalValueLabel.Location = new System.Drawing.Point(14, 15);
     60      this.originalValueLabel.Name = "originalValueLabel";
     61      this.originalValueLabel.Size = new System.Drawing.Size(72, 13);
     62      this.originalValueLabel.TabIndex = 2;
     63      this.originalValueLabel.Text = "Original Value";
    6964      //
    70       // oldValueLabel
     65      // originalValueTextBox
    7166      //
    72       this.oldValueLabel.AutoSize = true;
    73       this.oldValueLabel.Location = new System.Drawing.Point(14, 15);
    74       this.oldValueLabel.Name = "oldValueLabel";
    75       this.oldValueLabel.Size = new System.Drawing.Size(53, 13);
    76       this.oldValueLabel.TabIndex = 2;
    77       this.oldValueLabel.Text = "Old Value";
    78       //
    79       // oldValueTextBox
    80       //
    81       this.oldValueTextBox.Location = new System.Drawing.Point(91, 12);
    82       this.oldValueTextBox.Name = "oldValueTextBox";
    83       this.oldValueTextBox.ReadOnly = true;
    84       this.oldValueTextBox.Size = new System.Drawing.Size(100, 20);
    85       this.oldValueTextBox.TabIndex = 3;
     67      this.originalValueTextBox.Location = new System.Drawing.Point(91, 12);
     68      this.originalValueTextBox.Name = "originalValueTextBox";
     69      this.originalValueTextBox.ReadOnly = true;
     70      this.originalValueTextBox.Size = new System.Drawing.Size(100, 20);
     71      this.originalValueTextBox.TabIndex = 3;
    8672      //
    8773      // newValueTextBox
     
    9076      this.newValueTextBox.Name = "newValueTextBox";
    9177      this.newValueTextBox.Size = new System.Drawing.Size(100, 20);
    92       this.newValueTextBox.TabIndex = 4;
     78      this.newValueTextBox.TabIndex = 0;
    9379      this.newValueTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.newValueTextBox_KeyDown);
    9480      this.newValueTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.newValueTextBox_Validating);
     
    9884      //
    9985      this.newValueLabel.AutoSize = true;
    100       this.newValueLabel.Location = new System.Drawing.Point(8, 41);
     86      this.newValueLabel.Location = new System.Drawing.Point(14, 41);
    10187      this.newValueLabel.Name = "newValueLabel";
    10288      this.newValueLabel.Size = new System.Drawing.Size(59, 13);
     
    115101      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    116102      this.AutoSize = true;
    117       this.ClientSize = new System.Drawing.Size(209, 109);
     103      this.ClientSize = new System.Drawing.Size(209, 71);
    118104      this.Controls.Add(this.newValueLabel);
    119105      this.Controls.Add(this.newValueTextBox);
    120       this.Controls.Add(this.oldValueTextBox);
    121       this.Controls.Add(this.oldValueLabel);
    122       this.Controls.Add(this.okButton);
     106      this.Controls.Add(this.originalValueTextBox);
     107      this.Controls.Add(this.originalValueLabel);
    123108      this.MaximizeBox = false;
    124109      this.MinimizeBox = false;
     
    136121    #endregion
    137122
    138     protected System.Windows.Forms.Button okButton;
    139     private System.Windows.Forms.Label oldValueLabel;
    140     private System.Windows.Forms.TextBox oldValueTextBox;
     123    private System.Windows.Forms.Label originalValueLabel;
     124    private System.Windows.Forms.TextBox originalValueTextBox;
    141125    private System.Windows.Forms.TextBox newValueTextBox;
    142126    private System.Windows.Forms.Label newValueLabel;
  • branches/HeuristicLab.TreeSimplifierView/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SymbolicExpressionTreeNodeChangeValueDialog.cs

    r7388 r7411  
    2424using System.Text;
    2525using System.Windows.Forms;
    26 using HeuristicLab.Common;
    2726using HeuristicLab.Data;
    2827
     
    3837      }
    3938    }
    40     public string OldValue {
    41       get { return oldValueTextBox.Text; }
     39    public string OriginalValue {
     40      get { return originalValueTextBox.Text; }
    4241      set {
    4342        if (InvokeRequired)
    4443          Invoke(new Action<string>(x => this.NewValue = x), value);
    4544        else
    46           oldValueTextBox.Text = value;
     45          originalValueTextBox.Text = value;
    4746      }
    4847    }
     
    5655      }
    5756    }
     57    public TextBox NewValueTextBox {
     58      get { return newValueTextBox; }
     59    }
    5860
    5961    public ValueChangeDialog() {
    6062      InitializeComponent();
     63      originalValueTextBox.TabStop = false; // cannot receive focus using tab key
    6164    }
    62     public ValueChangeDialog(string caption, string oldValue)
     65    public ValueChangeDialog(string caption, string originalValue, string newValue)
    6366      : this() {
    6467      Caption = caption;
    65       OldValue = oldValue;
    66       NewValue = string.Empty;
     68      OriginalValue = originalValue;
     69      NewValue = newValue;
    6770    }
    6871
     
    8487      if (!Validate(newValueTextBox.Text, out errorMessage)) {
    8588        e.Cancel = true;
    86         okButton.Enabled = false;
    8789        errorProvider.SetError(newValueTextBox, errorMessage);
    8890        newValueTextBox.SelectAll();
     
    9193    private void newValueTextBox_Validated(object sender, EventArgs e) {
    9294      errorProvider.SetError(newValueTextBox, string.Empty);
    93       okButton.Enabled = true;
    9495    }
    9596
Note: See TracChangeset for help on using the changeset viewer.