Changeset 11229 for branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic
- Timestamp:
- 07/29/14 16:20:08 (10 years ago)
- Location:
- branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph/Arc.cs
r11211 r11229 20 20 #endregion 21 21 22 using System; 22 23 using HeuristicLab.Common; 23 24 using HeuristicLab.Core; … … 26 27 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 27 28 /// <summary> 28 /// An arc that can have a weight, a label, and can old additional information in the Data object29 /// An arc that can have a weight, a label, and a data object for holding additional info 29 30 /// </summary> 30 31 [StorableClass] 31 32 public class Arc : Item, IArc { 32 [Storable] 33 public IVertex Source { get; set; } 33 public event EventHandler Changed; 34 protected virtual void OnChanged(object sender, EventArgs args) { 35 var changed = Changed; 36 if (changed != null) 37 changed(sender, args); 38 } 34 39 35 40 [Storable] 36 public IVertex Target { get;set; }41 public IVertex Source { get; private set; } 37 42 38 43 [Storable] 39 public string Label { get;set; }44 public IVertex Target { get; private set; } 40 45 41 46 [Storable] 42 public double Weight { get; set; } 47 protected string label; 48 public string Label { 49 get { return label; } 50 set { 51 label = value; 52 OnChanged(this, EventArgs.Empty); 53 } 54 } 43 55 44 56 [Storable] 45 public object Data { get; set; } 57 protected double weight; 58 public double Weight { 59 get { return weight; } 60 set { 61 weight = value; 62 OnChanged(this, EventArgs.Empty); 63 } 64 } 65 66 [Storable] 67 protected object data; 68 public object Data { 69 get { return data; } 70 set { 71 data = value; 72 OnChanged(this, EventArgs.Empty); 73 } 74 } 46 75 47 76 [StorableConstructor] 48 77 public Arc(bool deserializing) : base(deserializing) { } 49 50 public override IDeepCloneable Clone(Cloner cloner) {51 return new Arc(this, cloner);52 }53 public Arc() { }54 78 55 79 public Arc(IVertex source, IVertex target) { … … 60 84 protected Arc(Arc original, Cloner cloner) 61 85 : base(original, cloner) { 62 Source = original.Source; 63 Target = original.Target; 64 Label = original.Label; 65 Weight = original.Weight; 66 Data = original.Data; 86 Source = cloner.Clone(original.Source); 87 Target = cloner.Clone(original.Target); 88 label = original.Label; 89 weight = original.Weight; 90 data = original; 91 } 92 93 public override IDeepCloneable Clone(Cloner cloner) { 94 return new Arc(this, cloner); 95 } 96 } 97 98 [StorableClass] 99 public class Arc<T> : Arc, IArc<T> where T : class,IItem { 100 public Arc(bool deserializing) 101 : base(deserializing) { 102 } 103 104 public Arc(IVertex source, IVertex target) 105 : base(source, target) { 106 } 107 108 protected Arc(Arc original, Cloner cloner) 109 : base(original, cloner) { 110 } 111 112 new public IVertex<T> Source { 113 get { return (IVertex<T>)base.Source; } 114 } 115 new public IVertex<T> Target { 116 get { return (IVertex<T>)base.Target; } 67 117 } 68 118 } -
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph/DirectedGraph.cs
r11211 r11229 24 24 using System.Drawing; 25 25 using System.Linq; 26 using System.Text;27 26 using HeuristicLab.Common; 28 27 using HeuristicLab.Core; … … 33 32 [StorableClass] 34 33 public class DirectedGraph : Item, IDirectedGraph { 35 public bool AllowDuplicateContent { get; set; } 36 34 protected HashSet<IVertex> vertices; 37 35 [Storable] 38 protected readonly List<IVertex> vertices; // for performance reasons, maybe this should be a linked list (fast remove)39 36 public IEnumerable<IVertex> Vertices { 40 37 get { return vertices; } 38 private set { vertices = new HashSet<IVertex>(value); } 41 39 } 42 40 41 protected HashSet<IArc> arcs; 43 42 [Storable] 44 private readonly Dictionary<string, IVertex> idMap;45 46 [Storable]47 private readonly Dictionary<object, IVertex> contentMap;48 49 [Storable]50 protected readonly List<IArc> arcs;51 43 public IEnumerable<IArc> Arcs { 52 44 get { return arcs; } 45 private set { arcs = new HashSet<IArc>(value); } 53 46 } 54 47 … … 60 53 [StorableHook(HookType.AfterDeserialization)] 61 54 private void AfterDeserialization() { 62 foreach (var arc in arcs) { 63 arc.Source.AddForwardArc(arc); 64 arc.Target.AddReverseArc(arc); 55 foreach (var vertex in vertices) { 56 vertex.ArcAdded += OnArcAdded; 57 vertex.ArcRemoved += OnArcRemoved; 58 vertex.Changed += OnVertexChanged; 65 59 } 66 60 67 foreach (var vertex in vertices) { 68 vertex.PreContentChanged += Vertex_PreContentChanged; 69 vertex.PostContentChanged += Vertex_PostContentChanged; 61 foreach (var arc in arcs) { 62 var source = arc.Source; 63 var target = arc.Target; 64 source.AddArc(arc); 65 target.AddArc(arc); 66 arc.Changed += OnArcChanged; 70 67 } 71 68 } 72 69 73 70 public DirectedGraph() { 74 vertices = new List<IVertex>(); 75 arcs = new List<IArc>(); 76 contentMap = new Dictionary<object, IVertex>(); 77 idMap = new Dictionary<string, IVertex>(); 71 vertices = new HashSet<IVertex>(); 72 arcs = new HashSet<IArc>(); 78 73 } 79 74 80 75 protected DirectedGraph(DirectedGraph original, Cloner cloner) 81 76 : base(original, cloner) { 82 vertices = new List<IVertex>(original.vertices); 83 arcs = new List<IArc>(original.arcs); 84 contentMap = new Dictionary<object, IVertex>(original.contentMap); 85 idMap = new Dictionary<string, IVertex>(original.idMap); 77 vertices = new HashSet<IVertex>(original.vertices.Select(cloner.Clone)); 78 arcs = new HashSet<IArc>(original.arcs.Select(cloner.Clone)); 86 79 } 87 80 … … 90 83 } 91 84 92 public bool Contains(IVertex t) {93 return vertices.Contains(t);94 }95 96 public bool Contains(object content) {97 return contentMap.ContainsKey(content);98 }99 100 public IVertex GetVertex(string id) {101 IVertex result;102 idMap.TryGetValue(id, out result);103 return result;104 }105 106 public IVertex GetVertex(object content) {107 IVertex result;108 contentMap.TryGetValue(content, out result);109 return result;110 }111 112 public virtual bool Any(Func<IVertex, bool> predicate) {113 return vertices.Any(predicate);114 }115 116 public virtual bool IsEmpty {117 get { return !vertices.Any(); }118 }119 120 85 public virtual void Clear() { 121 86 vertices.Clear(); 122 contentMap.Clear(); 123 idMap.Clear(); 87 arcs.Clear(); 124 88 } 125 89 126 90 public virtual void AddVertex(IVertex vertex) { 127 if (vertex.Content != null) {128 if (!AllowDuplicateContent && contentMap.ContainsKey(vertex.Content)) {129 throw new Exception("Content already exists in the graph.");130 }131 contentMap[vertex.Content] = vertex;132 }133 idMap.Add(vertex.Id, vertex);134 91 vertices.Add(vertex); 135 136 vertex.PreContentChanged += Vertex_PreContentChanged; 137 vertex.PostContentChanged += Vertex_PostContentChanged; 92 // register event handlers 93 vertex.Changed += OnVertexChanged; 94 vertex.ArcAdded += OnArcAdded; 95 vertex.ArcRemoved += OnArcRemoved; 96 OnVertexAdded(this, EventArgs.Empty); 138 97 } 139 98 140 99 public virtual void RemoveVertex(IVertex vertex) { 141 contentMap.Remove(vertex.Content);142 idMap.Remove(vertex.Id);143 100 vertices.Remove(vertex); 144 145 101 // remove connections to/from the removed vertex 146 foreach (var arc in vertex.InArcs) { 147 arc.Source.OutArcs = arc.Source.OutArcs.Where(x => x.Target != vertex); 148 } 149 foreach (var arc in vertex.OutArcs) { 150 arc.Target.InArcs = arc.Target.InArcs.Where(x => x.Source != vertex); 151 } 152 // de-register event handlers 153 vertex.PreContentChanged -= Vertex_PreContentChanged; 154 vertex.PostContentChanged -= Vertex_PostContentChanged; 102 foreach (var arc in vertex.InArcs.Concat(vertex.OutArcs)) 103 RemoveArc(arc); 104 // deregister event handlers 105 vertex.ArcAdded -= OnArcAdded; 106 vertex.ArcRemoved -= OnArcRemoved; 107 vertex.Changed -= OnVertexChanged; 108 OnVertexRemoved(this, EventArgs.Empty); 155 109 } 156 110 157 public virtualIArc AddArc(IVertex source, IVertex target) {111 public IArc AddArc(IVertex source, IVertex target) { 158 112 var arc = new Arc(source, target); 159 source.AddForwardArc(arc); 160 target.AddReverseArc(arc); 161 arcs.Add(arc); 113 AddArc(arc); 162 114 return arc; 163 115 } 164 116 165 private void Vertex_PreContentChanged(object sender, EventArgs args) { 166 var vertex = (IVertex)sender; 167 if (contentMap.ContainsKey(vertex.Content)) { 168 contentMap.Remove(vertex.Content); 169 } 117 public void AddArc(IArc arc) { 118 var source = (Vertex)arc.Source; 119 var target = (Vertex)arc.Target; 120 source.AddArc(arc); 121 target.AddArc(arc); 122 arcs.Add(arc); 170 123 } 171 124 172 private void Vertex_PostContentChanged(object sender, EventArgs args) { 173 var vertex = (IVertex)sender; 174 if (vertex.Content != null) 175 contentMap.Add(vertex.Content, vertex); 125 public void RemoveArc(IArc arc) { 126 arcs.Remove(arc); 127 var source = (Vertex)arc.Source; 128 var target = (Vertex)arc.Target; 129 source.RemoveArc(arc); 130 target.RemoveArc(arc); 176 131 } 132 133 public event EventHandler VertexAdded; 134 protected virtual void OnVertexAdded(object sender, EventArgs args) { 135 var added = VertexAdded; 136 if (added != null) 137 added(sender, args); 138 } 139 140 public event EventHandler VertexChanged; 141 protected virtual void OnVertexChanged(object sender, EventArgs args) { 142 var changed = VertexChanged; 143 if (changed != null) 144 changed(sender, args); 145 } 146 147 public event EventHandler VertexRemoved; 148 protected virtual void OnVertexRemoved(object sender, EventArgs args) { 149 var removed = VertexRemoved; 150 if (removed != null) 151 removed(sender, args); 152 } 153 154 protected virtual void OnArcAdded(object sender, EventArgs<IArc> args) { 155 var arc = args.Value; 156 // the ArcAdded event is fired by a vertex when an arc from or towards another vertex is added to his list of connections 157 // because the arc is added in both directions by both the source and the target, this event will get fired twice 158 // here, we only want to add the arc once, so if its already contained, we return without complaining 159 if (arcs.Contains(arc)) return; 160 arcs.Add(arc); 161 arc.Changed += OnArcChanged; 162 } 163 164 protected virtual void OnArcRemoved(object sender, EventArgs<IArc> args) { 165 var arc = args.Value; 166 if (!arcs.Contains(arc)) return; // the same rationale as above 167 arcs.Remove(arc); 168 arc.Changed -= OnArcChanged; 169 } 170 171 protected virtual void OnArcChanged(object sender, EventArgs args) { } 177 172 178 173 public override Image ItemImage { 179 174 get { return Common.Resources.VSImageLibrary.Graph; } 180 175 } 181 182 public string ExportDot() {183 var sb = new StringBuilder();184 sb.Append("digraph g {");185 foreach (var v in Vertices) {186 sb.Append("\"" + v.Id + "\" [label=\"" + v.Label + "\"];" + Environment.NewLine);187 }188 189 foreach (var v in Vertices) {190 foreach (var c in v.OutArcs.Select(x => x.Target)) {191 sb.Append("\"" + v.Id + "\" -> \"" + c.Id + "\"" + Environment.NewLine);192 }193 }194 sb.Append("}");195 return sb.ToString();196 }197 176 } 198 177 } -
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph/Interfaces/IArc.cs
r11211 r11229 20 20 #endregion 21 21 22 using System; 23 using HeuristicLab.Core; 22 24 23 25 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 24 public interface IArc { 25 IVertex Source { get; set; } 26 IVertex Target { get; set; } 26 public interface IArc : IItem { 27 event EventHandler Changed; // generic event for when the label, weight or data were changed 28 IVertex Source { get; } 29 IVertex Target { get; } 27 30 string Label { get; set; } 28 31 double Weight { get; set; } … … 30 33 } 31 34 32 public interface IArc<T> : IArc where T : class,I Vertex{33 new T Source { get; set; }34 new T Target { get; set; }35 public interface IArc<T> : IArc where T : class,IItem { 36 new IVertex<T> Source { get; } 37 new IVertex<T> Target { get; } 35 38 } 36 39 } -
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph/Interfaces/IDirectedGraph.cs
r11211 r11229 20 20 #endregion 21 21 22 using System;23 22 using System.Collections.Generic; 24 23 using HeuristicLab.Core; … … 26 25 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 27 26 public interface IDirectedGraph : IItem { 28 bool Contains(IVertex vertex);29 bool Any(Func<IVertex, bool> predicate);30 27 void Clear(); 31 28 void AddVertex(IVertex vertex); 32 29 IArc AddArc(IVertex source, IVertex target); 30 void AddArc(IArc arc); 33 31 void RemoveVertex(IVertex vertex); 32 void RemoveArc(IArc arc); 34 33 IEnumerable<IVertex> Vertices { get; } 35 bool Contains(object content); 36 IVertex GetVertex(string id); 37 IVertex GetVertex(object content); 34 IEnumerable<IArc> Arcs { get; } 38 35 } 39 36 } -
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph/Interfaces/IVertex.cs
r11211 r11229 22 22 using System; 23 23 using System.Collections.Generic; 24 using HeuristicLab.Common; 24 25 using HeuristicLab.Core; 25 26 26 27 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 27 28 public interface IVertex : IItem { 28 event EventHandler PreContentChanged; 29 event EventHandler PostContentChanged; 29 event EventHandler Changed; // generic event for when the content, label or weight have changed 30 event EventHandler<EventArgs<IArc>> ArcAdded; 31 event EventHandler<EventArgs<IArc>> ArcRemoved; 30 32 31 string Id { get; } 32 IEnumerable<IArc> InArcs { get; set; } 33 IEnumerable<IArc> OutArcs { get; set; } 33 IEnumerable<IArc> InArcs { get; } 34 IEnumerable<IArc> OutArcs { get; } 34 35 35 36 int InDegree { get; } … … 40 41 double Weight { get; set; } 41 42 42 void AddForwardArc(IArc arc); 43 void AddReverseArc(IArc arc); 43 object Content { get; set; } 44 44 45 object Content { get; set; } 45 void AddArc(IArc arc); 46 void RemoveArc(IArc arc); 47 void RemoveArc(IVertex vertex); 46 48 } 47 49 -
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph/Vertex.cs
r11211 r11229 30 30 [StorableClass] 31 31 public class Vertex : Item, IVertex { 32 public event EventHandler PreContentChanged; 33 protected virtual void OnPreContentChanged(object sender, EventArgs args) { 34 var changed = PreContentChanged; 35 if (changed != null) { 32 // use the same event to signal a change in the content, weight or label 33 public event EventHandler Changed; 34 protected virtual void OnChanged(object sender, EventArgs args) { 35 var changed = Changed; 36 if (changed != null) 36 37 changed(sender, args); 37 }38 38 } 39 39 40 public event EventHandler PostContentChanged; 41 protected virtual void OnPostContentChanged(object sender, EventArgs args) { 42 var changed = PostContentChanged; 43 if (changed != null) { 44 changed(sender, args); 40 public event EventHandler<EventArgs<IArc>> ArcAdded; 41 protected virtual void OnArcAdded(object sender, EventArgs<IArc> args) { 42 var added = ArcAdded; 43 if (added != null) 44 added(sender, args); 45 } 46 47 public event EventHandler<EventArgs<IArc>> ArcRemoved; 48 protected virtual void OnArcRemoved(object sender, EventArgs<IArc> args) { 49 var removed = ArcRemoved; 50 if (removed != null) 51 removed(sender, args); 52 } 53 54 [Storable] 55 protected string label; 56 public string Label { 57 get { return label; } 58 set { 59 label = value; 60 OnChanged(this, EventArgs.Empty); 45 61 } 46 62 } 47 63 48 64 [Storable] 49 private string id; 50 51 public string Id { 52 get { return id; } 65 protected double weight; 66 public double Weight { 67 get { return weight; } 68 set { 69 weight = value; 70 OnChanged(this, EventArgs.Empty); 71 } 53 72 } 54 55 [Storable]56 public string Label { get; set; }57 58 [Storable]59 public double Weight { get; set; }60 73 61 74 [Storable] … … 64 77 get { return content; } 65 78 set { 66 OnPreContentChanged(this, EventArgs.Empty);67 79 content = value; 68 On PostContentChanged(this, EventArgs.Empty);80 OnChanged(this, EventArgs.Empty); 69 81 } 70 82 } … … 73 85 public IEnumerable<IArc> InArcs { 74 86 get { return inArcs ?? Enumerable.Empty<IArc>(); } 75 set { inArcs = value.ToList(); }76 87 } 77 88 … … 79 90 public IEnumerable<IArc> OutArcs { 80 91 get { return outArcs ?? Enumerable.Empty<IArc>(); } 81 set { outArcs = value.ToList(); }82 92 } 83 93 … … 85 95 public Vertex(bool deserializing) : base(deserializing) { } 86 96 87 public Vertex() { 88 id = Guid.NewGuid().ToString(); 89 } 97 [StorableHook(HookType.AfterDeserialization)] 98 private void AfterDeserialization() { } 99 100 private Vertex() { } 90 101 91 102 public Vertex(object content) … … 96 107 protected Vertex(Vertex original, Cloner cloner) 97 108 : base(original, cloner) { 98 id = Guid.NewGuid().ToString();99 109 content = original.content; 100 Label = original.Label; 101 Weight = original.Weight; 102 inArcs = new List<IArc>(original.inArcs); 103 outArcs = new List<IArc>(original.outArcs); 110 label = original.Label; 111 weight = original.Weight; 112 113 inArcs = original.InArcs.Select(cloner.Clone).ToList(); 114 outArcs = original.OutArcs.Select(cloner.Clone).ToList(); 104 115 } 105 116 … … 108 119 } 109 120 110 [StorableHook(HookType.AfterDeserialization)] 111 private void AfterDeserialization() { 112 if (Id == null) { 113 id = Guid.NewGuid().ToString(); 121 public void AddArc(IArc arc) { 122 if (this != arc.Source && this != arc.Target) 123 throw new InvalidOperationException("The current vertex must be either the arc source or the arc target."); 124 125 if (this == arc.Source) { 126 if (outArcs == null) 127 outArcs = new List<IArc>(); 128 else if (outArcs.Contains(arc) || outArcs.Any(a => a.Target == arc.Target && a.Source == arc.Source)) 129 throw new InvalidOperationException("Arc already added."); 130 outArcs.Add(arc); 131 } else if (this == arc.Target) { 132 if (inArcs == null) 133 inArcs = new List<IArc>(); 134 else if (inArcs.Contains(arc) || inArcs.Any(a => a.Target == arc.Target && a.Source == arc.Source)) 135 throw new InvalidOperationException("Arc already added."); 136 inArcs.Add(arc); 137 } 138 OnArcAdded(this, new EventArgs<IArc>(arc)); 139 } 140 141 public void RemoveArc(IVertex vertex) { 142 try { 143 var arc = inArcs.Concat(outArcs).SingleOrDefault(x => x.Target == vertex || x.Source == vertex); 144 RemoveArc(arc); 145 } 146 catch (Exception) { 147 throw new InvalidOperationException("Only one arc allowed between two vertices"); 114 148 } 115 149 } 116 150 117 // this method can be used to add arcs towards targets that are not visible in the graph 118 // (they do not appear in the nodes Dictionary). It is the programmers responsibility to 119 // enforce the correct and desired behavior. 120 public void AddForwardArc(IArc arc) { 121 if (arc.Source != this) { throw new Exception("AddForwardArc: Source should be equal to this."); } 122 if (outArcs == null) 123 outArcs = new List<IArc>(); 124 outArcs.Add(arc); 151 public void RemoveArc(IArc arc) { 152 if (this != arc.Source && this != arc.Target) 153 throw new InvalidOperationException("The current vertex must be either the arc source or the arc target."); 154 155 if (this == arc.Source && outArcs != null) { 156 if (!outArcs.Remove(arc)) 157 throw new InvalidOperationException("Arc is not present in this vertex' outgoing arcs."); 158 } else if (this == arc.Target && inArcs != null) { 159 if (!inArcs.Remove(arc)) 160 throw new InvalidOperationException("Arc is not present in this vertex' incoming arcs."); 161 } 162 OnArcRemoved(this, new EventArgs<IArc>(arc)); 125 163 } 126 public void AddReverseArc(IArc arc) { 127 if (arc.Target != this) { throw new Exception("AddReverseArc: Target should be equal to this."); }; 128 if (inArcs == null) 129 inArcs = new List<IArc>(); 130 inArcs.Add(arc); 131 } 164 132 165 public int InDegree { get { return InArcs.Count(); } } 133 166 public int OutDegree { get { return OutArcs.Count(); } } … … 141 174 set { base.Content = value; } 142 175 } 143 144 public Vertex() { }145 176 146 177 [StorableConstructor] -
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Matching/SymbolicExpressionTreeMaxCommonSequenceCalculator.cs
r10562 r11229 2 2 using System.Collections.Generic; 3 3 4 namespace HeuristicLab.Problems.DataAnalysis.Symbolic .Matching{4 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 5 5 public class MaxCommonSequenceCalculator<T, U> 6 6 where T : class -
branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SimilarityCalculators/BottomUpSimilarityCalculator.cs
r11225 r11229 22 22 using System; 23 23 using System.Collections.Generic; 24 using System.Drawing;25 using System.Globalization;26 24 using System.Linq; 27 using System.Text;28 25 using HeuristicLab.Common; 29 26 using HeuristicLab.Core; 30 27 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 31 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;32 28 using HeuristicLab.Optimization.Operators; 33 29 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; … … 78 74 79 75 // visit nodes in order of decreasing height to ensure correct mapping 80 foreach (var v in n1.IterateNodesPrefix().OrderByDescending(x => compactedGraph[x]. Weight)) {76 foreach (var v in n1.IterateNodesPrefix().OrderByDescending(x => compactedGraph[x].Depth)) { 81 77 if (forwardMap.ContainsKey(v)) 82 78 continue; … … 115 111 /// Creates a compact representation of the two trees as a directed acyclic graph 116 112 /// </summary> 117 /// <param name=" t1">The first tree</param>118 /// <param name=" t2">The second tree</param>113 /// <param name="n1">The root of the first tree</param> 114 /// <param name="n2">The root of the second tree</param> 119 115 /// <returns>The compacted DAG representing the two trees</returns> 120 private Dictionary<ISymbolicExpressionTreeNode, IVertex> Compact(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) {121 var node sToVertices = new Dictionary<ISymbolicExpressionTreeNode, IVertex>(); // K122 var label sToVertices = new Dictionary<string, IVertex>(); // L116 private Dictionary<ISymbolicExpressionTreeNode, GraphNode> Compact(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) { 117 var nodeMap = new Dictionary<ISymbolicExpressionTreeNode, GraphNode>(); // K 118 var labelMap = new Dictionary<string, GraphNode>(); // L 123 119 var childrenCount = new Dictionary<ISymbolicExpressionTreeNode, int>(); // Children 124 var vertices = new List<IVertex>(); // G125 120 126 121 var nodes = n1.IterateNodesPostfix().Concat(n2.IterateNodesPostfix()); // the disjoint union F 122 var list = new List<GraphNode>(); 127 123 var queue = new Queue<ISymbolicExpressionTreeNode>(); 128 124 … … 130 126 if (n.SubtreeCount == 0) { 131 127 var label = n.ToString(); 132 if (!label sToVertices.ContainsKey(label)) {133 var z = new Vertex { Content= n, Label = label };134 label sToVertices[z.Label] = z;135 vertices.Add(z);136 } 137 node sToVertices[n] = labelsToVertices[label];128 if (!labelMap.ContainsKey(label)) { 129 var z = new GraphNode { SymbolicExpressionTreeNode = n, Label = label }; 130 labelMap[z.Label] = z; 131 list.Add(z); 132 } 133 nodeMap[n] = labelMap[label]; 138 134 queue.Enqueue(n); 139 135 } else { … … 141 137 } 142 138 } 143 144 139 while (queue.Any()) { 145 var v= queue.Dequeue();146 147 if ( v.SubtreeCount > 0) {148 var label = v.Symbol.Name;140 var n = queue.Dequeue(); 141 142 if (n.SubtreeCount > 0) { 143 var label = n.Symbol.Name; 149 144 bool found = false; 150 var height = v.GetDepth();145 var depth = n.GetDepth(); 151 146 152 147 bool sort = commutativeSymbols.Contains(label); 153 var vSubtrees = v.Subtrees.Select(x => nodesToVertices[x]).ToList(); 154 if (sort) vSubtrees.Sort((a, b) => String.Compare(a.Label, b.Label, StringComparison.Ordinal)); 155 156 // for all nodes w in G in reverse order 157 for (int i = vertices.Count - 1; i >= 0; --i) { 158 var w = vertices[i]; 159 var n = (ISymbolicExpressionTreeNode)w.Content; 160 if (v.SubtreeCount != n.SubtreeCount || label != w.Label || height != (int)w.Weight) 148 var nNodes = n.Subtrees.Select(x => nodeMap[x]).ToList(); 149 if (sort) nNodes.Sort((a, b) => String.Compare(a.Label, b.Label, StringComparison.Ordinal)); 150 151 for (int i = list.Count - 1; i >= 0; --i) { 152 var w = list[i]; 153 154 if (!(n.SubtreeCount == w.ChildrenCount && label == w.Label && depth == w.Depth)) 161 155 continue; 162 156 163 157 // sort V and W when the symbol is commutative because we are dealing with unordered trees 164 var wSubtrees = n.Subtrees.Select(x => nodesToVertices[x]).ToList(); 165 if (sort) wSubtrees.Sort((a, b) => String.Compare(a.Label, b.Label, StringComparison.Ordinal)); 166 167 if (vSubtrees.SequenceEqual(wSubtrees)) { 168 nodesToVertices[v] = w; 158 var m = w.SymbolicExpressionTreeNode; 159 var mNodes = m.Subtrees.Select(x => nodeMap[x]).ToList(); 160 if (sort) mNodes.Sort((a, b) => String.Compare(a.Label, b.Label, StringComparison.Ordinal)); 161 162 if (nNodes.SequenceEqual(mNodes)) { 163 nodeMap[n] = w; 169 164 found = true; 170 165 break; 171 166 } 172 } // 32: end for167 } 173 168 174 169 if (!found) { 175 var w = new Vertex { Content = v, Label = label, Weight = height }; 176 vertices.Add(w); 177 nodesToVertices[v] = w; 178 179 foreach (var u in v.Subtrees) { 180 AddArc(w, nodesToVertices[u]); 181 } // 40: end for 182 } // 41: end if 183 } // 42: end if 184 185 var p = v.Parent; 170 var w = new GraphNode { SymbolicExpressionTreeNode = n, Label = label, Depth = depth, ChildrenCount = n.SubtreeCount }; 171 list.Add(w); 172 nodeMap[n] = w; 173 } 174 } 175 176 var p = n.Parent; 186 177 if (p == null) 187 178 continue; … … 193 184 } 194 185 195 return node sToVertices;186 return nodeMap; 196 187 } 197 188 … … 202 193 var n = list[i]; 203 194 if (n.SubtreeCount > 0) { 204 var subtrees = commutativeSymbols.Contains(node.Symbol.Name) ? n.Subtrees.OrderBy( s => s.ToString()) : n.Subtrees;195 var subtrees = commutativeSymbols.Contains(node.Symbol.Name) ? n.Subtrees.OrderBy(x => x.ToString(), StringComparer.Ordinal) : n.Subtrees; 205 196 list.AddRange(subtrees); 206 197 } … … 210 201 } 211 202 212 private static IArc AddArc(IVertex source, IVertex target) { 213 var arc = new Arc(source, target); 214 source.AddForwardArc(arc); 215 target.AddReverseArc(arc); 216 return arc; 217 } 218 219 // debugging 220 private static string FormatMapping(ISymbolicExpressionTree t1, ISymbolicExpressionTree t2, Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> map) { 221 var symbolNameMap = new Dictionary<string, string> 222 { 223 {"ProgramRootSymbol", "Prog"}, 224 {"StartSymbol","RPB"}, 225 {"Multiplication", "$\\times$"}, 226 {"Division", "$\\div$"}, 227 {"Addition", "$+$"}, 228 {"Subtraction", "$-$"}, 229 {"Exponential", "$\\exp$"}, 230 {"Logarithm", "$\\log$"} 231 }; 232 233 var sb = new StringBuilder(); 234 var nodeIds = new Dictionary<ISymbolicExpressionTreeNode, string>(); 235 int offset = 0; 236 var layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>(x => x.Subtrees); 237 var nodeCoordinates = layoutEngine.CalculateLayout(t1.Root).ToDictionary(n => n.Content, n => new PointF(n.X, n.Y)); 238 239 double ws = 0.5; 240 double hs = 0.5; 241 242 var nl = Environment.NewLine; 243 sb.Append("\\documentclass[class=minimal,border=0pt]{standalone}" + nl + 244 "\\usepackage{tikz}" + nl + 245 "\\begin{document}" + nl + 246 "\\begin{tikzpicture}" + nl + 247 "\\def\\ws{1}" + nl + 248 "\\def\\hs{0.7}" + nl + 249 "\\def\\offs{" + offset + "}" + nl); 250 251 foreach (var node in t1.IterateNodesBreadth()) { 252 var id = Guid.NewGuid().ToString(); 253 nodeIds[node] = id; 254 var coord = nodeCoordinates[node]; 255 var nodeName = symbolNameMap.ContainsKey(node.Symbol.Name) ? symbolNameMap[node.Symbol.Name] : node.ToString(); 256 sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "\\node ({0}) at (\\ws*{1} + \\offs,\\hs*{2}) {{{3}}};", nodeIds[node], ws * coord.X, -hs * coord.Y, EscapeLatexString(nodeName))); 257 } 258 259 foreach (ISymbolicExpressionTreeNode t in t1.IterateNodesBreadth()) { 260 var n = t; 261 foreach (var s in t.Subtrees) { 262 sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "\\draw ({0}) -- ({1});", nodeIds[n], nodeIds[s])); 263 } 264 } 265 266 nodeCoordinates = layoutEngine.CalculateLayout(t2.Root).ToDictionary(n => n.Content, n => new PointF(n.X, n.Y)); 267 268 offset = 20; 269 sb.Append("\\def\\offs{" + offset + "}" + nl); 270 foreach (var node in t2.IterateNodesBreadth()) { 271 var id = Guid.NewGuid().ToString(); 272 nodeIds[node] = id; 273 var coord = nodeCoordinates[node]; 274 var nodeName = symbolNameMap.ContainsKey(node.Symbol.Name) ? symbolNameMap[node.Symbol.Name] : node.ToString(); 275 sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "\\node ({0}) at (\\ws*{1} + \\offs,\\hs*{2}) {{{3}}};", nodeIds[node], ws * coord.X, -hs * coord.Y, EscapeLatexString(nodeName))); 276 } 277 278 foreach (ISymbolicExpressionTreeNode t in t2.IterateNodesBreadth()) { 279 var n = t; 280 foreach (var s in t.Subtrees) { 281 sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "\\draw ({0}) -- ({1});", nodeIds[n], nodeIds[s])); 282 } 283 } 284 285 foreach (var p in map) { 286 var id1 = nodeIds[p.Key]; 287 var id2 = nodeIds[p.Value]; 288 289 sb.Append(string.Format(CultureInfo.InvariantCulture, "\\path[draw,->,color=gray] ({0}) edge[bend left,dashed] ({1});" + Environment.NewLine, id1, id2)); 290 } 291 sb.Append("\\end{tikzpicture}" + nl + 292 "\\end{document}" + nl); 293 return sb.ToString(); 294 } 295 296 private static string EscapeLatexString(string s) { 297 return s.Replace("\\", "\\\\").Replace("{", "\\{").Replace("}", "\\}").Replace("_", "\\_"); 203 private class GraphNode { 204 public ISymbolicExpressionTreeNode SymbolicExpressionTreeNode; 205 public string Label; 206 public int Depth; 207 public int ChildrenCount; 298 208 } 299 209 }
Note: See TracChangeset
for help on using the changeset viewer.