Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SymbolicDataAnalysisExpressionTracing.cs @ 10755

Last change on this file since 10755 was 10755, checked in by bburlacu, 10 years ago

#1772: Simplified genealogy graph and fragment graph creation:

  • the genealogy graph now has a 1-1 mapping between content and vertices (as opposed to 1-n as it was previously, to account for elites); this required changes to the directed graph implementation
  • the fragment graph only contains bifurcation points (where the subtree contains the fragment so tracing must be done both ways (in the root parent AND in the other parent). in the other cases, tracing is restarted from the parent genealogy graph node.
File size: 5.9 KB
Line 
1
2using System;
3using System.Collections.Generic;
4using System.IO;
5using System.Linq;
6using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
7using HeuristicLab.EvolutionTracking;
8using FragmentNode = HeuristicLab.EvolutionTracking.GenealogyGraphNode<HeuristicLab.EvolutionTracking.IFragment<HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.ISymbolicExpressionTreeNode>>;
9using IFragmentNode = HeuristicLab.EvolutionTracking.IGenealogyGraphNode<HeuristicLab.EvolutionTracking.IFragment<HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.ISymbolicExpressionTreeNode>>;
10using IGraphNode = HeuristicLab.EvolutionTracking.IGenealogyGraphNode<HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.ISymbolicExpressionTree>;
11
12namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
13  public static class SymbolicDataAnalysisExpressionTracing {
14    public static IGenealogyGraph<IFragment<ISymbolicExpressionTreeNode>> TraceSubtree(IGenealogyGraphNode<ISymbolicExpressionTree> graphNode, int subtreeIndex) {
15      var graph = new GenealogyGraph<IFragment<ISymbolicExpressionTreeNode>>();
16      var nodes = Trace(graphNode, subtreeIndex);
17      foreach (var n in nodes) {
18        graph.AddVertex(n);
19      }
20      return graph;
21    }
22
23    private static IEnumerable<IFragmentNode> Trace(IGraphNode graphNode, int subtreeIndex, FragmentNode parentNode = null) {
24      var node = graphNode; // current node
25      var index = subtreeIndex; // current index
26      var parent = parentNode; // current parent
27
28      while (true) {
29        if (!node.Parents.Any()) {
30          var fragmentNode = new FragmentNode {
31            Content = new Fragment<ISymbolicExpressionTreeNode> { Root = node.Content.NodeAt(index) },
32            Rank = node.Rank
33          };
34          if (parent != null) {
35            var arc = new GenealogyGraphArc { Source = parent, Target = fragmentNode };
36            parent.AddForwardArc(arc);
37            //            fragmentNode.Content.Index1 = parent.Content.Index1;
38          }
39          yield return fragmentNode; // no tracing if there are no parents
40          break;
41        }
42
43        if (node.IsElite) {
44          node = node.Parents.First();
45          continue;
46        } // skip elite, go up the graph to original individual
47
48        var tree = node.Content;
49        var subtree = tree.NodeAt(index);
50        var subtreeLength = subtree.GetLength();
51
52        var fragment = (IFragment<ISymbolicExpressionTreeNode>)node.InArcs.Last().Data;
53        if (fragment == null) break;
54        var fragmentLength = fragment.Root.GetLength();
55
56        if (fragment.Index1 == index) {
57          node = node.Parents.Last(); // take second parent which contains the fragment
58          index = fragment.Index2;
59        } else if (fragment.Index1 < index) {
60          if (fragment.Index1 + fragmentLength > index) {
61            node = node.Parents.Last(); // fragment contains subtree, take second parent
62            index += fragment.Index2 - fragment.Index1; // the subtree has the same index relative to the fragment
63          } else {
64            // fragment distinct from subtree
65            node = node.Parents.First(); // take first parent which contains the subtree
66            index += node.Content.NodeAt(fragment.Index1).GetLength() - fragmentLength; // subtreeIndex must be adjusted according to swapped fragments sizes
67          }
68        } else if (fragment.Index1 > index) {
69          if (fragment.Index1 < index + subtreeLength) {
70            // subtree contains fragment => bifurcation point in the fragment graph
71            var fragmentNode = new FragmentNode {
72              Content = new Fragment<ISymbolicExpressionTreeNode> { Root = subtree },
73              Rank = node.Rank
74            };
75            if (parent != null) {
76              var arc = new GenealogyGraphArc { Source = parent, Target = fragmentNode };
77              parent.AddForwardArc(arc);
78            }
79            fragmentNode.Content.Index1 = fragment.Index1 - index;
80            yield return fragmentNode;
81
82            var left = Trace(node.Parents.First(), index, fragmentNode); // trace subtree
83
84            if (node.Parents.Last().Content.NodeAt(fragment.Index2).GetLength() != fragmentLength) {
85              throw new Exception("Fragment lengths should match!");
86            }
87            var right = Trace(node.Parents.Last(), fragment.Index2, fragmentNode); // trace fragment
88            foreach (var v in left.Concat(right)) {
89              yield return v;
90            }
91            break;
92          } else {
93            node = node.Parents.First(); // fragment distinct from subtree: update node, index remains unchanged
94          }
95        }
96      }
97    }
98
99    private static string ViewAsText(this ISymbolicExpressionTreeNode root) {
100      var writer = new StringWriter();
101      SymbolicExpressionTreeHierarchicalFormatter.RenderNode(writer, root, string.Empty);
102      return writer.ToString();
103    }
104    #region some helper methods for shortening the tracing code
105
106    private static void AddChild(this IGenealogyGraphNode parent, IGenealogyGraphNode child) {
107      parent.AddForwardArc(child);
108      child.AddReverseArc(parent);
109      child.Rank = parent.Rank - 1;
110    }
111    private static ISymbolicExpressionTreeNode NodeAt(this ISymbolicExpressionTree tree, int position) {
112      return NodeAt(tree.Root, position);
113    }
114    private static ISymbolicExpressionTreeNode NodeAt(this ISymbolicExpressionTreeNode root, int position) {
115      return root.IterateNodesPrefix().ElementAt(position);
116    }
117    private static int IndexOf(this ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode node) {
118      return IndexOf(tree.Root, node);
119    }
120    private static int IndexOf(this ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode node) {
121      int i = 0;
122      foreach (var n in root.IterateNodesPrefix()) {
123        if (n == node) return i;
124        ++i;
125      }
126      return -1;
127    }
128    #endregion
129  }
130}
Note: See TracBrowser for help on using the repository browser.