Changeset 11979
- Timestamp:
- 02/11/15 12:39:20 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/TraceCalculator.cs
r11968 r11979 34 34 [StorableClass] 35 35 public class TraceCalculator : Item { 36 private IGenealogyGraph<ISymbolicExpressionTree> traceGraph;37 36 private Dictionary<IGenealogyGraphNode<ISymbolicExpressionTree>, TraceData> traceMap; 38 37 private Dictionary<ISymbolicExpressionTree, List<ISymbolicExpressionTreeNode>> nodeListCache; 39 40 public IGenealogyGraph<ISymbolicExpressionTree> TraceGraph { get { return traceGraph; }}38 private HashSet<Tuple<IGenealogyGraphNode<ISymbolicExpressionTree>, IGenealogyGraphNode<ISymbolicExpressionTree>, int>> traceCache; 39 public IGenealogyGraph<ISymbolicExpressionTree> TraceGraph { get; private set; } 41 40 42 41 public TraceCalculator() { 43 traceGraph = new GenealogyGraph<ISymbolicExpressionTree>();42 TraceGraph = new GenealogyGraph<ISymbolicExpressionTree>(); 44 43 traceMap = new Dictionary<IGenealogyGraphNode<ISymbolicExpressionTree>, TraceData>(); 45 44 nodeListCache = new Dictionary<ISymbolicExpressionTree, List<ISymbolicExpressionTreeNode>>(); 45 traceCache = new HashSet<Tuple<IGenealogyGraphNode<ISymbolicExpressionTree>, IGenealogyGraphNode<ISymbolicExpressionTree>, int>>(); 46 46 } 47 47 … … 54 54 } 55 55 56 public static IGenealogyGraph<ISymbolicExpressionTree> TraceSubtree(IGenealogyGraphNode<ISymbolicExpressionTree> node, int subtreeIndex) { 56 public static IGenealogyGraph<ISymbolicExpressionTree> TraceSubtree( 57 IGenealogyGraphNode<ISymbolicExpressionTree> node, int subtreeIndex) { 57 58 var tc = new TraceCalculator(); 58 59 tc.Trace(node, subtreeIndex); … … 61 62 62 63 public IGenealogyGraph<ISymbolicExpressionTree> Trace(IGenealogyGraphNode<ISymbolicExpressionTree> node, int subtreeIndex) { 63 traceGraph = new GenealogyGraph<ISymbolicExpressionTree>();64 TraceGraph = new GenealogyGraph<ISymbolicExpressionTree>(); 64 65 traceMap = new Dictionary<IGenealogyGraphNode<ISymbolicExpressionTree>, TraceData>(); 65 66 nodeListCache = new Dictionary<ISymbolicExpressionTree, List<ISymbolicExpressionTreeNode>>(); 67 traceCache = new HashSet<Tuple<IGenealogyGraphNode<ISymbolicExpressionTree>, IGenealogyGraphNode<ISymbolicExpressionTree>, int>>(); 66 68 TraceRecursive(node, subtreeIndex); 67 return traceGraph;69 return TraceGraph; 68 70 } 69 71 … … 88 90 /// <param name="subtreeIndex">The index of the traced subtree</param> 89 91 /// <param name="last">The last added node in the trace graph</param> 90 private void TraceRecursive(IGenealogyGraphNode<ISymbolicExpressionTree> node, int subtreeIndex, IGenealogyGraphNode<ISymbolicExpressionTree> last = null) { 92 private void TraceRecursive(IGenealogyGraphNode<ISymbolicExpressionTree> node, int subtreeIndex, 93 IGenealogyGraphNode<ISymbolicExpressionTree> last = null) { 91 94 var g = node; 92 95 int si = subtreeIndex; // subtree index … … 104 107 } 105 108 106 fi = fragment.Index1; 107 int fl = fragment.Root.GetLength(); 109 fi = fragment.Index1; // fragment index 110 int fl = fragment.Root.GetLength(); // fragment length 108 111 int sl = NodeAt(g.Data, si).GetLength(); // subtree length 109 112 110 113 #region trace crossover 114 111 115 if (inArcs.Count == 2) { 112 116 var parent0 = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs[0].Source; … … 133 137 // subtree contains fragment => branching point in the fragment graph 134 138 var n = AddTraceNode(g, si, fi); // current node becomes "last" as we restart tracing from the parent 135 TraceRecursive(parent0, si, n); 136 TraceRecursive(parent1, fragment.Index2, n); 139 var t0 = new Tuple<IGenealogyGraphNode<ISymbolicExpressionTree>, IGenealogyGraphNode<ISymbolicExpressionTree>, int>(parent0, n, si); 140 if (!traceCache.Contains(t0)) { 141 TraceRecursive(parent0, si, n); 142 traceCache.Add(t0); 143 } else { 144 n.Weight++; 145 } 146 var t1 = new Tuple<IGenealogyGraphNode<ISymbolicExpressionTree>, IGenealogyGraphNode<ISymbolicExpressionTree>, int>(parent1, n, fragment.Index2); 147 if (!traceCache.Contains(t1)) { 148 TraceRecursive(parent1, fragment.Index2, n); 149 traceCache.Add(t1); 150 } else { 151 n.Weight++; 152 } 137 153 break; 138 154 } else { … … 154 170 var n = AddTraceNode(g, si, fi); // current node becomes "last" as we restart tracing from the parent 155 171 int i = si < fi ? si : fi; 156 TraceRecursive(parent0, i, n); 172 var t = new Tuple<IGenealogyGraphNode<ISymbolicExpressionTree>, IGenealogyGraphNode<ISymbolicExpressionTree>, int>(parent0, n, i); 173 if (!traceCache.Contains(t)) { 174 TraceRecursive(parent0, i, n); 175 traceCache.Add(t); 176 } else { 177 n.Weight++; 178 } 157 179 break; 158 180 } else { … … 182 204 /// <param name="fi">The fragment index</param> 183 205 /// <returns></returns> 184 private IGenealogyGraphNode<ISymbolicExpressionTree> AddTraceNode(IGenealogyGraphNode<ISymbolicExpressionTree> g, int si, int fi) { 185 var n = traceGraph.GetByContent(g.Data); 206 private IGenealogyGraphNode<ISymbolicExpressionTree> AddTraceNode(IGenealogyGraphNode<ISymbolicExpressionTree> g, 207 int si, int fi) { 208 var n = TraceGraph.GetByContent(g.Data); 186 209 if (n == null) { 187 210 n = g.Copy(); 188 traceGraph.AddVertex(n);211 TraceGraph.AddVertex(n); 189 212 Debug.Assert(!traceMap.ContainsKey(n)); 190 213 traceMap[n] = new TraceData(si, fi, -1, -1); // only the first two fields are needed … … 213 236 /// <param name="si">The index of the traced subtree</param> 214 237 /// <param name="fi">The index of the fragment</param> 215 private void ConnectLast(IGenealogyGraphNode<ISymbolicExpressionTree> current, IGenealogyGraphNode<ISymbolicExpressionTree> last, int si, int fi) { 238 private void ConnectLast(IGenealogyGraphNode<ISymbolicExpressionTree> current, 239 IGenealogyGraphNode<ISymbolicExpressionTree> last, int si, int fi) { 216 240 var lastTraceData = traceMap[last]; 217 int lastSi = lastTraceData.SubtreeIndex; // last subtree index (index of the traced subtree in the previous trace node) 218 int lastFi = lastTraceData.FragmentIndex; // last fragment index (index of the fragment in the previous trace node) 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) 219 245 var td = new TraceData(si, fi, lastSi, lastFi); // trace data 220 //var arc = current.OutArcs.SingleOrDefault(a => a.Target == last && a.Data.Equals(td)); 221 var outArcs = (List<IArc>)((IVertex)current).OutArcs; 222 var arc = outArcs.FirstOrDefault(a => a.Target == last && ((IArc<IDeepCloneable>)a).Data.Equals(td)); 246 // using the inArcs seems to be slightly more efficient than using the outArcs 247 // TODO: more testing 248 var inArcs = (List<IArc>)((IVertex)last).InArcs; 249 var arc = inArcs.FirstOrDefault(a => a.Source == current && ((IArc<IDeepCloneable>)a).Data.Equals(td)); 223 250 if (arc == null) { 224 251 arc = new GenealogyGraphArc(current, last) { Data = td }; 225 traceGraph.AddArc(arc);252 TraceGraph.AddArc(arc); 226 253 } 227 254 } 228 255 } 229 // this class is here to help clarify the semantics 256 230 257 public class TraceData : Tuple<int, int, int, int>, IDeepCloneable { 231 258 public TraceData(int currentSubtreeIndex, int currentFragmentIndex, int lastSubtreeIndex, int lastFragmentIndex)
Note: See TracChangeset
for help on using the changeset viewer.