using System;
using System.Text;
using System.Collections.Generic;
namespace Eppstein
{
///
/// Contains a simple vertex with label
///
public class Vertex
{
///
/// Vertex label
///
private string Label;
///
/// Reference for a user object, for future use
///
public object Object = null;
#region Calculated fields
///
/// Points to edge in shortest path tree
///
public Edge EdgeToPath = null;
///
/// Distance to endpoint in shortest path calculation
///
public int Distance = int.MinValue;
///
/// Collection of out edges not part of shortest path
///
public List RelatedEdges = new List();
#endregion
#region Properties
///
/// Next vertex in shortest path
///
public Vertex Next
{
get { return EdgeToPath == null ? null : EdgeToPath.Head; }
}
#endregion
///
/// Public constructor
///
/// Label of new vertex
public Vertex(string _label)
{
Label = _label;
}
#region Overrided functions of Object class
///
/// Converts this object into a string where required
///
/// Vertex label
public override string ToString()
{
return Label;
}
///
/// Allows to compare a vertex with another one by label, or with a string containin label
///
/// Second object to compare with
/// True if considered to be equal, false if not
public override bool Equals(object _obj)
{
if (_obj == null)
return false;
if (_obj.GetType() == typeof(Vertex))
return (string.Compare(this.Label, ((Vertex)_obj).Label, StringComparison.InvariantCultureIgnoreCase) == 0);
if (_obj.GetType() == typeof(string))
return (string.Compare(this.Label, (string)_obj, StringComparison.InvariantCultureIgnoreCase) == 0);
return false;
}
///
/// Returns a hash for this object, it uses label's hash
///
/// Hash calculated for this object
public override int GetHashCode()
{
return Label.GetHashCode();
}
#endregion
}
///
/// Contains a directional edge
///
public class Edge
{
///
/// Index of tail vertex
///
public readonly Vertex Tail;
///
/// Index of head vertex
///
public readonly Vertex Head;
///
/// Weight of edge
///
public int Weight;
///
/// Group label of edge
///
public readonly string Group;
#region Properties
///
/// Returns the sidetrack delta (deviation from shortest path)
/// Only is valid when shortest path tree has been calculated
///
public int Delta
{
get { return this.Weight + this.Head.Distance - this.Tail.Distance; }
}
#endregion
///
/// Constructor, generates a valid Edge
///
/// Vertex object of tail endpoint
/// Vertex object of head endpoint
/// Weight of edge
/// Label of group where edge belongs to
/// Edge is directional, goes from tail to head
public Edge(Vertex _tail, Vertex _head, int _weight, string _group)
{
Tail = _tail;
Head = _head;
Weight = _weight;
Group = _group;
}
///
/// Tells if the edge is a possible sidetrack of specified vertex
///
/// Vertex to evaluate
/// True if edge is sidetrack of vertex, false if not
public bool IsSidetrackOf(Vertex _v)
{
return (this.Tail == _v && this != _v.EdgeToPath && this.Weight >= 0);
}
///
/// Converts this object into a string where required
///
/// Tail and head labels, and weight inside parenthesis
public override string ToString()
{
return string.Concat(this.Tail, "--" + this.Weight + "-->", this.Head);
}
}
///
/// Contains a path composed by a edges collection
///
public class Path : List
{
#region Properties
///
/// Returns false if path is empty, true if not
///
public bool IsValid
{
get { return (this.Count > 0); }
}
///
/// Returns string with comma-separated list containing all vertices in a path
///
public string VertexNames
{
get
{
if (!IsValid)
return "(empty)";
StringBuilder builder = new StringBuilder(this[0].Tail.ToString());
foreach (Edge e in this)
{
builder.Append("," + e.Head);
}
return builder.ToString();
}
}
///
/// Returns sum of all weights of edges in the path
///
public int Weight
{
get
{
int total = 0;
foreach (Edge e in this)
total += e.Weight;
return total;
}
}
///
/// Returns sum of all deltas of edges in the path
///
public int DeltaWeight
{
get
{
int total = 0;
foreach (Edge e in this)
total += e.Delta;
return total;
}
}
#endregion
///
/// Returns path's decriptive string
///
/// List of delta for path
public override string ToString()
{
if (!IsValid)
return "(empty)";
StringBuilder builder = new StringBuilder();
foreach (Edge _e in this)
{
builder.Append(_e.Delta);
builder.Append(',');
}
if (builder.Length > 0)
builder.Remove(builder.Length - 1, 1);
return builder.ToString();
}
}
}