Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/29/14 16:20:08 (10 years ago)
Author:
bburlacu
Message:

#2215: Refactored and simplified DirectedGraph and related components API, simplified the BottomUpSimilarityCalculator by not using a directed graph and vertices but a simpler object so that the similarity calculator is self-contained.

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  
    2020#endregion
    2121
     22using System;
    2223using HeuristicLab.Common;
    2324using HeuristicLab.Core;
     
    2627namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    2728  /// <summary>
    28   /// An arc that can have a weight, a label, and can old additional information in the Data object
     29  /// An arc that can have a weight, a label, and a data object for holding additional info
    2930  /// </summary>
    3031  [StorableClass]
    3132  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    }
    3439
    3540    [Storable]
    36     public IVertex Target { get; set; }
     41    public IVertex Source { get; private set; }
    3742
    3843    [Storable]
    39     public string Label { get; set; }
     44    public IVertex Target { get; private set; }
    4045
    4146    [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    }
    4355
    4456    [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    }
    4675
    4776    [StorableConstructor]
    4877    public Arc(bool deserializing) : base(deserializing) { }
    49 
    50     public override IDeepCloneable Clone(Cloner cloner) {
    51       return new Arc(this, cloner);
    52     }
    53     public Arc() { }
    5478
    5579    public Arc(IVertex source, IVertex target) {
     
    6084    protected Arc(Arc original, Cloner cloner)
    6185      : 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; }
    67117    }
    68118  }
  • branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph/DirectedGraph.cs

    r11211 r11229  
    2424using System.Drawing;
    2525using System.Linq;
    26 using System.Text;
    2726using HeuristicLab.Common;
    2827using HeuristicLab.Core;
     
    3332  [StorableClass]
    3433  public class DirectedGraph : Item, IDirectedGraph {
    35     public bool AllowDuplicateContent { get; set; }
    36 
     34    protected HashSet<IVertex> vertices;
    3735    [Storable]
    38     protected readonly List<IVertex> vertices; // for performance reasons, maybe this should be a linked list (fast remove)
    3936    public IEnumerable<IVertex> Vertices {
    4037      get { return vertices; }
     38      private set { vertices = new HashSet<IVertex>(value); }
    4139    }
    4240
     41    protected HashSet<IArc> arcs;
    4342    [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;
    5143    public IEnumerable<IArc> Arcs {
    5244      get { return arcs; }
     45      private set { arcs = new HashSet<IArc>(value); }
    5346    }
    5447
     
    6053    [StorableHook(HookType.AfterDeserialization)]
    6154    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;
    6559      }
    6660
    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;
    7067      }
    7168    }
    7269
    7370    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>();
    7873    }
    7974
    8075    protected DirectedGraph(DirectedGraph original, Cloner cloner)
    8176      : 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));
    8679    }
    8780
     
    9083    }
    9184
    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 
    12085    public virtual void Clear() {
    12186      vertices.Clear();
    122       contentMap.Clear();
    123       idMap.Clear();
     87      arcs.Clear();
    12488    }
    12589
    12690    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);
    13491      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);
    13897    }
    13998
    14099    public virtual void RemoveVertex(IVertex vertex) {
    141       contentMap.Remove(vertex.Content);
    142       idMap.Remove(vertex.Id);
    143100      vertices.Remove(vertex);
    144 
    145101      // 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);
    155109    }
    156110
    157     public virtual IArc AddArc(IVertex source, IVertex target) {
     111    public IArc AddArc(IVertex source, IVertex target) {
    158112      var arc = new Arc(source, target);
    159       source.AddForwardArc(arc);
    160       target.AddReverseArc(arc);
    161       arcs.Add(arc);
     113      AddArc(arc);
    162114      return arc;
    163115    }
    164116
    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);
    170123    }
    171124
    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);
    176131    }
     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) { }
    177172
    178173    public override Image ItemImage {
    179174      get { return Common.Resources.VSImageLibrary.Graph; }
    180175    }
    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     }
    197176  }
    198177}
  • branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph/Interfaces/IArc.cs

    r11211 r11229  
    2020#endregion
    2121
     22using System;
     23using HeuristicLab.Core;
    2224
    2325namespace 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; }
    2730    string Label { get; set; }
    2831    double Weight { get; set; }
     
    3033  }
    3134
    32   public interface IArc<T> : IArc where T : class,IVertex {
    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; }
    3538  }
    3639}
  • branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph/Interfaces/IDirectedGraph.cs

    r11211 r11229  
    2020#endregion
    2121
    22 using System;
    2322using System.Collections.Generic;
    2423using HeuristicLab.Core;
     
    2625namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    2726  public interface IDirectedGraph : IItem {
    28     bool Contains(IVertex vertex);
    29     bool Any(Func<IVertex, bool> predicate);
    3027    void Clear();
    3128    void AddVertex(IVertex vertex);
    3229    IArc AddArc(IVertex source, IVertex target);
     30    void AddArc(IArc arc);
    3331    void RemoveVertex(IVertex vertex);
     32    void RemoveArc(IArc arc);
    3433    IEnumerable<IVertex> Vertices { get; }
    35     bool Contains(object content);
    36     IVertex GetVertex(string id);
    37     IVertex GetVertex(object content);
     34    IEnumerable<IArc> Arcs { get; }
    3835  }
    3936}
  • branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph/Interfaces/IVertex.cs

    r11211 r11229  
    2222using System;
    2323using System.Collections.Generic;
     24using HeuristicLab.Common;
    2425using HeuristicLab.Core;
    2526
    2627namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    2728  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;
    3032
    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; }
    3435
    3536    int InDegree { get; }
     
    4041    double Weight { get; set; }
    4142
    42     void AddForwardArc(IArc arc);
    43     void AddReverseArc(IArc arc);
     43    object Content { get; set; }
    4444
    45     object Content { get; set; }
     45    void AddArc(IArc arc);
     46    void RemoveArc(IArc arc);
     47    void RemoveArc(IVertex vertex);
    4648  }
    4749
  • branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/DirectedGraph/Vertex.cs

    r11211 r11229  
    3030  [StorableClass]
    3131  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)
    3637        changed(sender, args);
    37       }
    3838    }
    3939
    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);
    4561      }
    4662    }
    4763
    4864    [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      }
    5372    }
    54 
    55     [Storable]
    56     public string Label { get; set; }
    57 
    58     [Storable]
    59     public double Weight { get; set; }
    6073
    6174    [Storable]
     
    6477      get { return content; }
    6578      set {
    66         OnPreContentChanged(this, EventArgs.Empty);
    6779        content = value;
    68         OnPostContentChanged(this, EventArgs.Empty);
     80        OnChanged(this, EventArgs.Empty);
    6981      }
    7082    }
     
    7385    public IEnumerable<IArc> InArcs {
    7486      get { return inArcs ?? Enumerable.Empty<IArc>(); }
    75       set { inArcs = value.ToList(); }
    7687    }
    7788
     
    7990    public IEnumerable<IArc> OutArcs {
    8091      get { return outArcs ?? Enumerable.Empty<IArc>(); }
    81       set { outArcs = value.ToList(); }
    8292    }
    8393
     
    8595    public Vertex(bool deserializing) : base(deserializing) { }
    8696
    87     public Vertex() {
    88       id = Guid.NewGuid().ToString();
    89     }
     97    [StorableHook(HookType.AfterDeserialization)]
     98    private void AfterDeserialization() { }
     99
     100    private Vertex() { }
    90101
    91102    public Vertex(object content)
     
    96107    protected Vertex(Vertex original, Cloner cloner)
    97108      : base(original, cloner) {
    98       id = Guid.NewGuid().ToString();
    99109      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();
    104115    }
    105116
     
    108119    }
    109120
    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");
    114148      }
    115149    }
    116150
    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));
    125163    }
    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
    132165    public int InDegree { get { return InArcs.Count(); } }
    133166    public int OutDegree { get { return OutArcs.Count(); } }
     
    141174      set { base.Content = value; }
    142175    }
    143 
    144     public Vertex() { }
    145176
    146177    [StorableConstructor]
Note: See TracChangeset for help on using the changeset viewer.