Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/GenealogyGraph.cs @ 7479

Last change on this file since 7479 was 7479, checked in by bburlacu, 12 years ago

#1772: Implemented an initial set of features: individual ancestry, genealogy tracking via customized genetic operators and data structures.

File size: 7.1 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Drawing;
4using System.Linq;
5using HeuristicLab.Common;
6using HeuristicLab.Core;
7using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
8using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
9
10namespace HeuristicLab.EvolutionaryTracking {
11  public class GenealogyGraph : NamedItem {
12    private readonly Dictionary<ISymbolicExpressionTree, Node> _dictionary;
13    public GenealogyGraph() {
14      _dictionary = new Dictionary<ISymbolicExpressionTree, Node>();
15    }
16
17    public GenealogyGraph(GenealogyGraph g) {
18      _dictionary = new Dictionary<ISymbolicExpressionTree, Node>(g._dictionary);
19    }
20
21    [StorableConstructor]
22    private GenealogyGraph(bool serializing) : base(serializing) { }
23
24    private GenealogyGraph(GenealogyGraph original, Cloner cloner)
25      : base(original, cloner) {
26      _dictionary = new Dictionary<ISymbolicExpressionTree, Node>(original._dictionary);
27    }
28
29    public bool HasNode(ISymbolicExpressionTree t) {
30      return _dictionary.ContainsKey(t);
31    }
32
33    public Node GetNode(ISymbolicExpressionTree t) {
34      return this.HasNode(t) ? _dictionary[t] : null;
35    }
36
37    public IEnumerable<ISymbolicExpressionTree> Keys {
38      get { return _dictionary.Keys; }
39    }
40
41    public IEnumerable<Node> Values {
42      get { return _dictionary.Values; }
43    }
44
45    public bool Any() {
46      return _dictionary.Any();
47    }
48
49    public bool Any(Func<KeyValuePair<ISymbolicExpressionTree, Node>, bool> predicate) {
50      return _dictionary.Any(predicate);
51    }
52
53    public void Clear() {
54      _dictionary.Clear();
55    }
56
57    /// <summary>
58    /// Adds a node representing an individual
59    /// </summary>
60    /// <param name="t">The symbolic expression tree</param>
61    public void AddNode(ISymbolicExpressionTree t, double q = 0.0, string l = "", bool elite = false) {
62      if (HasNode(t)) return;
63      _dictionary[t] = new Node { Data = t, Quality = q, Label = l, IsElite = elite };
64    }
65
66    /// <summary>
67    ///  more of a low level method to minimize memory usage when creating and returning subgraphs
68    /// </summary>
69    /// <param name="n"></param>
70    public void AddNode(Node n) {
71      var t = (ISymbolicExpressionTree)n.Data;
72      if (HasNode(t))
73        return;
74      _dictionary[t] = n;
75    }
76
77    /// <summary>
78    /// Remove a node from the graph along with edges associated with it
79    /// </summary>
80    /// <param name="t">The graph node</param>
81    public void RemoveNode(ISymbolicExpressionTree t) {
82      if (!_dictionary.ContainsKey(t))
83        return;
84      Node n = _dictionary[t];
85      if (n.InEdges != null) {
86        foreach (var e in n.InEdges.Where(e => e.Target.OutEdges != null)) {
87          e.Target.OutEdges.RemoveAll(arc => arc.Target == n);
88          if (!e.Target.OutEdges.Any())
89            e.Target.OutEdges = null; // set to null to be a little more memory efficient
90        }
91        n.InEdges = null;
92      }
93      if (n.OutEdges != null) {
94        foreach (var e in n.OutEdges.Where(e => e.Target.InEdges != null)) {
95          e.Target.InEdges.RemoveAll(arc => arc.Target == n);
96          if (!e.Target.OutEdges.Any())
97            e.Target.InEdges = null; // set to null to be a little more memory efficient
98        }
99        n.OutEdges = null;
100      }
101      _dictionary.Remove(t);
102    }
103
104    public double AverageDegree {
105      get { return Values.Average(x => x.Degree); }
106    }
107
108    /// <summary>
109    /// Adds a graph arc from a to b
110    /// </summary>
111    /// <param name="a"></param>
112    /// <param name="b"></param>
113    /// <param name="label"></param>
114    public void AddArc(ISymbolicExpressionTree a, ISymbolicExpressionTree b, string label) {
115      Node src, dest;
116      if (!HasNode(a)) {
117        src = new Node { Data = a };
118        _dictionary[a] = src;
119      } else {
120        src = _dictionary[a];
121      }
122      if (!HasNode(b)) {
123        dest = new Node { Data = b };
124        _dictionary[b] = dest;
125      } else {
126        dest = _dictionary[b];
127      }
128      // add forward and reverse arcs
129      src.AddForwardArc(dest, label);
130      dest.AddReverseArc(src, label);
131    }
132
133    public override IDeepCloneable Clone(Cloner cloner) {
134      return new GenealogyGraph(this, cloner);
135    }
136
137    public override string ItemName {
138      get { return "GenealogyGraph"; }
139    }
140
141    public override string ItemDescription {
142      get { return "A graph describing the genealogies of all the individuals"; }
143    }
144
145    public new Version ItemVersion {
146      get { return new Version(3, 3, 6); }
147    }
148
149    public new Image ItemImage {
150      get { return Common.Resources.VSImageLibrary.Graph; }
151    }
152  }
153
154  public class Node {
155    public string Id { get; private set; }
156    public string Label { get; set; }
157    public bool IsElite { get; set; }
158    public List<Arc> InEdges { get; set; }
159    public List<Arc> OutEdges { get; set; }
160    public object Data { get; set; }
161    public double Quality { get; set; }
162
163    public int Degree {
164      get { return (InEdges == null ? 0 : InEdges.Count) + (OutEdges == null ? 0 : OutEdges.Count); }
165    }
166
167    public Node() {
168      Id = Guid.NewGuid().ToString();
169    }
170
171    /// <summary>
172    /// Returns a genealogical graph rooted in the current node, containing all ancestry information
173    /// </summary>
174    /// <returns></returns>
175    public GenealogyGraph Genealogy() {
176      var graph = new GenealogyGraph();
177      graph.AddNode(this);
178      foreach (var node in this.Ancestors())
179        graph.AddNode(node);
180      return graph;
181    }
182
183    /// <summary>
184    /// Returns an enumerable of all the ancestors of the current node
185    /// </summary>
186    /// <returns></returns>
187    public IEnumerable<Node> Ancestors() {
188      var nodes = new HashSet<Node> { this };
189      int offset = 0;
190      int c0 = 1;
191      while (offset != c0) {
192        int c1 = c0;
193        for (int i = offset; i != c1; ++i) {
194          if (nodes.ElementAt(i).InEdges == null) continue;
195          foreach (var p in nodes.ElementAt(i).InEdges.Select(e => e.Target)) {
196            nodes.Add(p);
197            yield return p;
198          }
199        }
200        offset = c1;
201        c0 = nodes.Count;
202      }
203    }
204
205    public void AddForwardArc(Node target, string label) {
206      var e = new Arc { Target = target, Label = label };
207      if (OutEdges == null)
208        OutEdges = new List<Arc> { e };
209      else
210        OutEdges.Add(e);
211    }
212
213    public void AddReverseArc(Node target, string label) {
214      var e = new Arc { Target = target, Label = label };
215      if (InEdges == null)
216        InEdges = new List<Arc> { e };
217      else
218        InEdges.Add(e);
219    }
220  }
221
222  /// <summary>
223  /// An arc is an edge along with an orientation
224  /// </summary>
225  public class Arc {
226    public Node Target { get; set; }
227    public string Label { get; set; }
228    public double Weight { get; set; }
229    // other attributes
230  }
231
232  // an edge can be represented as a tuple<Node, Node> TODO: figure it out (might be useful for easier querying)
233}
Note: See TracBrowser for help on using the repository browser.