Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/GenericGraph/Vertex.cs @ 9419

Last change on this file since 9419 was 9419, checked in by bburlacu, 11 years ago

#1772: Refactoring of directed graph components, added code for correctly serializing vertices and edges. Added specific building blocks analyzers and new population diversity analyzer which correctly integrates with the parallel engine.

File size: 6.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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
22using System;
23using System.Collections.Generic;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
27
28namespace HeuristicLab.EvolutionaryTracking {
29  [StorableClass]
30  public class Vertex : Item, IVertex
31  {
32    [Storable]
33    private string id;
34    public string Id { get { return id; } }
35    [Storable] private string label;
36    public string Label { get { return label; } set { label = value; } }
37    [Storable] private double weight;
38    public double Weight { get { return weight; } set { weight = value; } }
39    [Storable] private List<IEdge> inEdges;
40    public List<IEdge> InEdges { get { return inEdges; } private set { inEdges = value; } }
41    [Storable] private List<IEdge> outEdges;
42    public List<IEdge> OutEdges { get { return outEdges; }private set { outEdges = value; }}
43    [Storable] private object content;
44    public object Content {
45      get { return content; }
46      set {
47        if (value == null)
48          throw new ArgumentException("Node content cannot be null.");
49        content = value;
50      }
51    }
52
53    [StorableConstructor]
54    public Vertex(bool deserializing) : base(deserializing) { }
55
56    public Vertex() {
57      id = Guid.NewGuid().ToString();
58    }
59
60    [StorableHook(HookType.AfterDeserialization)]
61    private void AfterDeserialization()
62    {
63      if (id == null) {
64        id = Guid.NewGuid().ToString();
65      }
66    }
67
68    protected Vertex(Vertex original, Cloner cloner)
69      : base(original, cloner) {
70      Content = original.Content;
71      id = Guid.NewGuid().ToString();
72      Label = original.Label;
73      Content = original.Content;
74      InEdges = new List<IEdge>(original.InEdges);
75      OutEdges = new List<IEdge>(original.OutEdges);
76    }
77
78    public override IDeepCloneable Clone(Cloner cloner) {
79      return new Vertex(this, cloner);
80    }
81
82    public Vertex(Vertex node) {
83      id = Guid.NewGuid().ToString();
84      Label = node.Label;
85      Content = node.Content;
86      InEdges = new List<IEdge>(node.InEdges);
87      OutEdges = new List<IEdge>(node.OutEdges);
88    }
89
90    public int InDegree { get { return InEdges == null ? 0 : InEdges.Count; } }
91    public int OutDegree { get { return OutEdges == null ? 0 : OutEdges.Count; } }
92    public int Degree { get { return InDegree + OutDegree; } }
93
94    /// <summary>
95    /// Performs an upward-breath-traversal of the graph using the nodes InEdges
96    /// </summary>
97    /// <returns>All the ancestors of the current node</returns>
98    public IEnumerable<IVertex> Ancestors() {
99      // for performance, we use a hashset for lookup and a list for iteration
100      var nodes = new HashSet<IVertex> { this };
101      var list = new List<IVertex> { this };
102      int i = 0;
103      while (i != list.Count) {
104        if (list[i].InEdges != null) {
105          foreach (var e in list[i].InEdges) {
106            if (nodes.Contains(e.Source)) continue;
107            nodes.Add(e.Source);
108            list.Add(e.Source);
109          }
110        }
111        ++i;
112      }
113      return list;
114    }
115
116    /// <summary>
117    /// Performs a downward-breath-traversal of the genealogy graph using the nodes OutEdges
118    /// </summary>
119    /// <returns>All the descendants of the current node</returns>
120    public IEnumerable<IVertex> Descendants() {
121      var nodes = new HashSet<IVertex> { this };
122      var list = new List<IVertex> { this };
123      int i = 0;
124      while (i != list.Count) {
125        if (list[i].OutEdges != null) {
126          foreach (var e in list[i].OutEdges) {
127            if (nodes.Contains(e.Target)) continue;
128            nodes.Add(e.Target);
129            list.Add(e.Target);
130          }
131        }
132        ++i;
133      }
134      return list;
135    }
136    // this method can be used to add arcs towards targets that are not visible in the graph
137    // (they do not appear in the nodes Dictionary). It is the programmers responsibility to
138    // enforce the correct and desired behavior.
139    public void AddForwardArc(IVertex target, double weight = 0.0, object data = null) {
140      var e = new Arc { Source = this, Target = target, Data = data, Weight = weight };
141      if (OutEdges == null) OutEdges = new List<IEdge> { e };
142      else OutEdges.Add(e);
143    }
144    public void AddForwardArc(IEdge arc) {
145      if (arc.Source == null) { arc.Source = this; }
146      if (arc.Source != this) { throw new Exception("AddForwardArc: Source should be equal to this."); }
147      if (OutEdges == null) { OutEdges = new List<IEdge> { arc }; } else { OutEdges.Add(arc); }
148    }
149    public void AddReverseArc(IEdge arc) {
150      if (arc.Target == null) { arc.Target = this; }
151      if (arc.Target != this) { throw new Exception("AddReverseArc: Target should be equal to this."); };
152      if (InEdges == null) { InEdges = new List<IEdge> { arc }; } else { InEdges.Add(arc); }
153    }
154    public void AddReverseArc(IVertex source, double weight = 0.0, object data = null) {
155      var e = new Arc { Source = source, Target = this, Data = data, Weight = weight };
156      if (InEdges == null) InEdges = new List<IEdge> { e };
157      else InEdges.Add(e);
158    }
159  }
160}
Note: See TracBrowser for help on using the repository browser.