/// <summary> /// Adds a neighbor to the node. /// </summary> /// <param name="neighborToAdd"></param> /// <param name="connectionWeight"></param> public void AddNeighbor(WeightedUndirectedGraphNode <T> neighborToAdd, int connectionWeight) { //First check if the connection doesn't already exist. if (!m_Neighbors.ContainsValue(neighborToAdd.Data)) { //Create a new connection object. This is used for the weighted graph. WeightedGraphConnection <T> newConnection = new WeightedGraphConnection <T>(neighborToAdd, connectionWeight); //Add the new connection to the list of connections. m_Neighbors.Add(newConnection, neighborToAdd.Data); //Tell the neighbor to add this connection to it's list of connections. //This is done because the graph is undirected. neighborToAdd.AddNeighbor(this, connectionWeight); } else { var myKey = m_Neighbors.FirstOrDefault(x => x.Value.Equals(neighborToAdd.Data)).Key; if (connectionWeight != myKey.ConnectionWeight) { WeightedGraphConnection <T> newConnection = new WeightedGraphConnection <T>(neighborToAdd, connectionWeight); m_Neighbors.Add(newConnection, neighborToAdd.Data); neighborToAdd.OneWayAdd(this, connectionWeight); } } }
public WeightedUndirectedGraph(T initialNodeData) { Nodes = new Dictionary <T, WeightedUndirectedGraphNode <T> >(); WeightedUndirectedGraphNode <T> initialNode = new WeightedUndirectedGraphNode <T>(initialNodeData); Nodes.Add(initialNodeData, initialNode); NumberOfComponents = 0; }
public void OneWayAdd(WeightedUndirectedGraphNode <T> neighborToAdd, int connectionWeight) { var myKey = m_Neighbors.FirstOrDefault(x => x.Value.Equals(neighborToAdd.Data)).Key; if (connectionWeight != myKey.ConnectionWeight) { //Create a new connection object. This is used for the weighted graph. WeightedGraphConnection <T> newConnection = new WeightedGraphConnection <T>(neighborToAdd, connectionWeight); //Add the new connection to the list of connections. m_Neighbors.Add(newConnection, neighborToAdd.Data); } }
/// <summary> /// Function for adding an edge. /// </summary> /// <param name="vertexOne"></param> /// <param name="vertexTwo"></param> /// <param name="connectionWeight"></param> public void AddEdge(T vertexOne, T vertexTwo, int connectionWeight) { //Check if vertex one and two are null. if (vertexOne == null) { throw new ArgumentNullException(nameof(vertexOne)); } if (vertexTwo == null) { throw new ArgumentNullException(nameof(vertexTwo)); } //Check if the nodes aren't already in the graph. bool v2Index = Nodes.ContainsKey(vertexTwo); bool v1Index = Nodes.ContainsKey(vertexOne); //The following segment guarantees that the two nodes are in the graph before making a connection between them. //Case: First node isn't in the graph. if (!v1Index) { //Create a new node that has the value of vertex one. WeightedUndirectedGraphNode <T> nodeOne = new WeightedUndirectedGraphNode <T>(vertexOne); //Add the node to the dictionary of the graph. Nodes.Add(vertexOne, nodeOne); } //Case: Second node isn't in the graph. if (!v2Index) { //Create a new node that has the value of vertex two. WeightedUndirectedGraphNode <T> nodeTwo = new WeightedUndirectedGraphNode <T>(vertexTwo); //Add the node to the dictionary of the graph. Nodes.Add(vertexTwo, nodeTwo); } //Finally establish the connection between the two nodes. Nodes[vertexTwo].AddNeighbor(Nodes[vertexOne], connectionWeight); }
//Algorithm for finding the shortest paths to all nodes from a given source node. public Dictionary <WeightedUndirectedGraphNode <T>, int> FindPath(T source) { //Get the source node. WeightedUndirectedGraphNode <T> sourceNode = Nodes[source]; //Create dictionary that will hold the distances to all nodes from source node. //This dictionary also contains the distance to the source itself. Dictionary <WeightedUndirectedGraphNode <T>, int> distances = new Dictionary <WeightedUndirectedGraphNode <T>, int>(); //Create priority queue that will always have the next smallest distance to at the front. PriorityQueue <WeightedUndirectedGraphNode <T> > distQueue = new PriorityQueue <WeightedUndirectedGraphNode <T> >(Nodes.Count); //As the previous loop set the distance from source to source to infinity //it now has to be changed to 0 as it should be //Set in the distance dictionary the distance to source as zero. distances[sourceNode] = 0; //Set the property Distance to this of the node itself as 0. //This will also reset any previous values of DistanceToThis. sourceNode.DistanceToThis = 0; //Add source to to priority queue. distQueue.Enqueue(sourceNode); //Initialize the the distances to nodes. foreach (var node in Nodes) { if (node.Value != sourceNode) { //Set the DistanceToThis property of the current node to infinity. node.Value.DistanceToThis = int.MaxValue; //Set the value in the distances dictionary. distances[node.Value] = int.MaxValue; //Enqueue the current node in the priority queue. distQueue.Enqueue(node.Value); } } //Finding the shortest distances can now begin. //The following while loop runs while the priority queue has element. //Once it is empty that means we have found the shortest path to all nodes. while (distQueue.Count() > 0) { //Get the value of the path to the node to which the distance is the shortest. int currentMin = distQueue.Front().DistanceToThis; //The the actual node. WeightedUndirectedGraphNode <T> currentVertex = distQueue.Front(); //Remove that node from the priority queue as it has now been visited. distQueue.Dequeue(); //Now each neighbor of the current node is visited. foreach (var neighbor in currentVertex.GetNeighbors()) { //Calculate an alternative distance to current neighbor. //The formula is as follows: //altDistance = (cost of the path to the current node) + (cost of the path to neighbor node); int alternativeDist = currentMin + neighbor.Key.ConnectionWeight; //Now a check must be performed to determine if a better route to current neighbor has been found. //That is why we check the value in the distances dictionary. if (alternativeDist < distances[neighbor.Key.ConnectionNeighbor]) { //First change the value in the distances dictionary. distances[neighbor.Key.ConnectionNeighbor] = alternativeDist; //Change the value of DistanceToThis of the neighbor node. neighbor.Key.ConnectionNeighbor.DistanceToThis = alternativeDist; //Resort the distance queue, //as the values have now changed and a smaller value is in the queue. distQueue.Sort(); } //Repeat the steps above for each neighbor } //Repeat the steps above for each element in the priority queue. } //Return the final dictionary of distances. return(distances); }
public WeightedGraphConnection(WeightedUndirectedGraphNode <T> connectionNeighbor, int weight) { ConnectionNeighbor = connectionNeighbor; ConnectionWeight = weight; }