Changeset 11486
- Timestamp:
- 10/21/14 19:56:48 (10 years ago)
- Location:
- branches/HeuristicLab.BottomUpTreeDistance
- Files:
-
- 5 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisInternalDiversityAnalyzer.cs
r11239 r11486 21 21 22 22 using System; 23 using System.Collections.Generic;24 23 using System.Linq; 25 24 using HeuristicLab.Analysis; … … 40 39 private const string QualityParameterName = "Quality"; 41 40 private const string PercentageOfBestSolutionsParameterName = "PercentageOfBestSolutions"; 42 43 41 private const string ResultCollectionParameterName = "Results"; 44 private readonly BottomUp TreeSimilarityCalculator busCalculator;42 private readonly BottomUpSimilarityCalculator busCalculator; 45 43 46 44 public SymbolicDataAnalysisInternalDiversityAnalyzer() { 47 busCalculator = new BottomUp TreeSimilarityCalculator();45 busCalculator = new BottomUpSimilarityCalculator(); 48 46 49 47 Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName)); … … 103 101 var qualities = QualityParameter.ActualValue.ToArray(); 104 102 105 Array.Sort(qualities, trees, new ReverseComparer());103 var pairs = trees.Zip(qualities, (t, q) => new { Tree = t, Quality = q }).OrderByDescending(x => x.Quality); 106 104 int n = (int)Math.Floor(trees.Length * PercentageOfBestSolutions); 107 108 double avgInternalDiversity = trees.Take(n).Average(tree => CalculateInternalDiversity(tree)); 105 double avgInternalDiversity = pairs.Take(n).Average(x => CalculateInternalDiversity(x.Tree)); 109 106 110 107 table.Rows["Avg. Internal Diversity"].Values.Add(avgInternalDiversity); … … 136 133 } 137 134 } 138 139 internal class ReverseComparer : IComparer<DoubleValue> {140 public int Compare(DoubleValue x, DoubleValue y) {141 return y.CompareTo(x);142 }143 }144 135 } -
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
r11243 r11486 219 219 <Compile Include="Matching\SymbolicExpressionTreeNodeComparer.cs" /> 220 220 <Compile Include="Matching\SymbolicExpressionTreeNodeSimilarityComparer.cs" /> 221 <Compile Include="SimilarityCalculators\BottomUp TreeSimilarityCalculator.cs" />221 <Compile Include="SimilarityCalculators\BottomUpSimilarityCalculator.cs" /> 222 222 <Compile Include="SimilarityCalculators\MaxCommonSubtreeSimilarityCalculator.cs" /> 223 223 <Compile Include="SymbolicExpressionTreeBacktransformator.cs" /> -
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Matching/SymbolicExpressionTreeNodeComparer.cs
r10562 r11486 1 using System; 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 22 using System; 2 23 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 3 24 … … 9 30 public class SymbolicExpressionTreeNodeComparer : ISymbolicExpressionTreeNodeComparer { 10 31 public int Compare(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 11 if (!(a is SymbolicExpressionTreeTerminalNode)) { 12 return b is SymbolicExpressionTreeTerminalNode 13 ? -1 14 : string.Compare(a.Symbol.Name, b.Symbol.Name, StringComparison.Ordinal); 15 } 16 if (!(b is SymbolicExpressionTreeTerminalNode)) return 1; 17 // at this point we know a and b are terminal nodes 32 var ta = a as SymbolicExpressionTreeTerminalNode; 33 var tb = b as SymbolicExpressionTreeTerminalNode; 34 35 if (ta == null) 36 return tb == null ? String.CompareOrdinal(a.Symbol.Name, b.Symbol.Name) : -1; 37 38 if (tb == null) 39 return 1; 40 41 // at this point we know a and b are both terminals 18 42 var va = a as VariableTreeNode; 19 if (va != null) { 20 if (b is ConstantTreeNode) return -1; 21 var vb = (VariableTreeNode)b; 22 return (va.VariableName.Equals(vb.VariableName) 23 ? va.Weight.CompareTo(vb.Weight) 24 : string.Compare(va.VariableName, vb.VariableName, StringComparison.Ordinal)); 25 } 26 // at this point we know for sure that a is a constant tree node 27 if (b is VariableTreeNode) return 1; 28 var ca = (ConstantTreeNode)a; 29 var cb = (ConstantTreeNode)b; 30 return ca.Value.CompareTo(cb.Value); 43 var vb = b as VariableTreeNode; 44 45 if (va != null) 46 return vb == null ? -1 : CompareVariables(va, vb); 47 48 if (vb != null) 49 return 1; 50 51 // at this point we know a and b are not variables 52 var ca = a as ConstantTreeNode; 53 var cb = b as ConstantTreeNode; 54 55 if (ca != null && cb != null) 56 return ca.Value.CompareTo(cb.Value); 57 58 // for other unknown terminal types, compare strings 59 return string.CompareOrdinal(a.ToString(), b.ToString()); 60 } 61 62 private static int CompareVariables(VariableTreeNode a, VariableTreeNode b) { 63 int result = string.CompareOrdinal(a.VariableName, b.VariableName); 64 return result == 0 ? a.Weight.CompareTo(b.Weight) : result; 31 65 } 32 66 } 67 33 68 } -
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SimilarityCalculators/BottomUpSimilarityCalculator.cs
r11482 r11486 22 22 using System; 23 23 using System.Collections.Generic; 24 using System.Diagnostics; 25 using System.Globalization; 24 26 using System.Linq; 25 27 using HeuristicLab.Common; … … 31 33 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 32 34 [StorableClass] 33 [Item("BottomUp TreeSimilarityCalculator", "A similarity calculator which uses the tree bottom-up distance as a similarity metric.")]34 public class BottomUp TreeSimilarityCalculator : SingleObjectiveSolutionSimilarityCalculator {35 private readonly HashSet<string> commutativeSymbols ;36 37 public BottomUpTreeSimilarityCalculator() {38 commutativeSymbols = new HashSet<string>(); 39 }40 41 p ublic BottomUpTreeSimilarityCalculator(IEnumerable<string> commutativeSymbols) {42 this.commutativeSymbols = new HashSet<string>(commutativeSymbols);35 [Item("BottomUpSimilarityCalculator", "A similarity calculator which uses the tree bottom-up distance as a similarity metric.")] 36 public class BottomUpSimilarityCalculator : SingleObjectiveSolutionSimilarityCalculator { 37 private readonly HashSet<string> commutativeSymbols = new HashSet<string> { "Addition", "Multiplication", "Average", "And", "Or", "Xor" }; 38 public bool MatchVariableWeights { get; set; } 39 public bool MatchConstantValues { get; set; } 40 41 public BottomUpSimilarityCalculator() { } 42 43 protected BottomUpSimilarityCalculator(BottomUpSimilarityCalculator original, Cloner cloner) 44 : base(original, cloner) { 43 45 } 44 46 45 47 public override IDeepCloneable Clone(Cloner cloner) { 46 return new BottomUpTreeSimilarityCalculator(this, cloner); 47 } 48 49 protected BottomUpTreeSimilarityCalculator(BottomUpTreeSimilarityCalculator original, Cloner cloner) 50 : base(original, cloner) { 48 return new BottomUpSimilarityCalculator(this, cloner); 49 } 50 51 public double CalculateSimilarity(ISymbolicExpressionTree t1, ISymbolicExpressionTree t2) { 52 if (t1 == t2) 53 return 1; 54 55 var map = ComputeBottomUpMapping(t1.Root, t2.Root); 56 return 2.0 * map.Count / (t1.Length + t2.Length); 51 57 } 52 58 … … 58 64 throw new ArgumentException("Cannot calculate similarity when one of the arguments is null."); 59 65 60 var similarity = CalculateS olutionSimilarity(t1, t2);66 var similarity = CalculateSimilarity(t1, t2); 61 67 if (similarity > 1.0) 62 68 throw new Exception("Similarity value cannot be greater than 1"); … … 65 71 } 66 72 67 public bool AddCommutativeSymbol(string symbolName) {68 return commutativeSymbols.Add(symbolName);69 }70 71 public bool RemoveCommutativeSymbol(string symbolName) {72 return commutativeSymbols.Remove(symbolName);73 }74 75 public double CalculateSolutionSimilarity(ISymbolicExpressionTree t1, ISymbolicExpressionTree t2) {76 if (t1 == t2)77 return 1;78 79 var map = ComputeBottomUpMapping(t1.Root, t2.Root);80 return 2.0 * map.Count / (t1.Length + t2.Length);81 }82 83 73 public Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> ComputeBottomUpMapping(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) { 74 var comparer = new SymbolicExpressionTreeNodeComparer(); // use a node comparer because it's faster than calling node.ToString() (strings are expensive) and comparing strings 84 75 var compactedGraph = Compact(n1, n2); 85 76 … … 103 94 // at this point we know that v and w are isomorphic, however, the mapping cannot be done directly (as in the paper) because the trees are unordered (subtree order might differ) 104 95 // the solution is to sort subtrees by label using IterateBreadthOrdered (this will work because the subtrees are isomorphic!) and simultaneously iterate over the two subtrees 105 var eV = IterateBreadthOrdered(v ).GetEnumerator();106 var eW = IterateBreadthOrdered(w ).GetEnumerator();96 var eV = IterateBreadthOrdered(v, comparer).GetEnumerator(); 97 var eW = IterateBreadthOrdered(w, comparer).GetEnumerator(); 107 98 108 99 while (eV.MoveNext() && eW.MoveNext()) { … … 110 101 var t = eW.Current; 111 102 112 if (reverseMap.ContainsKey(t)) { 113 throw new Exception("A mapping to this node already exists."); 114 } 103 Debug.Assert(!reverseMap.ContainsKey(t)); 115 104 116 105 forwardMap[s] = t; … … 134 123 135 124 var nodes = n1.IterateNodesPostfix().Concat(n2.IterateNodesPostfix()); // the disjoint union F 136 var list = new List<GraphNode>(); 125 var list = new List<GraphNode>(); // preallocate size to avoid list resizing as it has a performance hit 137 126 var queue = new Queue<ISymbolicExpressionTreeNode>(); 138 127 139 128 foreach (var n in nodes) { 140 129 if (n.SubtreeCount == 0) { 141 var label = n.ToString();130 var label = Label(n); 142 131 if (!labelMap.ContainsKey(label)) { 143 132 var z = new GraphNode { SymbolicExpressionTreeNode = n, Label = label }; … … 161 150 bool sort = commutativeSymbols.Contains(label); 162 151 var nNodes = n.Subtrees.Select(x => nodeMap[x]).ToList(); 163 if (sort) nNodes.Sort((a, b) => String.Compare(a.Label, b.Label, StringComparison.Ordinal));152 if (sort) nNodes.Sort((a, b) => string.CompareOrdinal(a.Label, b.Label)); 164 153 165 154 for (int i = list.Count - 1; i >= 0; --i) { … … 172 161 var m = w.SymbolicExpressionTreeNode; 173 162 var mNodes = m.Subtrees.Select(x => nodeMap[x]).ToList(); 174 if (sort) mNodes.Sort((a, b) => String.Compare(a.Label, b.Label, StringComparison.Ordinal));163 if (sort) mNodes.Sort((a, b) => string.CompareOrdinal(a.Label, b.Label)); 175 164 176 165 if (nNodes.SequenceEqual(mNodes)) { … … 182 171 183 172 if (!found) { 184 var w = new GraphNode { SymbolicExpressionTreeNode = n, Label = label, Depth = depth , ChildrenCount = n.SubtreeCount};173 var w = new GraphNode { SymbolicExpressionTreeNode = n, Label = label, Depth = depth }; 185 174 list.Add(w); 186 175 nodeMap[n] = w; … … 188 177 } 189 178 179 if (n == n1 || n == n2) 180 continue; 181 190 182 var p = n.Parent; 191 183 if (p == null) … … 201 193 } 202 194 203 /// <summary> 204 /// This method iterates the nodes of a subtree in breadth order while also sorting the subtrees of commutative symbols based on their label. 205 /// This is necessary in order for the mapping to be realized correctly. 206 /// </summary> 207 /// <param name="node">The root of the subtree</param> 208 /// <returns>A list of nodes in breadth order (with children of commutative symbols sorted by label)</returns> 209 private IEnumerable<ISymbolicExpressionTreeNode> IterateBreadthOrdered(ISymbolicExpressionTreeNode node) { 195 private IEnumerable<ISymbolicExpressionTreeNode> IterateBreadthOrdered(ISymbolicExpressionTreeNode node, ISymbolicExpressionTreeNodeComparer comparer) { 210 196 var list = new List<ISymbolicExpressionTreeNode> { node }; 211 197 int i = 0; … … 213 199 var n = list[i]; 214 200 if (n.SubtreeCount > 0) { 215 var subtrees = commutativeSymbols.Contains(node.Symbol.Name) ? n.Subtrees.OrderBy(x => x .ToString(), StringComparer.Ordinal) : n.Subtrees;201 var subtrees = commutativeSymbols.Contains(node.Symbol.Name) ? n.Subtrees.OrderBy(x => x, comparer) : n.Subtrees; 216 202 list.AddRange(subtrees); 217 203 } … … 219 205 } 220 206 return list; 207 } 208 209 private string Label(ISymbolicExpressionTreeNode node) { 210 if (node.SubtreeCount > 0) 211 return node.Symbol.Name; 212 213 var constant = node as ConstantTreeNode; 214 if (constant != null) 215 return MatchConstantValues ? constant.Value.ToString(CultureInfo.InvariantCulture) : constant.Symbol.Name; 216 var variable = node as VariableTreeNode; 217 if (variable != null) { 218 return MatchVariableWeights ? variable.Weight + variable.VariableName : variable.VariableName; 219 } 220 221 return node.ToString(); 221 222 } 222 223 … … 225 226 public string Label; 226 227 public int Depth; 227 public int ChildrenCount ;228 public int ChildrenCount { get { return SymbolicExpressionTreeNode.SubtreeCount; } } 228 229 } 229 230 } -
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs
r11254 r11486 358 358 } 359 359 foreach (var op in operators.OfType<SingleObjectivePopulationDiversityAnalyzer>()) { 360 op.SimilarityCalculator = new BottomUp TreeSimilarityCalculator();360 op.SimilarityCalculator = new BottomUpSimilarityCalculator(); 361 361 } 362 362 } -
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Tests/BottomUpTreeSimilarityCalculatorTest.cs
r11244 r11486 14 14 [TestClass] 15 15 public class BottomUpSimilarityCalculatorTest { 16 private readonly BottomUp TreeSimilarityCalculator busCalculator;16 private readonly BottomUpSimilarityCalculator busCalculator; 17 17 private readonly SymbolicExpressionImporter importer; 18 18 … … 22 22 23 23 public BottomUpSimilarityCalculatorTest() { 24 busCalculator = new BottomUp TreeSimilarityCalculator(new List<string> { "Addition", "Multiplication", "And", "Or", "Xor" });24 busCalculator = new BottomUpSimilarityCalculator { MatchConstantValues = true, MatchVariableWeights = true }; 25 25 importer = new SymbolicExpressionImporter(); 26 26 } … … 85 85 for (int i = 0; i < trees.Length - 1; ++i) { 86 86 for (int j = i + 1; j < trees.Length; ++j) { 87 s += busCalculator.CalculateS olutionSimilarity(trees[i], trees[j]);87 s += busCalculator.CalculateSimilarity(trees[i], trees[j]); 88 88 } 89 89 }
Note: See TracChangeset
for help on using the changeset viewer.