Changeset 12225


Ignore:
Timestamp:
03/19/15 01:10:21 (4 years ago)
Author:
bburlacu
Message:

#1772: Work in progress for calculating sampling counts for subtrees in the population: updated TraceCalculator to aggregate tracing statistics, updated SymbolicDataAnalysisGenealogyGraphView, added SymbolicDataAnalysisSubtreeSampleCountAnalyzer.

Location:
branches/HeuristicLab.EvolutionTracking
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.EvolutionTracking.Views/3.4/GenealogyGraphView.cs

    r11817 r12225  
    3535    protected override void OnContentChanged() {
    3636      base.OnContentChanged();
    37       if (Content != null) { genealogyGraphChart.GenealogyGraph = Content; }
     37      if (Content != null && Content != genealogyGraphChart.GenealogyGraph) { genealogyGraphChart.GenealogyGraph = Content; }
    3838    }
    3939    #endregion
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj

    r12208 r12225  
    368368      <SubType>Designer</SubType>
    369369    </EmbeddedResource>
    370     <EmbeddedResource Include="Tracking\SymbolicDataAnalysisGenealogyGraphView.resx">
    371       <DependentUpon>SymbolicDataAnalysisGenealogyGraphView.cs</DependentUpon>
    372     </EmbeddedResource>
    373370  </ItemGroup>
    374371  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Tracking/SymbolicDataAnalysisGenealogyGraphView.cs

    r12208 r12225  
    4141    private ISymbolicExpressionTreeNode selectedSubtree;
    4242    private ISymbolicExpressionTreeNode SelectedSubtree {
    43       get {
    44         return selectedSubtree;
    45       }
     43      get { return selectedSubtree; }
    4644      set {
    47         if (selectedSubtree == value) return;
     45        if (value == null || selectedSubtree == value) return;
    4846        selectedSubtree = value;
    4947        ClonedSubtree = (ISymbolicExpressionTreeNode)selectedSubtree.Clone();
    5048      }
    5149    }
    52 
     50    // the clone is necessary in order to deselect parts of a tree (by removing subtrees)
     51    // and do "high level" matching of the remaining part
    5352    private ISymbolicExpressionTreeNode ClonedSubtree { get; set; }
     53
     54    // we use the symbolic expression tree chart to call the drawing routines
     55    // and highlight relevant tree parts
     56    public SymbolicExpressionTreeChart SymbolicExpressionTreeChart {
     57      get {
     58        var view = (GraphicalSymbolicExpressionTreeView)base.viewHost.ActiveView;
     59        return view == null ? null : view.SymbolicExpressionTreeChart;
     60      }
     61    }
    5462
    5563    public SymbolicDataAnalysisGenealogyGraphView() {
     
    6169    protected override void OnContentChanged() {
    6270      base.OnContentChanged();
    63       if (Content != null) { genealogyGraphChart.GenealogyGraph = Content; }
    64     }
    65     #endregion
    66 
    67     public SymbolicExpressionTreeChart SymbolicExpressionTreeChart {
    68       get {
    69         var view = (GraphicalSymbolicExpressionTreeView)base.viewHost.ActiveView;
    70         return view == null ? null : view.SymbolicExpressionTreeChart;
    71       }
    72     }
    73 
    74     protected override void RegisterContentEvents() {
    75       base.RegisterContentEvents();
    76       if (SymbolicExpressionTreeChart != null)
    77         SymbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked += treeChart_SymbolicExpressionTreeNodeClicked;
    78     }
    79 
    80     protected override void DeregisterContentEvents() {
    81       if (SymbolicExpressionTreeChart != null)
    82         SymbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked -= treeChart_SymbolicExpressionTreeNodeClicked;
    83       base.DeregisterContentEvents();
     71      if (Content != null && Content != genealogyGraphChart.GenealogyGraph) {
     72        genealogyGraphChart.GenealogyGraph = Content;
     73      }
    8474    }
    8575
     
    110100        var fragment = data as IFragment<ISymbolicExpressionTreeNode>;
    111101        var td = data as TraceData;
     102        //        double max = Content.Vertices.SelectMany(x => x.Data.IterateNodesPrefix()).Max(x => x.NodeWeight);
     103
    112104        if (fragment != null) {
    113           treeChart_HighlightSubtree(graphNode.Data.NodeAt(fragment.Index1));
     105          //          treeChart_HighlightSubtree(graphNode.Data.NodeAt(fragment.Index1));
     106          var nodes = graphNode.Data.IterateNodesPrefix().ToList();
     107          int c = ColorGradient.Colors.Count - 1;
     108          foreach (var n in nodes.Skip(1)) { // skip program root symbol
     109            //            var i = (int)Math.Round(n.NodeWeight / max * c);
     110            //            const int alpha = 50;
     111            //            var fillColor = Color.FromArgb(alpha, ColorGradient.Colors[i]);
     112
     113            //            treeChart_HighlightSubtree(n, null, fillColor);
     114          }
    114115        } else if (td != null) {
     116
    115117          var nodes = graphNode.Data.IterateNodesPrefix().ToList();
     118          int c = ColorGradient.Colors.Count - 1;
     119          foreach (var n in nodes.Skip(1)) { // skip program root symbol
     120            //            var i = (int)Math.Round(n.NodeWeight / max * c);
     121            //            const int alpha = 50;
     122            //            var fillColor = Color.FromArgb(alpha, ColorGradient.Colors[i]);
     123
     124            //            treeChart_HighlightSubtree(n, null, fillColor);
     125          }
     126
    116127          treeChart_HighlightSubtree(nodes[td.LastSubtreeIndex], Color.Orange);
    117           treeChart_HighlightSubtree(nodes[td.LastFragmentIndex], null, Color.PowderBlue);
     128          treeChart_HighlightSubtree(nodes[td.LastFragmentIndex], Color.CornflowerBlue);
    118129        }
    119130      }
     
    125136      // highlight the selected subtree inside the displayed tree on the right hand side
    126137      treeChart_ClearColors();
    127       treeChart_HighlightSubtree(subtree);
     138      treeChart_HighlightSubtree(subtree, Color.Black, Color.RoyalBlue);
    128139
    129140      bool trace = genealogyGraphChart.TraceFragments; // check whether we are in 'trace' or 'match' mode
     
    136147            var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
    137148            var subtreeIndex = graphNode.Data.IterateNodesPrefix().ToList().IndexOf(subtree);
    138             var traceGraph = TraceCalculator.TraceSubtree(graphNode, subtreeIndex);
     149            var traceGraph = TraceCalculator.TraceSubtree(graphNode, subtreeIndex, updateVertexWeights: true, updateSubtreeWeights: true, cacheTraceNodes: true);
    139150            if (traceGraph.Vertices.Any()) {
    140151              genealogyGraphChart.UpdateEnabled = false;
    141               genealogyGraphChart.ClearArcs();
    142               var genealogyNodes = traceGraph.Vertices.Select(v => Content.GetByContent(v.Data));
    143               genealogyGraphChart.HighlightNodes(genealogyNodes, Color.Black, false);
     152              genealogyGraphChart.ClearPrimitives();
     153              var traceVertices = traceGraph.Vertices.ToList();
     154              var genealogyNodes = traceVertices.Select(v => Content.GetByContent(v.Data)).ToList();
     155              // color graph vertices according to their weight
     156              double max = traceGraph.Vertices.Max(x => x.Data.IterateNodesPrefix().Max(n => x.Weight));
     157              for (int i = 0; i < genealogyNodes.Count; ++i) {
     158                var g = genealogyNodes[i];
     159                g.Weight = traceVertices[i].Weight;
     160                var v = genealogyGraphChart.GetMappedNode(g);
     161                if (v != null) {
     162                  v.Brush = new SolidBrush(ColorGradient.Colors[(int)Math.Round(g.Weight * (ColorGradient.Colors.Count - 1) / max)]);
     163                }
     164              }
     165
    144166              genealogyGraphChart.UpdateEnabled = true;
    145167              genealogyGraphChart.EnforceUpdate();
     168
    146169              if (openNew_CheckBox.Checked)
    147170                MainFormManager.MainForm.ShowContent(traceGraph); // display the fragment graph on the screen
    148 
    149               var max = traceGraph.Vertices.Max(x => x.Weight);
    150 
    151               genealogyGraphChart.UpdateEnabled = false;
    152               foreach (var traceNode in traceGraph.Vertices) {
    153                 var g = Content.GetByContent(traceNode.Data);
    154                 g.Weight = traceNode.Weight;
    155                 var v = genealogyGraphChart.GetMappedNode(g);
    156                 if (v != null) {
    157                   int i = (int)Math.Round(g.Weight * (ColorGradient.Colors.Count - 1) / max);
    158 
    159                   v.Brush = new SolidBrush(ColorGradient.Colors[i]);
    160                 }
    161               }
    162               genealogyGraphChart.UpdateEnabled = true;
    163               genealogyGraphChart.EnforceUpdate();
    164171            }
    165172          } else {
     
    188195          break;
    189196      }
     197    }
     198    #endregion
     199
     200    protected override void RegisterContentEvents() {
     201      base.RegisterContentEvents();
     202      if (SymbolicExpressionTreeChart != null)
     203        SymbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked += treeChart_SymbolicExpressionTreeNodeClicked;
     204    }
     205
     206    protected override void DeregisterContentEvents() {
     207      if (SymbolicExpressionTreeChart != null)
     208        SymbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked -= treeChart_SymbolicExpressionTreeNodeClicked;
     209      base.DeregisterContentEvents();
    190210    }
    191211
     
    210230
    211231    private void treeChart_HighlightSubtree(ISymbolicExpressionTreeNode subtree, Color? lineColor = null, Color? fillColor = null) {
    212       var lc = lineColor ?? Color.RoyalBlue;
    213       var fc = fillColor ?? Color.White;
     232      if (lineColor == null && fillColor == null)
     233        return;
     234
    214235      foreach (var s in subtree.IterateNodesPrefix()) {
    215236        var visualNode = SymbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(s);
    216         visualNode.LineColor = lc;
    217         visualNode.FillColor = fc;
    218 
    219         foreach (var c in s.Subtrees) {
    220           var visualArc = SymbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(s, c);
    221           visualArc.LineColor = lc;
     237        if (lineColor != null) {
     238          visualNode.LineColor = (Color)lineColor;
     239          foreach (var c in s.Subtrees) {
     240            var visualArc = SymbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(s, c);
     241            visualArc.LineColor = (Color)lineColor;
     242          }
    222243        }
     244        if (fillColor != null)
     245          visualNode.FillColor = (Color)fillColor;
    223246      }
    224247      SymbolicExpressionTreeChart.RepaintNodes();
    225248    }
    226249
     250    #region navigate the genealogy / trace graph
    227251    private void navigateLeftButton_Click(object sender, EventArgs e) {
    228252      var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
     
    267291      }
    268292    }
     293    #endregion
    269294  }
     295
     296  // bogus class needed in order to be able to "design" the view
    270297  public class SymbolicDataAnalysisGenealogyGraphViewDesignable : GenealogyGraphView<ISymbolicExpressionTree> { }
    271298
     299  #region helper methods
    272300  internal static class Util {
    273301    internal static ISymbolicExpressionTreeNode NodeAt(this ISymbolicExpressionTree tree, int position) {
     
    278306    }
    279307  }
     308  #endregion
    280309}
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj

    r12208 r12225  
    309309    <Compile Include="Symbols\VariableTreeNode.cs" />
    310310    <Compile Include="Tracking\Analyzers\SymbolicDataAnalysisFragmentLengthAnalyzer.cs" />
     311    <Compile Include="Tracking\Analyzers\SymbolicDataAnalysisSubtreeSampleCountAnalyzer.cs" />
    311312    <Compile Include="Tracking\Analyzers\SymbolicDataAnalysisTraceOverlapAnalyzer.cs" />
    312313    <Compile Include="Tracking\SymbolicDataAnalysisExpressionAfterCrossoverOperator.cs" />
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/TraceCalculator.cs

    r11979 r12225  
    3939    public IGenealogyGraph<ISymbolicExpressionTree> TraceGraph { get; private set; }
    4040
     41    public bool UpdateVertexWeights { get; set; }
     42    public bool UpdateSubtreeWeights { get; set; }
     43    public bool CacheTraceNodes { get; set; }
     44
    4145    public TraceCalculator() {
     46      ResetState();
     47    }
     48
     49    protected TraceCalculator(TraceCalculator original, Cloner cloner)
     50      : base(original, cloner) {
     51    }
     52
     53    public override IDeepCloneable Clone(Cloner cloner) {
     54      return new TraceCalculator(this, cloner);
     55    }
     56
     57    public void ResetState() {
    4258      TraceGraph = new GenealogyGraph<ISymbolicExpressionTree>();
    4359      traceMap = new Dictionary<IGenealogyGraphNode<ISymbolicExpressionTree>, TraceData>();
     
    4662    }
    4763
    48     protected TraceCalculator(TraceCalculator original, Cloner cloner)
    49       : base(original, cloner) {
    50     }
    51 
    52     public override IDeepCloneable Clone(Cloner cloner) {
    53       return new TraceCalculator(this, cloner);
    54     }
    55 
    56     public static IGenealogyGraph<ISymbolicExpressionTree> TraceSubtree(
    57       IGenealogyGraphNode<ISymbolicExpressionTree> node, int subtreeIndex) {
    58       var tc = new TraceCalculator();
     64    public static IGenealogyGraph<ISymbolicExpressionTree> TraceSubtree(IGenealogyGraphNode<ISymbolicExpressionTree> node, int subtreeIndex, bool updateVertexWeights = false, bool updateSubtreeWeights = false, bool cacheTraceNodes = true) {
     65      var tc = new TraceCalculator {
     66        UpdateVertexWeights = updateSubtreeWeights,
     67        UpdateSubtreeWeights = updateSubtreeWeights,
     68        CacheTraceNodes = cacheTraceNodes
     69      };
    5970      tc.Trace(node, subtreeIndex);
    6071      return tc.TraceGraph;
    6172    }
    6273
    63     public IGenealogyGraph<ISymbolicExpressionTree> Trace(IGenealogyGraphNode<ISymbolicExpressionTree> node, int subtreeIndex) {
    64       TraceGraph = new GenealogyGraph<ISymbolicExpressionTree>();
    65       traceMap = new Dictionary<IGenealogyGraphNode<ISymbolicExpressionTree>, TraceData>();
    66       nodeListCache = new Dictionary<ISymbolicExpressionTree, List<ISymbolicExpressionTreeNode>>();
    67       traceCache = new HashSet<Tuple<IGenealogyGraphNode<ISymbolicExpressionTree>, IGenealogyGraphNode<ISymbolicExpressionTree>, int>>();
     74    public IGenealogyGraph<ISymbolicExpressionTree> Trace(IGenealogyGraphNode<ISymbolicExpressionTree> node, int subtreeIndex, bool resetState = true) {
     75      if (resetState) ResetState();
    6876      TraceRecursive(node, subtreeIndex);
    6977      return TraceGraph;
     
    9098    /// <param name="subtreeIndex">The index of the traced subtree</param>
    9199    /// <param name="last">The last added node in the trace graph</param>
    92     private void TraceRecursive(IGenealogyGraphNode<ISymbolicExpressionTree> node, int subtreeIndex,
    93       IGenealogyGraphNode<ISymbolicExpressionTree> last = null) {
     100    private void TraceRecursive(IGenealogyGraphNode<ISymbolicExpressionTree> node, int subtreeIndex, IGenealogyGraphNode<ISymbolicExpressionTree> last = null) {
    94101      var g = node;
    95102      int si = subtreeIndex; // subtree index
    96103      int fi = 0; // fragment index
    97104      while (((List<IArc>)((IVertex)g).InArcs).Count > 0) {
    98         //      while (g.Parents.Any()) {
    99105        Debug.Assert(si < g.Data.Length);
    100106        var inArcs = (List<IArc>)((IVertex)g).InArcs;
     
    138144              var n = AddTraceNode(g, si, fi); // current node becomes "last" as we restart tracing from the parent
    139145              var t0 = new Tuple<IGenealogyGraphNode<ISymbolicExpressionTree>, IGenealogyGraphNode<ISymbolicExpressionTree>, int>(parent0, n, si);
    140               if (!traceCache.Contains(t0)) {
     146              if (!(CacheTraceNodes && traceCache.Contains(t0))) {
    141147                TraceRecursive(parent0, si, n);
    142148                traceCache.Add(t0);
    143               } else {
     149              }
     150              if (UpdateVertexWeights)
    144151                n.Weight++;
    145               }
    146152              var t1 = new Tuple<IGenealogyGraphNode<ISymbolicExpressionTree>, IGenealogyGraphNode<ISymbolicExpressionTree>, int>(parent1, n, fragment.Index2);
    147               if (!traceCache.Contains(t1)) {
     153              if (!(CacheTraceNodes && traceCache.Contains(t1))) {
    148154                TraceRecursive(parent1, fragment.Index2, n);
    149155                traceCache.Add(t1);
    150               } else {
     156              }
     157              // gather statistics about sampled individuals and sampled subtrees
     158              if (UpdateVertexWeights)
    151159                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                for (int i = 0; i < arcs.Count; ++i) {
     163                  var td = (TraceData)((IArc<IDeepCloneable>)arcs[i]).Data;
     164                  var p = (IGenealogyGraphNode<ISymbolicExpressionTree>)arcs[i].Source;
     165                  // TODO: the first part of the check below represents a necessary but not sufficient condition
     166                  // TODO: therefore, a Difference check is also performed, it would be nice to make this code more ellegant
     167                  if (td.LastFragmentIndex == td.SubtreeIndex && fragment.Root.Difference(NodeAt(p.Data, td.SubtreeIndex)) == null) {
     168                    arcs[i].Weight++;
     169                    break;
     170                  }
     171                }
    152172              }
    153173              break;
     
    171191            int i = si < fi ? si : fi;
    172192            var t = new Tuple<IGenealogyGraphNode<ISymbolicExpressionTree>, IGenealogyGraphNode<ISymbolicExpressionTree>, int>(parent0, n, i);
    173             if (!traceCache.Contains(t)) {
     193            if (!(CacheTraceNodes && traceCache.Contains(t))) {
    174194              TraceRecursive(parent0, i, n);
    175195              traceCache.Add(t);
    176             } else {
     196            }
     197            if (UpdateVertexWeights)
    177198              n.Weight++;
    178             }
    179199            break;
    180200          } else {
     
    204224    /// <param name="fi">The fragment index</param>
    205225    /// <returns></returns>
    206     private IGenealogyGraphNode<ISymbolicExpressionTree> AddTraceNode(IGenealogyGraphNode<ISymbolicExpressionTree> g,
    207       int si, int fi) {
     226    private IGenealogyGraphNode<ISymbolicExpressionTree> AddTraceNode(IGenealogyGraphNode<ISymbolicExpressionTree> g, int si, int fi) {
    208227      var n = TraceGraph.GetByContent(g.Data);
    209228      if (n == null) {
     
    239258      IGenealogyGraphNode<ISymbolicExpressionTree> last, int si, int fi) {
    240259      var lastTraceData = traceMap[last];
    241       int lastSi = lastTraceData.SubtreeIndex;
    242       // last subtree index (index of the traced subtree in the previous trace node)
    243       int lastFi = lastTraceData.FragmentIndex;
    244       // last fragment index (index of the fragment in the previous trace node)
     260      int lastSi = lastTraceData.SubtreeIndex; // last subtree index (index of the traced subtree in the previous trace node)
     261      int lastFi = lastTraceData.FragmentIndex; // last fragment index (index of the fragment in the previous trace node)
    245262      var td = new TraceData(si, fi, lastSi, lastFi); // trace data
    246263      // using the inArcs seems to be slightly more efficient than using the outArcs
Note: See TracChangeset for help on using the changeset viewer.