Free cookie consent management tool by TermsFeed Policy Generator

source: branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.EvolutionTracking/3.4/GenealogyGraph/GenealogyGraph.cs @ 18242

Last change on this file since 18242 was 17434, checked in by bburlacu, 5 years ago

#1772: Merge trunk changes and fix all errors and compilation warnings.

File size: 8.7 KB
RevLine 
[10278]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 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
[10267]22using System;
23using System.Collections.Generic;
[11459]24using System.Drawing;
25using System.IO;
[10300]26using System.Linq;
[11459]27using System.Text;
[17434]28using HEAL.Attic;
[10267]29using HeuristicLab.Common;
30using HeuristicLab.Core;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32
[17434]33namespace HeuristicLab.EvolutionTracking
34{
[10888]35  [Item("GenealogyGraph", "A class representing a genealogy graph")]
[17434]36  [StorableType("66DCA305-87F7-41D8-91CF-68415B1809A8")]
37  public class GenealogyGraph : DirectedGraph, IGenealogyGraph
38  {
[11459]39    private Dictionary<object, IGenealogyGraphNode> contentMap;
40    private Dictionary<string, IGenealogyGraphNode> idMap;
[11318]41
[11925]42    private readonly Comparison<IArc<IDeepCloneable>> compareArcs = (a, b) => {
[11969]43      var da = a.Data;
44      var db = b.Data;
45
46      if ((da == null && db == null) || (da != null && db != null))
[11752]47        return 0;
[11969]48
49      if (da == null)
[11752]50        return -1;
[11969]51
[11752]52      return 1;
53    };
54
55    protected Dictionary<double, List<IGenealogyGraphNode>> ranks;
56    public IEnumerable<KeyValuePair<double, IEnumerable<IGenealogyGraphNode>>> Ranks {
57      get { return ranks.Select(x => new KeyValuePair<double, IEnumerable<IGenealogyGraphNode>>(x.Key, x.Value)); }
[10267]58    }
[11752]59    public IEnumerable<IGenealogyGraphNode> GetByRank(double rank) {
60      return ranks.ContainsKey(rank) ? ranks[rank] : Enumerable.Empty<IGenealogyGraphNode>();
61    }
[10300]62    protected GenealogyGraph(GenealogyGraph original, Cloner cloner)
63      : base(original, cloner) {
[11502]64      RebuildDictionaries();
[11969]65      // sort arcs so that in the case of crossover (child vertex with two parents)
66      // the arc which holds the fragment information is always last
67      foreach (var arcList in base.Vertices.Select(v => (List<IArc>)v.InArcs)) {
68        arcList.Sort((a, b) => compareArcs((IGenealogyGraphArc)a, (IGenealogyGraphArc)b));
69      }
[10300]70    }
[10267]71    public override IDeepCloneable Clone(Cloner cloner) {
[10300]72      return new GenealogyGraph(this, cloner);
[10267]73    }
[11233]74
[10267]75    [StorableConstructor]
[17434]76    protected GenealogyGraph(StorableConstructorFlag _) : base(_) { }
[11459]77    [StorableHook(HookType.AfterDeserialization)]
78    private void AfterDeserialization() {
[11502]79      RebuildDictionaries();
[11969]80      foreach (var arcList in base.Vertices.Select(v => (List<IArc>)v.InArcs)) {
81        arcList.Sort((a, b) => compareArcs((IGenealogyGraphArc)a, (IGenealogyGraphArc)b));
82      }
[11459]83    }
[10267]84    public GenealogyGraph() {
[11752]85      ranks = new Dictionary<double, List<IGenealogyGraphNode>>();
[11233]86      contentMap = new Dictionary<object, IGenealogyGraphNode>();
87      idMap = new Dictionary<string, IGenealogyGraphNode>();
[10267]88    }
[11390]89    new public IEnumerable<IGenealogyGraphNode> Vertices {
90      get { return base.Vertices.Select(x => (IGenealogyGraphNode)x); }
[11233]91    }
[11475]92    new public IEnumerable<IGenealogyGraphArc> Arcs {
93      get { return base.Arcs.Select(x => (IGenealogyGraphArc)x); }
94    }
[10888]95    public override IArc AddArc(IVertex source, IVertex target) {
96      var arc = new GenealogyGraphArc((IGenealogyGraphNode)source, (IGenealogyGraphNode)target);
[11253]97      base.AddArc(arc);
[10888]98      return arc;
99    }
[10300]100    public override void AddVertex(IVertex vertex) {
[10888]101      base.AddVertex(vertex);
[11390]102      var genealogyGraphNode = (IGenealogyGraphNode)vertex;
[12966]103
[11390]104      if (contentMap.ContainsKey(genealogyGraphNode.Data))
[11233]105        throw new InvalidOperationException("Duplicate content is not allowed in the genealogy graph.");
[11390]106      contentMap[genealogyGraphNode.Data] = genealogyGraphNode;
[12966]107
[11390]108      if (idMap.ContainsKey(genealogyGraphNode.Id))
[11318]109        throw new InvalidOperationException("Duplicate ids are not allowed in the genealogy graph.");
[11390]110      idMap[genealogyGraphNode.Id] = genealogyGraphNode;
[12966]111
[11694]112      if (!ranks.ContainsKey(genealogyGraphNode.Rank))
113        ranks[genealogyGraphNode.Rank] = new List<IGenealogyGraphNode>();
114      ranks[genealogyGraphNode.Rank].Add(genealogyGraphNode);
[10278]115    }
[10300]116    public override void RemoveVertex(IVertex vertex) {
[10302]117      var node = (IGenealogyGraphNode)vertex;
[11253]118      contentMap.Remove(node.Data);
[11233]119      idMap.Remove(node.Id);
[11752]120      if (ranks.ContainsKey(node.Rank)) {
121        ranks[node.Rank].Remove(node); // this call will be slow, use with caution
122        if (!ranks[node.Rank].Any())
123          ranks.Remove(node.Rank);
[10278]124      }
125      base.RemoveVertex(vertex);
126    }
[12958]127
128    public override void RemoveVertices(IEnumerable<IVertex> vertices) {
129      foreach (var v in vertices)
130        this.RemoveVertex(v);
131    }
132
[11233]133    public IGenealogyGraphNode GetByContent(object content) {
134      IGenealogyGraphNode result;
135      contentMap.TryGetValue(content, out result);
136      return result;
137    }
138    public IGenealogyGraphNode GetById(string id) {
139      IGenealogyGraphNode result;
140      idMap.TryGetValue(id, out result);
141      return result;
142    }
143    public bool Contains(object content) {
144      return contentMap.ContainsKey(content);
145    }
[10278]146    public event EventHandler GraphUpdated;
147    private void OnGraphUpdated(object sender, EventArgs args) {
148      var updated = GraphUpdated;
149      if (updated != null) updated(sender, args);
150    }
[10677]151    public override void Clear() {
152      base.Clear();
153      ranks.Clear();
[11475]154      contentMap.Clear();
155      idMap.Clear();
[10677]156    }
[11502]157    private void RebuildDictionaries() {
158      contentMap = new Dictionary<object, IGenealogyGraphNode>();
159      idMap = new Dictionary<string, IGenealogyGraphNode>();
160      ranks = new Dictionary<double, List<IGenealogyGraphNode>>();
161
162      foreach (var v in Vertices) {
163        contentMap[v.Data] = v;
164        idMap[v.Id] = v;
165        if (ranks.ContainsKey(v.Rank)) {
166          ranks[v.Rank].Add(v);
167        } else {
168          ranks[v.Rank] = new List<IGenealogyGraphNode> { v };
169        }
170      }
171    }
[11459]172    public void ExportDot(string path) {
173      var sb = new StringBuilder();
174      sb.AppendLine("graph fragmentgraph {");
175      foreach (var v in Vertices) {
[11852]176        double width = Math.Max(0.5, v.Degree);
177        sb.AppendLine("\"" + v.Id + "\"[shape=circle, style = filled, width = " + width + ", label = " + v.Rank + "\n" + String.Format("{0:00}", v.Quality) + ", fillcolor = \"" + ColorTranslator.ToHtml(GetColor(v)) + "\"]");
[11459]178      }
[11502]179      foreach (var a in Arcs) {
[11459]180        sb.AppendLine("\"" + a.Source.Id + "\" -- \"" + a.Target.Id + "\"");
181      }
182
183      sb.AppendLine("}");
184      File.WriteAllText(path, sb.ToString());
185    }
186    private Color GetColor(IGenealogyGraphNode node) {
187      var colorIndex = (int)Math.Round(node.Quality * ColorGradient.Colors.Count);
188      if (colorIndex >= ColorGradient.Colors.Count) return ColorGradient.Colors.Last();
189      return ColorGradient.Colors[colorIndex];
190    }
[10267]191  }
[10300]192
[11459]193  [Item("GenealogyGraph", "A genealogy graph in which the vertex data is of type T")]
[17434]194  [StorableType("3F5043F7-2538-4B76-BA12-062A4CEF5A1A")]
195  public class GenealogyGraph<T> : GenealogyGraph, IGenealogyGraph<T> where T : class, IItem
196  {
[11639]197    public GenealogyGraph() { }
198    private GenealogyGraph(GenealogyGraph original, Cloner cloner)
199      : base(original, cloner) {
200    }
201    public override IDeepCloneable Clone(Cloner cloner) {
202      return new GenealogyGraph<T>(this, cloner);
203    }
[11390]204    new public IEnumerable<IGenealogyGraphNode<T>> Vertices {
205      get { return base.Vertices.Select(x => (IGenealogyGraphNode<T>)x); }
[10677]206    }
[11390]207    new public IGenealogyGraphNode<T> GetByContent(object content) {
[11386]208      return (IGenealogyGraphNode<T>)base.GetByContent(content);
209    }
[11390]210    new public IGenealogyGraphNode<T> GetById(string id) {
[11386]211      return (IGenealogyGraphNode<T>)base.GetById(id);
212    }
[11752]213    new public IEnumerable<IGenealogyGraphNode<T>> GetByRank(double rank) {
214      return base.GetByRank(rank).Select(x => (IGenealogyGraphNode<T>)x);
215    }
216    public new IEnumerable<KeyValuePair<double, IEnumerable<IGenealogyGraphNode<T>>>> Ranks {
217      get { return base.Ranks.Select(x => new KeyValuePair<double, IEnumerable<IGenealogyGraphNode<T>>>(x.Key, x.Value.Select(n => (IGenealogyGraphNode<T>)n))); }
218    }
[10347]219  }
[10267]220}
Note: See TracBrowser for help on using the repository browser.