Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SymbolicDataAnalysisExpressionAfterManipulatorOperator.cs @ 11253

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

#1772: Ported the rest of the changes to the DirectedGraph and Vertex to the GenealogyGraph and GenealogyGraphNode. Adapted tracking operators, analyzers and views.

File size: 4.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Core;
26using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
27using HeuristicLab.EvolutionTracking;
28
29namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
30  public class SymbolicDataAnalysisExpressionAfterManipulatorOperator : AfterManipulatorOperator<ISymbolicExpressionTree> {
31    public override IOperation Apply() {
32      var childVertex = (IGenealogyGraphNode<ISymbolicExpressionTree>)GenealogyGraph.GetByContent(ChildParameter.ActualValue);
33      var nodesBefore = (List<ISymbolicExpressionTreeNode>)childVertex.InArcs.First().Data;
34      var nodesAfter = ChildParameter.ActualValue.IterateNodesPrefix().ToList();
35      IFragment<ISymbolicExpressionTreeNode> fragment = null;
36
37      // try to find if a subtree was replaced by comparing references
38      for (int i = 0; i < Math.Min(nodesBefore.Count, nodesAfter.Count); ++i) {
39        if (nodesAfter[i] != nodesBefore[i]) {
40          fragment = new Fragment<ISymbolicExpressionTreeNode> {
41            Root = nodesAfter[i],
42            Index1 = i,
43            Index2 = i
44          };
45        }
46      }
47      // if the fragment could not be identified by reference comparison, we try to identify it by comparing node labels
48      // the fragment root will be the lowest common ancestor of all the differing nodes
49      if (fragment == null) {
50        var list = new List<ISymbolicExpressionTreeNode>();
51        var root = ChildParameter.ActualValue.Root;
52
53        for (int i = 0; i < Math.Min(nodesBefore.Count, nodesAfter.Count); ++i) {
54          var a = nodesAfter[i];
55          var b = nodesBefore[i];
56
57          if (!Equals(a.ToString(), b.ToString())) // label comparison is sufficient
58            list.Add(a);
59        }
60
61        var lca = LowestCommonAncestor(root, list);
62        int index = nodesAfter.IndexOf(lca);
63        fragment = new Fragment<ISymbolicExpressionTreeNode> {
64          Root = lca,
65          Index1 = index,
66          Index2 = index
67        };
68      }
69
70      if (fragment == null)
71        throw new ArgumentNullException("Could not identify fragment.");
72
73      childVertex.InArcs.First().Data = fragment;
74      return base.Apply();
75    }
76
77    private static ISymbolicExpressionTreeNode LowestCommonAncestor(ISymbolicExpressionTreeNode root, List<ISymbolicExpressionTreeNode> nodes) {
78      if (nodes.Count == 0)
79        throw new ArgumentException("The nodes list should contain at least one element.");
80
81      if (nodes.Count == 1)
82        return nodes[0];
83
84      int lowestLevel = nodes.Min(x => root.GetBranchLevel(x));
85
86      // bring the nodes in the nodes to the same level (relative to the root)
87      for (int i = 0; i < nodes.Count; ++i) {
88        var node = nodes[i];
89        var level = root.GetBranchLevel(node);
90        for (int j = lowestLevel; j < level; ++j)
91          node = node.Parent;
92        nodes[i] = node;
93      }
94
95      // while not all the elements in the nodes are equal, go one level up
96      while (nodes.Any(x => x != nodes[0])) {
97        for (int i = 0; i < nodes.Count; ++i)
98          nodes[i] = nodes[i].Parent;
99      }
100
101      return nodes[0];
102    }
103  }
104}
Note: See TracBrowser for help on using the repository browser.