Changeset 7779 for branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/GenealogyGraph.cs
- Timestamp:
- 05/03/12 12:26:11 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/GenealogyGraph.cs
r7522 r7779 1 using System; 1 #region License Information 2 /* HeuristicLab 3 * Copyright (C) 2002-2010 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 System.Collections.Generic; 3 24 using System.Drawing; … … 8 29 9 30 namespace HeuristicLab.EvolutionaryTracking { 10 public class GenealogyGraph : NamedItem { 11 private readonly Dictionary<object, Node> _dictionary; 31 [Item("Genealogy graph", "Generic class for tracking the evolution of objects.")] 32 public class GenealogyGraph<T> : NamedItem, IGenealogyGraph<T> where T : class { 33 private readonly Dictionary<T, GenealogyGraphNode> _dictionary; 12 34 13 35 public GenealogyGraph() { 14 _dictionary = new Dictionary< object,Node>();15 } 16 17 public GenealogyGraph(GenealogyGraph g) {18 _dictionary = new Dictionary< object,Node>(g._dictionary);36 _dictionary = new Dictionary<T, GenealogyGraphNode>(); 37 } 38 39 public GenealogyGraph(GenealogyGraph<T> g) { 40 _dictionary = new Dictionary<T, GenealogyGraphNode>(g._dictionary); 19 41 } 20 42 21 43 public override IDeepCloneable Clone(Cloner cloner) { 22 return new GenealogyGraph(this, cloner); 23 } 24 25 public override string ItemName { 26 get { return "GenealogyGraph"; } 27 } 28 29 public override string ItemDescription { 30 get { return "A graph describing the genealogies of all the individuals"; } 31 } 32 33 public new Version ItemVersion { 34 get { return new Version(3, 3, 6); } 35 } 36 37 public new Image ItemImage { 44 return new GenealogyGraph<T>(this, cloner); 45 } 46 47 public override Image ItemImage { 38 48 get { return Common.Resources.VSImageLibrary.Graph; } 39 49 } … … 44 54 } 45 55 46 private GenealogyGraph(GenealogyGraph original, Cloner cloner)56 private GenealogyGraph(GenealogyGraph<T> original, Cloner cloner) 47 57 : base(original, cloner) { 48 _dictionary = new Dictionary< object,Node>(original._dictionary);49 } 50 51 public bool HasNode( objectt) {58 _dictionary = new Dictionary<T, GenealogyGraphNode>(original._dictionary); 59 } 60 61 public bool HasNode(T t) { 52 62 return _dictionary.ContainsKey(t); 53 63 } 54 64 55 public Node GetNode(objectt) {56 return this.HasNode(t) ? _dictionary[t] : null;57 } 58 59 public IEnumerable< object> Keys {65 public GenealogyGraphNode GetNode(T t) { 66 return HasNode(t) ? _dictionary[t] : null; 67 } 68 69 public IEnumerable<T> Keys { 60 70 get { return _dictionary.Keys; } 61 71 } 62 72 63 public IEnumerable< Node> Values {73 public IEnumerable<GenealogyGraphNode> Values { 64 74 get { return _dictionary.Values; } 65 75 } 66 76 67 public bool Any(){68 return _dictionary.Any();69 } 70 71 public bool Any(Func<KeyValuePair< object,Node>, bool> predicate) {77 public bool IsEmpty { 78 get { return !_dictionary.Any(); } 79 } 80 81 public bool Any(Func<KeyValuePair<T, GenealogyGraphNode>, bool> predicate) { 72 82 return _dictionary.Any(predicate); 73 83 } … … 81 91 /// </summary> 82 92 /// <param name="t">The symbolic expression tree</param> 83 /// <param name="q">The quality value </param> 84 /// <param name="l">The node label</param> 93 /// <param name="quality">The quality value </param> 94 /// <param name="label">The node label</param> 95 /// <param name="rank">The node rank</param> 85 96 /// <param name="elite">Specifies if this node is an elite</param> 86 public void AddNode( object t, double q = 0.0, string l = "", double g = 0, bool elite = false) {97 public void AddNode(T t, double quality = 0.0, string label = "", double rank = 0, bool elite = false, int cutIndex = -1) { 87 98 if (HasNode(t)) return; 88 var color = new Color { R = (byte)(255 - 255 * q), G = (byte)(255 * q), B = 50 }; 89 _dictionary[t] = new Node { Data = t, Quality = q, Label = l, IsElite = elite, Rank = g, Color = color }; 99 _dictionary[t] = new GenealogyGraphNode { Data = t, Quality = quality, Label = label, IsElite = elite, Rank = rank, CutpointIndex = cutIndex }; 90 100 } 91 101 … … 93 103 /// more of a low level method to minimize memory usage when creating and returning subgraphs 94 104 /// </summary> 95 /// <param name="n"></param> 96 public void AddNode(Node n) { 97 var t = n.Data; 98 if (HasNode(t)) 99 return; 105 /// <param name="n">The node to be added</param> 106 public void AddNode(GenealogyGraphNode n) { 107 var t = (T)n.Data; 108 if (HasNode(t)) return; 100 109 _dictionary[t] = n; 101 110 } … … 105 114 /// </summary> 106 115 /// <param name="t">The graph node</param> 107 public void RemoveNode(object t) { 108 if (!_dictionary.ContainsKey(t)) 109 return; 110 Node n = _dictionary[t]; 116 public void RemoveNode(T t) { 117 if (!_dictionary.ContainsKey(t)) return; 118 GenealogyGraphNode n = _dictionary[t]; 111 119 if (n.InEdges != null) { 112 120 foreach (var e in n.InEdges.Where(e => e.Target.OutEdges != null)) { … … 138 146 /// <param name="b"></param> 139 147 /// <param name="label"></param> 140 public void AddArc( object a, object b, string label = "") {141 Node src, dest;148 public void AddArc(T a, T b, int opType = 0) { 149 GenealogyGraphNode src, dest; 142 150 if (!HasNode(a)) { 143 src = new Node { Data = a };151 src = new GenealogyGraphNode { Data = a }; 144 152 _dictionary[a] = src; 145 153 } else { … … 147 155 } 148 156 if (!HasNode(b)) { 149 dest = new Node { Data = b };157 dest = new GenealogyGraphNode { Data = b }; 150 158 _dictionary[b] = dest; 151 159 } else { … … 153 161 } 154 162 // add forward and reverse arcs 155 src.AddForwardArc(dest, label);156 dest.AddReverseArc(src, label);157 } 158 159 public void AddArcs( object[] a, object b, string label) {160 Node src, dest;163 src.AddForwardArc(dest, opType); 164 dest.AddReverseArc(src, opType); 165 } 166 167 public void AddArcs(T[] a, T b, int opType = 0) { 168 GenealogyGraphNode src, dest; 161 169 if (!HasNode(b)) { 162 dest = new Node { Data = b };170 dest = new GenealogyGraphNode { Data = b }; 163 171 _dictionary[b] = dest; 164 172 } else { … … 167 175 foreach (var o in a) { 168 176 if (!HasNode(o)) { 169 src = new Node { Data = o };177 src = new GenealogyGraphNode { Data = o }; 170 178 _dictionary[o] = src; 171 179 } else { 172 180 src = _dictionary[o]; 173 181 } 174 src.AddForwardArc(dest, label);175 dest.AddReverseArc(src, label);182 src.AddForwardArc(dest, opType); 183 dest.AddReverseArc(src, opType); 176 184 } 177 185 } 178 186 } 179 187 180 public class Node {188 public class GenealogyGraphNode : IComparable { 181 189 public string Id { get; private set; } 182 190 public string Label { get; set; } 183 191 public bool IsElite { get; set; } 184 public List<Arc> InEdges { get; set; }185 public List<Arc> OutEdges { get; set; }186 192 public object Data { get; set; } 187 193 public double Quality { get; set; } 188 194 public double Rank { get; set; } 189 public Color Color { get; set; } 190 191 public int Degree { 192 get { return (InEdges == null ? 0 : InEdges.Count) + (OutEdges == null ? 0 : OutEdges.Count); } 193 } 194 195 public Node() { 195 public int CutpointIndex { get; set; } 196 public List<GenealogyGraphArc> InEdges { get; set; } 197 public List<GenealogyGraphArc> OutEdges { get; set; } 198 199 public int Degree { get { return (InEdges == null ? 0 : InEdges.Count) + (OutEdges == null ? 0 : OutEdges.Count); } } 200 201 public GenealogyGraphNode() { Id = Guid.NewGuid().ToString(); } 202 203 public GenealogyGraphNode(GenealogyGraphNode node) { 196 204 Id = Guid.NewGuid().ToString(); 197 } 198 199 /// <summary> 200 /// Returns a genealogical graph rooted in the current node, containing all ancestry information 205 Rank = node.Rank; 206 Quality = node.Quality; 207 IsElite = node.IsElite; 208 Label = node.Label; 209 Data = node.Data; 210 InEdges = node.InEdges; 211 OutEdges = node.OutEdges; 212 CutpointIndex = node.CutpointIndex; 213 } 214 215 /// <summary> 216 /// Returns all the ancestors of the current node 201 217 /// </summary> 202 218 /// <returns></returns> 203 public GenealogyGraph Genealogy() { 204 var graph = new GenealogyGraph(); 205 graph.AddNode(this); 206 foreach (var node in this.Ancestors()) 207 graph.AddNode(node); 208 return graph; 209 } 210 211 /// <summary> 212 /// Returns an enumerable of all the ancestors of the current node 213 /// </summary> 214 /// <returns></returns> 215 public IEnumerable<Node> Ancestors() { 216 var nodes = new HashSet<Node> { this }; 219 public IEnumerable<GenealogyGraphNode> Ancestors() { 220 var nodes = new HashSet<GenealogyGraphNode> { this }; 217 221 int offset = 0; 218 222 int c0 = 1; … … 231 235 } 232 236 233 public void AddForwardArc(Node target, string label) { 234 var e = new Arc { Target = target, Label = label }; 235 if (OutEdges == null) 236 OutEdges = new List<Arc> { e }; 237 else 238 OutEdges.Add(e); 239 } 240 241 public void AddReverseArc(Node target, string label) { 242 var e = new Arc { Target = target, Label = label }; 243 if (InEdges == null) 244 InEdges = new List<Arc> { e }; 245 else 246 InEdges.Add(e); 237 /// <summary> 238 /// Returns all the descendants of the current node (identical to above method except for using the OutEdges) 239 /// </summary> 240 /// <returns></returns> 241 public IEnumerable<GenealogyGraphNode> Descendants() { 242 var nodes = new HashSet<GenealogyGraphNode> { this }; 243 int offset = 0; 244 int c0 = 1; 245 while (offset != c0) { 246 int c1 = c0; 247 for (int i = offset; i != c1; ++i) { 248 if (nodes.ElementAt(i).OutEdges == null) continue; 249 foreach (var p in nodes.ElementAt(i).OutEdges.Select(e => e.Target)) { 250 nodes.Add(p); 251 yield return p; 252 } 253 } 254 offset = c1; 255 c0 = nodes.Count; 256 } 257 } 258 259 public void AddForwardArc(GenealogyGraphNode target, int opType) { 260 var e = new GenealogyGraphArc { Target = target, OperatorType = opType }; 261 if (OutEdges == null) OutEdges = new List<GenealogyGraphArc> { e }; 262 else OutEdges.Add(e); 263 } 264 265 public void AddReverseArc(GenealogyGraphNode target, int opType) { 266 var e = new GenealogyGraphArc { Target = target, OperatorType = opType }; 267 if (InEdges == null) InEdges = new List<GenealogyGraphArc> { e }; 268 else InEdges.Add(e); 269 } 270 271 // comparable 272 // may seem weird, it is actually implemented so higher quality means "less than" in terms of ordering 273 // if quality is equal, the elite node takes precedence 274 public int CompareTo(object obj) { 275 if (obj == null) return 1; 276 var other = obj as GenealogyGraphNode; 277 if (other == null) return 1; 278 if (Quality.Equals(other.Quality)) { 279 if (IsElite) return -1; 280 return other.IsElite ? 1 : -1; 281 } 282 return other.Quality.CompareTo(Quality); 247 283 } 248 284 } … … 251 287 /// An arc is an edge along with an orientation 252 288 /// </summary> 253 public class Arc { 254 public Node Target { get; set; } 255 public string Label { get; set; } 256 public double Weight { get; set; } 257 // other attributes 258 } 259 // an edge can be represented as a tuple<Node, Node> TODO: figure it out (might be useful for easier querying) 260 261 public struct Color { 262 public byte R { get; set; } 263 public byte G { get; set; } 264 public byte B { get; set; } 289 public class GenealogyGraphArc { 290 public GenealogyGraphNode Target { get; set; } 291 // OperationType is an identifier for the genetic operation (mutation, crossover) that a graph arc will represent 292 // So basically it describes which operator was applied to an individual/graph node (the one emitting the arc), 293 // while Target represents the end result of that operator (node ==GeneticOperation==> Target) 294 public int OperatorType { get; set; } 295 // these two fields are not used, but they might be useful later 296 public string Label { get; set; } // might be useful later 297 public double Weight { get; set; } // might be useful later 265 298 } 266 299 }
Note: See TracChangeset
for help on using the changeset viewer.