Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
03/29/15 23:40:57 (10 years ago)
Author:
bburlacu
Message:

#1772: Some more work on subtree sample counting.

Location:
branches/HeuristicLab.EvolutionTracking
Files:
1 deleted
3 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.EvolutionTracking/3.4/Analyzers/GenealogyAnalyzer.cs

    r11769 r12265  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Tracking/SymbolicDataAnalysisGenealogyGraphView.cs

    r12231 r12265  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    8484      nodeWeightLabel.Text = String.Format("{0:0.00}", graphNode.Weight);
    8585
     86      if (!graphNode.InArcs.Any()) return;
     87
    8688      if (openNew_CheckBox.Checked) {
    8789        // get the ancestors into a new view
     
    9698      }
    9799
    98       if (graphNode.InArcs.Any()) {
    99         var data = graphNode.InArcs.Last().Data;
    100         var fragment = data as IFragment<ISymbolicExpressionTreeNode>;
    101         var td = data as TraceData;
    102         //        double max = Content.Vertices.Max(x => x.Data.IterateNodesPrefix().Max(y => y.NodeWeight));
    103 
    104         // calculate max only in the current generation
    105         double max = Content.GetByRank(graphNode.Rank).Max(x => ((IGenealogyGraphNode<ISymbolicExpressionTree>)x).Data.IterateNodesPrefix().Max(y => y.NodeWeight));
    106         if (max.IsAlmost(0)) max = 1;
    107         int c = ColorGradient.Colors.Count - 1;
    108         const int alpha = 100;
    109         if (fragment != null) {
    110           // highlight the fragment with a blue line color
    111           foreach (var n in graphNode.Data.NodeAt(fragment.Index1).IterateNodesPrefix()) {
    112             treeChart_HighlightSubtree(n, Color.CornflowerBlue);
    113           }
    114           // highlight all the nodes according to their sample count
    115           var nodes = graphNode.Data.IterateNodesPrefix().ToList();
    116           foreach (var n in nodes.Skip(1)) {
    117             var i = (int)Math.Round(n.NodeWeight / max * c);
    118             var fillColor = Color.FromArgb(alpha, ColorGradient.Colors[i]);
    119             treeChart_HighlightSubtree(n, null, fillColor);
    120           }
    121         } else if (td != null) {
    122           var nodes = graphNode.Data.IterateNodesPrefix().ToList();
    123           foreach (var n in nodes.Skip(1)) { // skip program root symbol
    124             var i = (int)Math.Round(n.NodeWeight / max * c);
    125             var fillColor = Color.FromArgb(alpha, ColorGradient.Colors[i]);
    126             treeChart_HighlightSubtree(n, null, fillColor);
    127           }
    128           treeChart_HighlightSubtree(nodes[td.LastSubtreeIndex], Color.Orange);
    129           treeChart_HighlightSubtree(nodes[td.LastFragmentIndex], Color.CornflowerBlue);
    130         }
    131       }
    132     }
     100      var data = graphNode.InArcs.Last().Data;
     101      var fragment = data as IFragment<ISymbolicExpressionTreeNode>;
     102      var td = data as TraceData;
     103      // calculate max only in the current generation
     104      var max = Content.GetByRank(graphNode.Rank).Max(x => ((IGenealogyGraphNode<ISymbolicExpressionTree>)x).Data.IterateNodesPrefix().Max(y => y.NodeWeight));
     105      //      var max = Content.GetByRank(graphNode.Rank).Max(x => x.Weight);
     106
     107      if (max.IsAlmost(0))
     108        max = 1;
     109
     110      int colorCount = ColorGradient.Colors.Count - 1;
     111      const int alpha = 100;
     112      if (fragment != null) {
     113        // highlight the fragment with a blue line color
     114        foreach (var n in graphNode.Data.NodeAt(fragment.Index1).IterateNodesPrefix()) {
     115          treeChart_HighlightSubtree(n, Color.CornflowerBlue);
     116        }
     117        // highlight all the nodes according to their sample count
     118        var nodes = graphNode.Data.IterateNodesPrefix().ToList();
     119        foreach (var n in nodes.Skip(1)) {
     120          var i = (int)Math.Round(n.NodeWeight / max * colorCount);
     121          var fillColor = Color.FromArgb(alpha, ColorGradient.Colors[i]);
     122          treeChart_HighlightSubtree(n, null, fillColor);
     123        }
     124      } else if (td != null) {
     125        var nodes = graphNode.Data.IterateNodesPrefix().ToList();
     126        foreach (var n in nodes.Skip(1)) { // skip program root symbol
     127          var i = (int)Math.Round(n.NodeWeight / max * colorCount);
     128          var fillColor = Color.FromArgb(alpha, ColorGradient.Colors[i]);
     129          treeChart_HighlightSubtree(n, null, fillColor);
     130        }
     131        treeChart_HighlightSubtree(nodes[td.LastSubtreeIndex], Color.Orange);
     132        treeChart_HighlightSubtree(nodes[td.LastFragmentIndex], Color.CornflowerBlue);
     133      }
     134    }
     135
     136    #region specific symbolic expression tree node click actions
     137    private void OnTreeNodeLeftClicked(ISymbolicExpressionTreeNode node) {
     138      SelectedSubtree = node;
     139      bool trace = genealogyGraphChart.TraceFragments;
     140
     141      // check whether we are in 'trace' or 'match' mode
     142      if (trace) {
     143        // TODO: maybe highlight based on per generation maximum
     144        //        double max = Content.Vertices.Max(x => x.Data.IterateNodesPrefix().Average(y => y.NodeWeight));
     145        // perform fragment tracing
     146        var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
     147        var max = Content.GetByRank(graphNode.Rank).Max(x => x.Weight);
     148        var subtreeIndex = graphNode.Data.IterateNodesPrefix().ToList().IndexOf(node);
     149        var traceGraph = TraceCalculator.TraceSubtree(graphNode, subtreeIndex, updateVertexWeights: false, updateSubtreeWeights: false, cacheTraceNodes: true);
     150        if (traceGraph.Vertices.Any()) {
     151          var vertices = traceGraph.Vertices.Select(x => Content.GetByContent(x.Data));
     152          genealogyGraphChart.UpdateEnabled = false;
     153          genealogyGraphChart.ClearPrimitives();
     154          foreach (var v in vertices) {
     155            var vNode = genealogyGraphChart.GetMappedNode(v);
     156            var wSum = v.Data.IterateNodesPrefix().Average(x => x.NodeWeight);
     157            // use a grayscale gradient
     158            var color = ColorGradient.GrayscaledColors[(int)Math.Round(wSum / max * (ColorGradient.GrayscaledColors.Count - 1))];
     159            vNode.Brush = new SolidBrush(color);
     160          }
     161          genealogyGraphChart.UpdateEnabled = true;
     162          genealogyGraphChart.EnforceUpdate();
     163
     164          if (openNew_CheckBox.Checked) {
     165            MainFormManager.MainForm.ShowContent(traceGraph); // display the fragment graph on the screen
     166          }
     167        }
     168      } else {
     169        // perform matching like it was done before
     170        // currently there is no possibility to specify the subtree matching criteria
     171        var trees = Content.Vertices.Select(x => x.Data);
     172        var matchingTrees = trees.Where(x => x.Root.ContainsSubtree(node, comparer));
     173
     174        var matchingVertices = matchingTrees.Select(x => Content.GetByContent(x));
     175        graphChart_HighlightMatchingVertices(matchingVertices);
     176      }
     177    }
     178
     179    private void OnTreeNodeMiddleClicked(ISymbolicExpressionTreeNode node) {
     180      var index = SelectedSubtree.IterateNodesPrefix().ToList().IndexOf(node);
     181      if (index > 0) {
     182        var s = ClonedSubtree.NodeAt(index);
     183        s.Parent.RemoveSubtree(s.Parent.IndexOfSubtree(s));
     184
     185        var trees = Content.Vertices.Select(x => x.Data);
     186        var matchingTrees = trees.Where(x => x.Root.ContainsSubtree(ClonedSubtree, comparer));
     187
     188        var matchingVertices = matchingTrees.Select(x => Content.GetByContent(x));
     189        treeChart_HighlightSubtree(node, Color.Black, Color.White);
     190        graphChart_HighlightMatchingVertices(matchingVertices);
     191      }
     192    }
     193    #endregion
    133194
    134195    public void treeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs args) {
     
    139200      treeChart_HighlightSubtree(subtree, Color.Black, Color.RoyalBlue);
    140201
    141       bool trace = genealogyGraphChart.TraceFragments; // check whether we are in 'trace' or 'match' mode
    142 
    143202      switch (args.Button) {
    144203        case MouseButtons.Left: {
    145             SelectedSubtree = subtree;
    146             if (trace) {
    147               // TODO: maybe highlight based on per generation maximum
    148               double max = Content.Vertices.Max(x => x.Data.IterateNodesPrefix().Average(y => y.NodeWeight));
    149               // perform fragment tracing
    150               var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
    151               var subtreeIndex = graphNode.Data.IterateNodesPrefix().ToList().IndexOf(subtree);
    152               var traceGraph = TraceCalculator.TraceSubtree(graphNode, subtreeIndex, updateVertexWeights: false, updateSubtreeWeights: false, cacheTraceNodes: true);
    153               if (traceGraph.Vertices.Any()) {
    154                 var vertices = traceGraph.Vertices.Select(x => Content.GetByContent(x.Data));
    155                 genealogyGraphChart.UpdateEnabled = false;
    156                 genealogyGraphChart.ClearPrimitives();
    157                 foreach (var v in vertices) {
    158                   var vNode = genealogyGraphChart.GetMappedNode(v);
    159                   var wSum = v.Data.IterateNodesPrefix().Average(x => x.NodeWeight);
    160                   // use a grayscal gradient
    161                   var color = ColorGradient.GrayscaledColors[(int)Math.Round(wSum / max * (ColorGradient.GrayscaledColors.Count - 1))];
    162                   vNode.Brush = new SolidBrush(color);
    163                 }
    164                 genealogyGraphChart.UpdateEnabled = true;
    165                 genealogyGraphChart.EnforceUpdate();
    166 
    167                 if (openNew_CheckBox.Checked) {
    168                   MainFormManager.MainForm.ShowContent(traceGraph); // display the fragment graph on the screen
    169                 }
    170               }
    171             } else {
    172               // perform matching like it was done before
    173               // currently there is no possibility to specify the subtree matching criteria
    174               var trees = Content.Vertices.Select(x => x.Data);
    175               var matchingTrees = trees.Where(x => x.Root.ContainsSubtree(subtree, comparer));
    176 
    177               var matchingVertices = matchingTrees.Select(x => Content.GetByContent(x));
    178               graphChart_HighlightMatchingVertices(matchingVertices);
    179             }
     204            OnTreeNodeLeftClicked(subtree);
    180205            break;
    181206          }
    182207        case MouseButtons.Middle: {
    183             var index = SelectedSubtree.IterateNodesPrefix().ToList().IndexOf(subtree);
    184             if (index > 0) {
    185               var s = ClonedSubtree.NodeAt(index);
    186               s.Parent.RemoveSubtree(s.Parent.IndexOfSubtree(s));
    187 
    188               var trees = Content.Vertices.Select(x => x.Data);
    189               var matchingTrees = trees.Where(x => x.Root.ContainsSubtree(ClonedSubtree, comparer));
    190 
    191               var matchingVertices = matchingTrees.Select(x => Content.GetByContent(x));
    192               treeChart_HighlightSubtree(subtree, Color.Black, Color.White);
    193               graphChart_HighlightMatchingVertices(matchingVertices);
    194             }
     208            OnTreeNodeMiddleClicked(subtree);
    195209            break;
    196210          }
     
    260274    private void navigateRightButton_Click(object sender, EventArgs e) {
    261275      var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
    262       var inArcs = graphNode.InArcs.ToList();
     276      var inArcs = (List<IArc>)((IVertex)graphNode).InArcs;
    263277      if (inArcs.Count > 0) {
    264         var data = inArcs.Last().Data;
    265         var fragment = (data as IFragment<ISymbolicExpressionTreeNode>);
    266         var td = data as TraceData;
     278        if (inArcs.Count == 1) {
     279          genealogyGraphChart.SelectedGraphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs[0].Source;
     280          return;
     281        }
     282        IGenealogyGraphNode<ISymbolicExpressionTree> source = null;
     283        var fragment = ((IArc<IDeepCloneable>)inArcs.Last()).Data as IFragment<ISymbolicExpressionTreeNode>;
     284        var traceData = ((IArc<IDeepCloneable>)inArcs[0]).Data as TraceData;
    267285        if (fragment != null) {
    268           genealogyGraphChart.SelectedGraphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs.Last().Source;
    269         } else if (td != null) {
    270           if (inArcs.Count == 1) {
    271             genealogyGraphChart.SelectedGraphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs[0].Source;
    272             return;
    273           }
    274           // the first arc from inArcs will always represent the connection to the root parent
    275           // (tracing the body of the traced subtree)
    276           // therefore, in order to follow the correct non-root parent, we have to find the correct arc
    277           // But, the FragmentIndex recorded in the TraceData of the first arc has to match the SubtreeIndex recorded in the TraceData of the searched arc
    278           td = (TraceData)inArcs[0].Data;
    279           var f1 = (graphNode.Data).NodeAt(td.LastFragmentIndex);
    280           for (int i = 1; i < inArcs.Count; ++i) {
    281             td = (TraceData)inArcs[i].Data;
    282             var f2 = ((IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs[i].Source).Data.NodeAt(td.SubtreeIndex);
    283             // if the subtrees are the same we have found a match
    284             // note: this is not necessarily 100% correct if in the trace graph we have identical fragments on different arcs
    285             if (f1.Difference(f2) == null) {
    286               genealogyGraphChart.SelectedGraphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs[i].Source;
    287               return;
    288             }
    289           }
    290           throw new InvalidOperationException("Error calculating the next step.");
    291         }
     286          source = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs.Last().Source;
     287        }
     288        if (traceData != null) {
     289          var f = graphNode.Data.NodeAt(traceData.LastFragmentIndex);
     290          var selected = inArcs.Skip(1).First(x => {
     291            var td = (TraceData)((IArc<IDeepCloneable>)x).Data;
     292            var s = (IGenealogyGraphNode<ISymbolicExpressionTree>)x.Source;
     293            return f.Difference(s.Data.NodeAt(td.SubtreeIndex)) == null;
     294          });
     295          source = (IGenealogyGraphNode<ISymbolicExpressionTree>)selected.Source;
     296        }
     297        if (source != null)
     298          genealogyGraphChart.SelectedGraphNode = source;
    292299      }
    293300    }
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/Analyzers/SymbolicDataAnalysisSubtreeSampleCountAnalyzer.cs

    r12225 r12265  
    1 #region License Information
     1#region License information
    22/* HeuristicLab
    33 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     
    2626using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2727using HeuristicLab.EvolutionTracking;
     28using HeuristicLab.Parameters;
    2829using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2930
     
    3233  [StorableClass]
    3334  public class SymbolicDataAnalysisSubtreeSampleCountAnalyzer : EvolutionTrackingAnalyzer<ISymbolicExpressionTree> {
     35    private const string CacheTraceNodesParameterName = "CacheTraceNodes";
    3436    private readonly TraceCalculator traceCalculator = new TraceCalculator { UpdateVertexWeights = true, UpdateSubtreeWeights = true, CacheTraceNodes = true };
    3537
     38    #region parameters
     39    public IFixedValueParameter<BoolValue> CacheTraceNodesParameter {
     40      get { return (IFixedValueParameter<BoolValue>)Parameters[CacheTraceNodesParameterName]; }
     41    }
     42    #endregion
     43
     44    #region parameter properties
     45    public bool CacheTraceNodes {
     46      get { return CacheTraceNodesParameter.Value.Value; }
     47      set { CacheTraceNodesParameter.Value.Value = value; }
     48    }
     49    #endregion
     50
    3651    public SymbolicDataAnalysisSubtreeSampleCountAnalyzer() {
    37       UpdateCounterParameter.ActualName = "TraceOverlapAnalyzerUpdateCounter";
     52      UpdateCounterParameter.ActualName = "SubtreeSampleCountAnalyzerUpdateCounter";
     53
     54      Parameters.Add(new FixedValueParameter<BoolValue>(CacheTraceNodesParameterName, new BoolValue(true)));
    3855    }
    3956
     
    7794        return base.Apply();
    7895
    79       double avgTraceOverlap = 0;
    80 
     96      traceCalculator.CacheTraceNodes = CacheTraceNodes;
    8197      if (Generation.Value > 0) {
    8298        var rank = PopulationGraph.GetByRank(Generation.Value).Cast<IGenealogyGraphNode<ISymbolicExpressionTree>>().ToList();
    83         foreach (var n in rank) {
    84           // during the trace the SymbolicExpressionTreeNode weights will be updated behind the scenes
    85           // the weights represent the sample count of each subtree
    86           var trace = traceCalculator.Trace(n, 2, false);
    87           foreach (var v in trace.Vertices) {
    88             var g = PopulationGraph.GetByContent(v.Data);
    89             g.Weight = v.Weight;
    90           }
     99        foreach (var n in rank)
     100          traceCalculator.Trace(n, 2, false); // during this call weights will be updated
     101
     102        foreach (var v in traceCalculator.TraceGraph.Vertices) {
     103          var g = PopulationGraph.GetByContent(v.Data);
     104          g.Weight = v.Weight;
    91105        }
    92106      }
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/TraceCalculator.cs

    r12231 r12265  
    155155                traceCache.Add(t1);
    156156              }
    157               // gather statistics about sampled individuals and sampled subtrees
    158               if (UpdateVertexWeights)
    159                 n.Weight++;
    160               if (UpdateSubtreeWeights) {
    161                 var arcs = (List<IArc>)((IVertex)n).InArcs; // at this moment n will have been added as a child to the next trace node
    162 
    163                 // TODO: try to simplify the code below
    164                 for (int i = 0; i < arcs.Count; ++i) {
    165                   var td = (TraceData)((IArc<IDeepCloneable>)arcs[i]).Data;
    166                   var p = (IGenealogyGraphNode<ISymbolicExpressionTree>)arcs[i].Source;
    167                   var s = NodeAt(p.Data, td.SubtreeIndex);
    168                   if (td.LastFragmentIndex == td.SubtreeIndex && fragment.Root.Difference(s) == null) {
    169                     foreach (var ss in s.IterateNodesPrefix()) ss.NodeWeight++; // the node weight will represent the total sample count for a given node
    170                     arcs[i].Weight++; // the arc weights (since there are multiple arcs) will sum up to the same count but give more detail
    171                     break;
    172                   }
    173                 }
    174               }
    175157              break;
    176158            } else {
     
    197179              traceCache.Add(t);
    198180            }
    199             if (UpdateVertexWeights)
    200               n.Weight++;
    201181            break;
    202182          } else {
     
    257237    /// <param name="si">The index of the traced subtree</param>
    258238    /// <param name="fi">The index of the fragment</param>
    259     private void ConnectLast(IGenealogyGraphNode<ISymbolicExpressionTree> current,
    260       IGenealogyGraphNode<ISymbolicExpressionTree> last, int si, int fi) {
     239    private void ConnectLast(IGenealogyGraphNode<ISymbolicExpressionTree> current, IGenealogyGraphNode<ISymbolicExpressionTree> last, int si, int fi) {
    261240      var lastTraceData = traceMap[last];
    262241      int lastSi = lastTraceData.SubtreeIndex; // last subtree index (index of the traced subtree in the previous trace node)
    263242      int lastFi = lastTraceData.FragmentIndex; // last fragment index (index of the fragment in the previous trace node)
    264243      var td = new TraceData(si, fi, lastSi, lastFi); // trace data
    265       // using the inArcs seems to be slightly more efficient than using the outArcs
     244
    266245      // TODO: more testing
    267       var inArcs = (List<IArc>)((IVertex)last).InArcs;
     246      var inArcs = (List<IArc>)((IVertex)last).InArcs; // using the InArcs seems to be slightly more efficient than using the OutArcs
    268247      var arc = inArcs.FirstOrDefault(a => a.Source == current && ((IArc<IDeepCloneable>)a).Data.Equals(td));
    269248      if (arc == null) {
    270249        arc = new GenealogyGraphArc(current, last) { Data = td };
    271250        TraceGraph.AddArc(arc);
     251      } else {
     252        if (UpdateVertexWeights) {
     253          arc.Weight++;
     254          current.Weight++;
     255        }
     256        if (UpdateSubtreeWeights) {
     257          var subtree = NodeAt(current.Data, td.SubtreeIndex);
     258          foreach (var s in subtree.IterateNodesPrefix())
     259            s.NodeWeight++;
     260        }
    272261      }
    273262    }
Note: See TracChangeset for help on using the changeset viewer.