GraphElements.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. using System;
  2. using System.Text;
  3. using System.Collections.Generic;
  4. namespace Eppstein
  5. {
  6. /// <summary>
  7. /// Contains a simple vertex with label
  8. /// </summary>
  9. public class Vertex
  10. {
  11. /// <summary>
  12. /// Vertex label
  13. /// </summary>
  14. private string Label;
  15. /// <summary>
  16. /// Reference for a user object, for future use
  17. /// </summary>
  18. public object Object = null;
  19. #region Calculated fields
  20. /// <summary>
  21. /// Points to edge in shortest path tree
  22. /// </summary>
  23. public Edge EdgeToPath = null;
  24. /// <summary>
  25. /// Distance to endpoint in shortest path calculation
  26. /// </summary>
  27. public int Distance = int.MinValue;
  28. /// <summary>
  29. /// Collection of out edges not part of shortest path
  30. /// </summary>
  31. public List<Edge> RelatedEdges = new List<Edge>();
  32. #endregion
  33. #region Properties
  34. /// <summary>
  35. /// Next vertex in shortest path
  36. /// </summary>
  37. public Vertex Next
  38. {
  39. get { return EdgeToPath == null ? null : EdgeToPath.Head; }
  40. }
  41. #endregion
  42. /// <summary>
  43. /// Public constructor
  44. /// </summary>
  45. /// <param name="_label">Label of new vertex</param>
  46. public Vertex(string _label)
  47. {
  48. Label = _label;
  49. }
  50. #region Overrided functions of Object class
  51. /// <summary>
  52. /// Converts this object into a string where required
  53. /// </summary>
  54. /// <returns>Vertex label</returns>
  55. public override string ToString()
  56. {
  57. return Label;
  58. }
  59. /// <summary>
  60. /// Allows to compare a vertex with another one by label, or with a string containin label
  61. /// </summary>
  62. /// <param name="_obj">Second object to compare with</param>
  63. /// <returns>True if considered to be equal, false if not</returns>
  64. public override bool Equals(object _obj)
  65. {
  66. if (_obj == null)
  67. return false;
  68. if (_obj.GetType() == typeof(Vertex))
  69. return (string.Compare(this.Label, ((Vertex)_obj).Label, StringComparison.InvariantCultureIgnoreCase) == 0);
  70. if (_obj.GetType() == typeof(string))
  71. return (string.Compare(this.Label, (string)_obj, StringComparison.InvariantCultureIgnoreCase) == 0);
  72. return false;
  73. }
  74. /// <summary>
  75. /// Returns a hash for this object, it uses label's hash
  76. /// </summary>
  77. /// <returns>Hash calculated for this object</returns>
  78. public override int GetHashCode()
  79. {
  80. return Label.GetHashCode();
  81. }
  82. #endregion
  83. }
  84. /// <summary>
  85. /// Contains a directional edge
  86. /// </summary>
  87. public class Edge
  88. {
  89. /// <summary>
  90. /// Index of tail vertex
  91. /// </summary>
  92. public readonly Vertex Tail;
  93. /// <summary>
  94. /// Index of head vertex
  95. /// </summary>
  96. public readonly Vertex Head;
  97. /// <summary>
  98. /// Weight of edge
  99. /// </summary>
  100. public int Weight;
  101. /// <summary>
  102. /// Group label of edge
  103. /// </summary>
  104. public readonly string Group;
  105. #region Properties
  106. /// <summary>
  107. /// Returns the sidetrack delta (deviation from shortest path)
  108. /// Only is valid when shortest path tree has been calculated
  109. /// </summary>
  110. public int Delta
  111. {
  112. get { return this.Weight + this.Head.Distance - this.Tail.Distance; }
  113. }
  114. #endregion
  115. /// <summary>
  116. /// Constructor, generates a valid Edge
  117. /// </summary>
  118. /// <param name="_tail">Vertex object of tail endpoint</param>
  119. /// <param name="_head">Vertex object of head endpoint</param>
  120. /// <param name="_weight">Weight of edge</param>
  121. /// <param name="_group">Label of group where edge belongs to</param>
  122. /// <remarks>Edge is directional, goes from tail to head</remarks>
  123. public Edge(Vertex _tail, Vertex _head, int _weight, string _group)
  124. {
  125. Tail = _tail;
  126. Head = _head;
  127. Weight = _weight;
  128. Group = _group;
  129. }
  130. /// <summary>
  131. /// Tells if the edge is a possible sidetrack of specified vertex
  132. /// </summary>
  133. /// <param name="_v">Vertex to evaluate</param>
  134. /// <returns>True if edge is sidetrack of vertex, false if not</returns>
  135. public bool IsSidetrackOf(Vertex _v)
  136. {
  137. return (this.Tail == _v && this != _v.EdgeToPath && this.Weight >= 0);
  138. }
  139. /// <summary>
  140. /// Converts this object into a string where required
  141. /// </summary>
  142. /// <returns>Tail and head labels, and weight inside parenthesis</returns>
  143. public override string ToString()
  144. {
  145. return string.Concat(this.Tail, "--" + this.Weight + "-->", this.Head);
  146. }
  147. }
  148. /// <summary>
  149. /// Contains a path composed by a edges collection
  150. /// </summary>
  151. public class Path : List<Edge>
  152. {
  153. #region Properties
  154. /// <summary>
  155. /// Returns false if path is empty, true if not
  156. /// </summary>
  157. public bool IsValid
  158. {
  159. get { return (this.Count > 0); }
  160. }
  161. /// <summary>
  162. /// Returns string with comma-separated list containing all vertices in a path
  163. /// </summary>
  164. public string VertexNames
  165. {
  166. get
  167. {
  168. if (!IsValid)
  169. return "(empty)";
  170. StringBuilder builder = new StringBuilder(this[0].Tail.ToString());
  171. foreach (Edge e in this)
  172. {
  173. builder.Append("," + e.Head);
  174. }
  175. return builder.ToString();
  176. }
  177. }
  178. /// <summary>
  179. /// Returns sum of all weights of edges in the path
  180. /// </summary>
  181. public int Weight
  182. {
  183. get
  184. {
  185. int total = 0;
  186. foreach (Edge e in this)
  187. total += e.Weight;
  188. return total;
  189. }
  190. }
  191. /// <summary>
  192. /// Returns sum of all deltas of edges in the path
  193. /// </summary>
  194. public int DeltaWeight
  195. {
  196. get
  197. {
  198. int total = 0;
  199. foreach (Edge e in this)
  200. total += e.Delta;
  201. return total;
  202. }
  203. }
  204. #endregion
  205. /// <summary>
  206. /// Returns path's decriptive string
  207. /// </summary>
  208. /// <returns>List of delta for path</returns>
  209. public override string ToString()
  210. {
  211. if (!IsValid)
  212. return "(empty)";
  213. StringBuilder builder = new StringBuilder();
  214. foreach (Edge _e in this)
  215. {
  216. builder.Append(_e.Delta);
  217. builder.Append(',');
  218. }
  219. if (builder.Length > 0)
  220. builder.Remove(builder.Length - 1, 1);
  221. return builder.ToString();
  222. }
  223. }
  224. }