Node
GraphNode
/// <summary>
/// Represents a node in a graph. A graph node contains some piece of data, along with a set of
/// neighbors. There can be an optional cost between a graph node and each of its neighbors.
/// </summary>
/// <typeparam name="T">The type of data stored in the graph node.</typeparam>
public class GraphNode<T> : Node<T>
{
#region Fields
private List<int> costs; // the cost associated with each edge
#endregion
#region Properties
/// <summary>
/// Returns the set of neighbors for this graph node.
/// </summary>
public new NodeList<T> Neighbors
{
get
{
if (base.Neighbors == null)
{
base.Neighbors = new NodeList<T>();
}
return base.Neighbors;
}
}
/// <summary>
/// Returns the set of costs for the edges eminating from this graph node.
/// The k<sup>th</sup> cost (Cost[k]) represents the cost from the graph node to the node
/// represented by its k<sup>th</sup> neighbor (Neighbors[k]).
/// </summary>
/// <value></value>
public List<int> Costs
{
get
{
if (costs == null)
{
costs = new List<int>();
}
return costs;
}
}
#endregion
#region Constructors
public GraphNode(T value)
: base(value)
{
}
public GraphNode(T value, NodeList<T> neighbors)
: base(value, neighbors)
{
}
#endregion
}
Graph
/// <summary>
/// Represents a graph. A graph is an arbitrary collection of GraphNode instances.
/// </summary>
/// <typeparam name="T">The type of data stored in the graph's nodes.</typeparam>
public class Graph<T> : ICollection<T>, IEnumerable<T>
{
#region Fields
private NodeList<T> nodeSet; // the set of nodes in the graph
#endregion
#region Properties
/// <summary>
/// Returns the set of nodes in the graph.
/// </summary>
public NodeList<T> Nodes
{
get { return nodeSet; }
}
/// <summary>
/// Returns the number of vertices in the graph.
/// </summary>
public int Count
{
get { return nodeSet.Count; }
}
bool ICollection<T>.IsReadOnly
{
get { return false; }
}
#endregion
#region Constructors
public Graph()
: this(null)
{
}
public Graph(NodeList<T> nodeSet)
{
this.nodeSet = nodeSet ?? new NodeList<T>();
}
#endregion
#region Methods
#region Add
/// <summary>
/// Adds a new value to the graph.
/// </summary>
/// <param name="value">The value to add to the graph</param>
public void Add(T value)
{
nodeSet.Add(new GraphNode<T>(value));
}
/// <summary>
/// Adds a new GraphNode instance to the Graph
/// </summary>
/// <param name="node">The GraphNode instance to add.</param>
public void Add(GraphNode<T> node)
{
// adds a node to the graph
nodeSet.Add(node);
}
#region Add*Edge Methods
/// <summary>
/// Adds a directed edge from a GraphNode with one value (from) to a GraphNode with another value (to).
/// </summary>
/// <param name="from">The value of the GraphNode from which the directed edge eminates.</param>
/// <param name="to">The value of the GraphNode to which the edge leads.</param>
public void AddDirectedEdge(T from, T to)
{
AddDirectedEdge(from, to, 0);
}
/// <summary>
/// Adds a directed edge from one GraphNode (from) to another (to).
/// </summary>
/// <param name="from">The GraphNode from which the directed edge eminates.</param>
/// <param name="to">The GraphNode to which the edge leads.</param>
public void AddDirectedEdge(GraphNode<T> from, GraphNode<T> to)
{
AddDirectedEdge(from, to, 0);
}
/// <summary>
/// Adds a directed edge from one GraphNode (from) to another (to) with an associated cost.
/// </summary>
/// <param name="from">The GraphNode from which the directed edge eminates.</param>
/// <param name="to">The GraphNode to which the edge leads.</param>
/// <param name="cost">The cost of the edge from "from" to "to".</param>
public void AddDirectedEdge(GraphNode<T> from, GraphNode<T> to, int cost)
{
from.Neighbors.Add(to);
from.Costs.Add(cost);
}
/// <summary>
/// Adds a directed edge from a GraphNode with one value (from) to a GraphNode with another value (to)
/// with an associated cost.
/// </summary>
/// <param name="from">The value of the GraphNode from which the directed edge eminates.</param>
/// <param name="to">The value of the GraphNode to which the edge leads.</param>
/// <param name="cost">The cost of the edge from "from" to "to".</param>
public void AddDirectedEdge(T from, T to, int cost)
{
((GraphNode<T>)nodeSet.Find(from)).Neighbors.Add(nodeSet.Find(to));
((GraphNode<T>)nodeSet.Find(from)).Costs.Add(cost);
}
/// <summary>
/// Adds an undirected edge from a GraphNode with one value (from) to a GraphNode with another value (to).
/// </summary>
/// <param name="from">The value of one of the GraphNodes that is joined by the edge.</param>
/// <param name="to">The value of one of the GraphNodes that is joined by the edge.</param>
public void AddUndirectedEdge(T from, T to)
{
AddUndirectedEdge(from, to, 0);
}
/// <summary>
/// Adds an undirected edge from one GraphNode to another.
/// </summary>
/// <param name="from">One of the GraphNodes that is joined by the edge.</param>
/// <param name="to">One of the GraphNodes that is joined by the edge.</param>
public void AddUndirectedEdge(GraphNode<T> from, GraphNode<T> to)
{
AddUndirectedEdge(from, to, 0);
}
/// <summary>
/// Adds an undirected edge from one GraphNode to another with an associated cost.
/// </summary>
/// <param name="from">One of the GraphNodes that is joined by the edge.</param>
/// <param name="to">One of the GraphNodes that is joined by the edge.</param>
/// <param name="cost">The cost of the undirected edge.</param>
public void AddUndirectedEdge(GraphNode<T> from, GraphNode<T> to, int cost)
{
from.Neighbors.Add(to);
from.Costs.Add(cost);
to.Neighbors.Add(from);
to.Costs.Add(cost);
}
/// <summary>
/// Adds an undirected edge from a GraphNode with one value (from) to a GraphNode with another value (to)
/// with an associated cost.
/// </summary>
/// <param name="from">The value of one of the GraphNodes that is joined by the edge.</param>
/// <param name="to">The value of one of the GraphNodes that is joined by the edge.</param>
/// <param name="cost">The cost of the undirected edge.</param>
public void AddUndirectedEdge(T from, T to, int cost)
{
((GraphNode<T>)nodeSet.Find(from)).Neighbors.Add(nodeSet.Find(to));
((GraphNode<T>)nodeSet.Find(from)).Costs.Add(cost);
((GraphNode<T>)nodeSet.Find(to)).Neighbors.Add(nodeSet.Find(from));
((GraphNode<T>)nodeSet.Find(to)).Costs.Add(cost);
}
#endregion
#endregion
#region Clear
/// <summary>
/// Clears out the contents of the Graph.
/// </summary>
public void Clear()
{
nodeSet.Clear();
}
#endregion
#region Contains
/// <summary>
/// Returns a Boolean, indicating if a particular value exists within the graph.
/// </summary>
/// <param name="value">The value to search for.</param>
/// <returns>True if the value exist in the graph; false otherwise.</returns>
public bool Contains(T value)
{
return nodeSet.Find(value) != null;
}
#endregion
#region CopyTo
public void CopyTo(T[] array, int arrayIndex)
{
for (int i = 0; i < nodeSet.Count; i++)
{
array[arrayIndex + i] = nodeSet[i].Value;
}
}
#endregion
#region Remove
/// <summary>
/// Attempts to remove a node from a graph.
/// </summary>
/// <param name="value">The value that is to be removed from the graph.</param>
/// <returns>True if the corresponding node was found, and removed; false if the value was not
/// present in the graph.</returns>
/// <remarks>This method removes the GraphNode instance, and all edges leading to or from the
/// GraphNode.</remarks>
public bool Remove(T value)
{
// first remove the node from the nodeset
GraphNode<T> nodeToRemove = (GraphNode<T>)nodeSet.Find(value);
if (nodeToRemove == null)
{
// node wasn't found
return false;
}
// otherwise, the node was found
nodeSet.Remove(nodeToRemove);
// enumerate through each node in the nodeSet, removing edges to this node
foreach (GraphNode<T> gnode in nodeSet)
{
int index = gnode.Neighbors.IndexOf(nodeToRemove);
if (index != -1)
{
// remove the reference to the node and associated cost
gnode.Neighbors.RemoveAt(index);
gnode.Costs.RemoveAt(index);
}
}
return true;
}
#endregion
#region IEnumerable<T> Members
/// <summary>
/// Returns an enumerator that allows for iterating through the contents of the graph.
public IEnumerator<T> GetEnumerator()
{
foreach (GraphNode<T> gnode in nodeSet)
{
yield return gnode.Value;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
#endregion
}
/// <summary>
/// The Node<T> class represents the base concept of a Node for a tree or graph.
/// It contains a data item of type T, and a list of neighbors.
/// </summary>
/// <typeparam name="T">The type of data contained in the Node.</typeparam>
public class Node<T>
{
#region Fields
private T data;
private NodeList<T> neighbors;
#endregion
#region Properties
public T Value
{
get { return data; }
protected internal set { data = value; }
}
protected NodeList<T> Neighbors
{
get { return neighbors; }
set { neighbors = value; }
}
#endregion
#region Constructors
protected internal Node()
{
}
public Node(T data)
: this(data, null)
{
}
public Node(T data, NodeList<T> neighbors)
{
this.data = data;
this.neighbors = neighbors;
}
#endregion
}