Changeset 11229 for branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph
- Timestamp:
- 07/29/14 16:20:08 (10 years ago)
- Location:
- branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph
- Files:
-
- 6 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]
Note: See TracChangeset
for help on using the changeset viewer.