Changeset 10471 for branches/HeuristicLab.ReingoldTilfordTreeLayout/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding
- Timestamp:
- 02/19/14 22:18:49 (11 years ago)
- Location:
- branches/HeuristicLab.ReingoldTilfordTreeLayout/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.ReingoldTilfordTreeLayout/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Formatters/SymbolicExpressionTreeLatexFormatter.cs
r10468 r10471 53 53 54 54 public string Format(ISymbolicExpressionTree symbolicExpressionTree) { 55 layoutEngine.Reset(); 55 56 var layoutNodes = layoutAdapter.Convert(symbolicExpressionTree).ToList(); 56 57 layoutEngine.Root = layoutNodes[0]; 57 foreach (var ln in layoutNodes) 58 layoutEngine.AddNode(ln.Content, ln); 58 layoutEngine.AddNodes(layoutNodes); 59 59 layoutEngine.CalculateLayout(); 60 60 var nodeCoordinates = layoutEngine.GetNodeCoordinates(); -
branches/HeuristicLab.ReingoldTilfordTreeLayout/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj
r9970 r10471 185 185 <Compile Include="Formatters\SymbolicExpressionTreeLatexFormatter.cs" /> 186 186 <Compile Include="Interfaces\ILayoutAdapter.cs" /> 187 <Compile Include="Interfaces\ILayoutNode.cs" />188 187 <Compile Include="Interfaces\IReadOnlySymbol.cs" /> 189 188 <Compile Include="Interfaces\ISymbolicExpressionGrammar.cs" /> -
branches/HeuristicLab.ReingoldTilfordTreeLayout/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ILayoutAdapter.cs
r9970 r10471 4 4 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { 5 5 public interface ILayoutAdapter<T> where T : class { 6 IEnumerable< ILayoutNode<T>> Convert(T root, Func<T, ILayoutNode<T>> convertFunc);6 IEnumerable<LayoutNode<T>> Convert(T root, Func<T, LayoutNode<T>> convertFunc); 7 7 } 8 8 } -
branches/HeuristicLab.ReingoldTilfordTreeLayout/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/LayoutEngines/LayoutNode.cs
r9970 r10471 20 20 #endregion 21 21 22 using System; 22 23 using System.Collections.Generic; 23 24 using System.Linq; 24 25 25 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding .LayoutEngines{26 public class LayoutNode<T> : ILayoutNode<T>where T : class {27 public ILayoutNode<T> NextLeft {26 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { 27 public class LayoutNode<T> where T : class { 28 public LayoutNode<T> NextLeft { 28 29 get { 29 30 return Children == null ? Thread : Children.First(); 30 31 } 31 32 } 32 public ILayoutNode<T> NextRight {33 public LayoutNode<T> NextRight { 33 34 get { 34 35 return Children == null ? Thread : Children.Last(); 35 36 } 36 37 } 37 public ILayoutNode<T> LeftSibling {38 public LayoutNode<T> LeftSibling { 38 39 get { 39 40 if (Parent == null) return null; … … 41 42 } 42 43 } 43 public ILayoutNode<T> LeftmostSibling {44 public LayoutNode<T> LeftmostSibling { 44 45 get { 45 46 if (Parent == null) return null; … … 48 49 } 49 50 50 public ILayoutNode<T> Thread { get; set; }51 public ILayoutNode<T> Ancestor { get; set; }52 public ILayoutNode<T> Parent { get; set; }53 public List< ILayoutNode<T>> Children { get; set; }51 public LayoutNode<T> Thread { get; set; } 52 public LayoutNode<T> Ancestor { get; set; } 53 public LayoutNode<T> Parent { get; set; } 54 public List<LayoutNode<T>> Children { get; set; } 54 55 public float Mod { get; set; } 55 56 public float Prelim { get; set; } … … 65 66 } 66 67 67 public T Content { get; set; } 68 private T content; 69 public T Content { 70 get { return content; } 71 set { 72 if (value == null) 73 throw new ArgumentNullException("LayoutNode: Content cannot be null."); 74 content = value; 75 } 76 } 68 77 } 69 78 } -
branches/HeuristicLab.ReingoldTilfordTreeLayout/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/LayoutEngines/ReingoldTilfordLayoutEngine.cs
r9970 r10471 7 7 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { 8 8 public class ReingoldTilfordLayoutEngine<T> where T : class { 9 private readonly Dictionary<T, ILayoutNode<T>> nodes; // provides a reverse mapping T => ILayoutNode9 private readonly Dictionary<T, LayoutNode<T>> nodeMap; // provides a reverse mapping T => LayoutNode 10 10 11 11 public ReingoldTilfordLayoutEngine() { 12 node s = new Dictionary<T, ILayoutNode<T>>();13 } 14 15 public Dictionary<T, ILayoutNode<T>> Nodes { get { return nodes; } }16 17 public void AddNode(T content , ILayoutNode<T> node) {18 if (node s.ContainsKey(content)) {12 nodeMap = new Dictionary<T, LayoutNode<T>>(); 13 } 14 15 public Dictionary<T, LayoutNode<T>> NodeMap { get { return nodeMap; } } 16 17 public void AddNode(T content) { 18 if (nodeMap.ContainsKey(content)) { 19 19 throw new ArgumentException("Content already present in the dictionary."); 20 20 } 21 nodes.Add(content, node); 22 } 23 24 public ILayoutNode<T> GetNode(T content) { 25 ILayoutNode<T> ILayoutNode; 26 nodes.TryGetValue(content, out ILayoutNode); 27 return ILayoutNode; 21 var node = new LayoutNode<T> { Content = content }; 22 nodeMap.Add(content, node); 23 } 24 25 public void AddNode(LayoutNode<T> node) { 26 var content = node.Content; 27 if (nodeMap.ContainsKey(content)) { 28 throw new ArgumentException("Content already present in the dictionary."); 29 } 30 nodeMap.Add(content, node); 31 } 32 33 public void AddNodes(IEnumerable<LayoutNode<T>> nodes) { 34 foreach (var node in nodes) 35 nodeMap.Add(node.Content, node); 36 } 37 38 public LayoutNode<T> GetNode(T content) { 39 LayoutNode<T> layoutNode; 40 nodeMap.TryGetValue(content, out layoutNode); 41 return layoutNode; 28 42 } 29 43 … … 40 54 } 41 55 42 private ILayoutNode<T> root;43 public ILayoutNode<T> Root {56 private LayoutNode<T> root; 57 public LayoutNode<T> Root { 44 58 get { return root; } 45 59 set { … … 49 63 50 64 public void ResetCoordinates() { 51 foreach (var node in node s.Values) {65 foreach (var node in nodeMap.Values) { 52 66 node.X = 0; 53 67 node.Y = 0; … … 56 70 57 71 /// <summary> 58 /// Transform ILayoutNode coordinates so that all coordinates are positive and start from 0.72 /// Transform LayoutNode coordinates so that all coordinates are positive and start from 0. 59 73 /// </summary> 60 74 private void NormalizeCoordinates() { 61 var list = node s.Values.ToList();75 var list = nodeMap.Values.ToList(); 62 76 float xmin = 0, ymin = 0; 63 for (int i = 0; i !=list.Count; ++i) {77 for (int i = 0; i < list.Count; ++i) { 64 78 if (xmin > list[i].X) xmin = list[i].X; 65 79 if (ymin > list[i].Y) ymin = list[i].Y; 66 80 } 67 for (int i = 0; i !=list.Count; ++i) {81 for (int i = 0; i < list.Count; ++i) { 68 82 list[i].X -= xmin; 69 83 list[i].Y -= ymin; … … 73 87 public void Reset() { 74 88 root = null; 75 node s.Clear();89 nodeMap.Clear(); 76 90 } 77 91 78 92 public void ResetParameters() { 79 foreach (var layoutNode in node s.Values) {93 foreach (var layoutNode in nodeMap.Values) { 80 94 // reset layout-related parameters 81 95 layoutNode.Ancestor = layoutNode; … … 99 113 100 114 /// <summary> 101 /// Returns a map of coordinates for each ILayoutNode in the symbolic expression tree.115 /// Returns a map of coordinates for each LayoutNode in the symbolic expression tree. 102 116 /// </summary> 103 117 /// <returns></returns> 104 118 public Dictionary<T, PointF> GetNodeCoordinates() { 105 return node s.ToDictionary(x => x.Key, x => new PointF(x.Value.X, x.Value.Y));119 return nodeMap.ToDictionary(x => x.Key, x => new PointF(x.Value.X, x.Value.Y)); 106 120 } 107 121 … … 112 126 public RectangleF Bounds() { 113 127 float xmin, xmax, ymin, ymax; xmin = xmax = ymin = ymax = 0; 114 var list = node s.Values.ToList();115 for (int i = 0; i !=list.Count; ++i) {128 var list = nodeMap.Values.ToList(); 129 for (int i = 0; i < list.Count; ++i) { 116 130 float x = list[i].X, y = list[i].Y; 117 131 if (xmin > x) xmin = x; … … 123 137 } 124 138 125 private void FirstWalk( ILayoutNode<T> v) {126 ILayoutNode<T> w;139 private void FirstWalk(LayoutNode<T> v) { 140 LayoutNode<T> w; 127 141 if (v.IsLeaf) { 128 142 w = v.LeftSibling; … … 151 165 } 152 166 153 private void SecondWalk( ILayoutNode<T> v, float m) {167 private void SecondWalk(LayoutNode<T> v, float m) { 154 168 v.X = v.Prelim + m; 155 169 v.Y = v.Level * minVerticalSpacing; … … 160 174 } 161 175 162 private void Apportion( ILayoutNode<T> v, ref ILayoutNode<T> defaultAncestor) {176 private void Apportion(LayoutNode<T> v, ref LayoutNode<T> defaultAncestor) { 163 177 var w = v.LeftSibling; 164 178 if (w == null) return; 165 ILayoutNode<T> vip = v;166 ILayoutNode<T> vop = v;167 ILayoutNode<T> vim = w;168 ILayoutNode<T> vom = vip.LeftmostSibling;179 LayoutNode<T> vip = v; 180 LayoutNode<T> vop = v; 181 LayoutNode<T> vim = w; 182 LayoutNode<T> vom = vip.LeftmostSibling; 169 183 170 184 float sip = vip.Mod; … … 202 216 } 203 217 204 private void MoveSubtree( ILayoutNode<T> wm, ILayoutNode<T> wp, float shift) {205 int subtrees = wp.Number - wm.Number; // TODO: Investigate possible bug (if the value ever happens to be zero) - happens when the tree is actually a graph 206 if (subtrees == 0) throw new Exception( );218 private void MoveSubtree(LayoutNode<T> wm, LayoutNode<T> wp, float shift) { 219 int subtrees = wp.Number - wm.Number; // TODO: Investigate possible bug (if the value ever happens to be zero) - happens when the tree is actually a graph (but that's outside the use case of this algorithm which only works with trees) 220 if (subtrees == 0) throw new Exception("MoveSubtree failed: check if object is really a tree (no cycles)"); 207 221 wp.Change -= shift / subtrees; 208 222 wp.Shift += shift; … … 212 226 } 213 227 214 private void ExecuteShifts( ILayoutNode<T> v) {228 private void ExecuteShifts(LayoutNode<T> v) { 215 229 if (v.IsLeaf) return; 216 230 float shift = 0; … … 225 239 } 226 240 227 private ILayoutNode<T> Ancestor(ILayoutNode<T> u, ILayoutNode<T> v) {241 private LayoutNode<T> Ancestor(LayoutNode<T> u, LayoutNode<T> v) { 228 242 var ancestor = u.Ancestor; 229 243 if (ancestor == null) return null; -
branches/HeuristicLab.ReingoldTilfordTreeLayout/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/LayoutEngines/SymbolicExpressionTreeLayoutAdapter.cs
r9970 r10471 22 22 using System; 23 23 using System.Collections.Generic; 24 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.LayoutEngines;25 24 26 25 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { 27 26 // adapter class that provides some conversion methods from symbolic expression trees to layout nodes (preserving the tree structure) 28 27 public class SymbolicExpressionTreeLayoutAdapter : ILayoutAdapter<ISymbolicExpressionTreeNode> { 29 // default conversion function between ISymbolicExpressionTreeNode and ILayoutNode<ISymbolicExpressionTree>30 ILayoutNode<ISymbolicExpressionTreeNode> defaultConvert(ISymbolicExpressionTreeNode node) {28 // default conversion function between ISymbolicExpressionTreeNode and LayoutNode<ISymbolicExpressionTree> 29 LayoutNode<ISymbolicExpressionTreeNode> defaultConvert(ISymbolicExpressionTreeNode node) { 31 30 var layoutNode = new LayoutNode<ISymbolicExpressionTreeNode> { Content = node }; 32 31 layoutNode.Ancestor = layoutNode; … … 34 33 } 35 34 36 public IEnumerable< ILayoutNode<ISymbolicExpressionTreeNode>> Convert(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, ILayoutNode<ISymbolicExpressionTreeNode>> convertFunc = null) {35 public IEnumerable<LayoutNode<ISymbolicExpressionTreeNode>> Convert(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, LayoutNode<ISymbolicExpressionTreeNode>> convertFunc = null) { 37 36 return Convert(tree.Root, convertFunc); 38 37 } 39 38 // translate the symbolic expression tree structure to a layout node tree structure 40 39 // return an enumerable containing all the layout nodes 41 public IEnumerable< ILayoutNode<ISymbolicExpressionTreeNode>> Convert(ISymbolicExpressionTreeNode root, Func<ISymbolicExpressionTreeNode, ILayoutNode<ISymbolicExpressionTreeNode>> convertFunc = null) {40 public IEnumerable<LayoutNode<ISymbolicExpressionTreeNode>> Convert(ISymbolicExpressionTreeNode root, Func<ISymbolicExpressionTreeNode, LayoutNode<ISymbolicExpressionTreeNode>> convertFunc = null) { 42 41 var rootLayoutNode = convertFunc == null ? defaultConvert(root) : convertFunc(root); 43 42 rootLayoutNode.Ancestor = rootLayoutNode; 44 43 45 44 if (root.SubtreeCount > 0) { 46 rootLayoutNode.Children = new List< ILayoutNode<ISymbolicExpressionTreeNode>>(root.SubtreeCount);45 rootLayoutNode.Children = new List<LayoutNode<ISymbolicExpressionTreeNode>>(root.SubtreeCount); 47 46 Expand(rootLayoutNode, convertFunc); 48 47 } 49 48 50 var list = new List< ILayoutNode<ISymbolicExpressionTreeNode>> { rootLayoutNode };49 var list = new List<LayoutNode<ISymbolicExpressionTreeNode>> { rootLayoutNode }; 51 50 int i = 0; 52 51 while (i < list.Count) { 53 52 if (list[i].Children != null) 54 foreach (ILayoutNode<ISymbolicExpressionTreeNode> child in list[i].Children) 55 list.Add(child); 53 list.AddRange(list[i].Children); 54 // foreach (LayoutNode<ISymbolicExpressionTreeNode> child in list[i].Children) 55 // list.Add(child); 56 56 ++i; 57 57 } … … 59 59 } 60 60 61 private void Expand( ILayoutNode<ISymbolicExpressionTreeNode> layoutNode, Func<ISymbolicExpressionTreeNode, ILayoutNode<ISymbolicExpressionTreeNode>> convertFunc = null) {61 private void Expand(LayoutNode<ISymbolicExpressionTreeNode> layoutNode, Func<ISymbolicExpressionTreeNode, LayoutNode<ISymbolicExpressionTreeNode>> convertFunc = null) { 62 62 if (layoutNode.Children == null) return; 63 63 for (int i = 0; i < layoutNode.Content.SubtreeCount; ++i) { … … 68 68 childLayoutNode.Level = layoutNode.Level + 1; 69 69 childLayoutNode.Ancestor = childLayoutNode; 70 childLayoutNode.Children = subtree.SubtreeCount > 0 ? new List< ILayoutNode<ISymbolicExpressionTreeNode>>(subtree.SubtreeCount) : null;70 childLayoutNode.Children = subtree.SubtreeCount > 0 ? new List<LayoutNode<ISymbolicExpressionTreeNode>>(subtree.SubtreeCount) : null; 71 71 layoutNode.Children.Add(childLayoutNode); 72 72 Expand(childLayoutNode, convertFunc);
Note: See TracChangeset
for help on using the changeset viewer.