/// <summary> /// Return the name (key) of the next unvisited vertex /// </summary> /// <param name="name">Name/Key of the Dictionary item to look for</param> /// <returns>Vertex of the next, previously unvisited vertex</returns> public Vertex GetAdjacentUnvisited(String name) { bool foundVisited = false; int indexOfVertexInList = 0; int incrementor = 0; Vertex returnValue = null; if (GraphDictionary.ContainsKey(name)) // Test if the key exists in the dictionary { indexOfVertexInList = GraphList.IndexOf(GraphDictionary[name]); // Get the index of the vertex do // Loop through vertices until one is found that { // wasn't found before if ((adjMatrix[indexOfVertexInList, incrementor] != 0) && (!GraphList[incrementor].Visited) && (!VisitedList.Contains(GraphList[incrementor]))) { returnValue = GraphList[incrementor]; // Return the next vertex GraphList[incrementor].Visited = true; // Set it's "visited" property to true foundVisited = true; // Set the "found" variable to true to break the loop } incrementor++; // do/while incrementor } while ((!foundVisited) && (incrementor < adjMatrix.GetLength(1))); // Once we find a vertex, or get to the end of the matrix, break } return(returnValue); }
/// <summary> /// Dijkstra's algorithm - calculate shortest path /// </summary> /// <param name="name">Starting vertex to calculate from</param> public void ShortestPath(string name) { PriorityQueue searchQueue = new PriorityQueue(); Vertex nextVertex; List <Vertex> currentVertices = new List <Vertex>(); Reset(); // Reset all graph weight information name = name.ToUpper(); // Set input data to uppercase if (!GraphDictionary.ContainsKey(name)) // If the supplied index doesn't exist, throw exception { throw new IndexOutOfRangeException(); } GraphDictionary[name].Distance = 0; // Set first node properties GraphDictionary[name].Final = true; int distanceBetweenNeighbors; int distanceToSource; try { GraphDictionary[name].Visited = true; // Set first vertex as visited searchQueue.Enqueue(GraphDictionary[name]); // Add first vertex to priority queue do { nextVertex = GetAdjacentUnvisited(searchQueue.Peek().Name); // Get next adjacent vertex if (nextVertex != null) { distanceBetweenNeighbors = adjMatrix[ // Calculate distance between focus and neighbor GraphList.IndexOf(GraphDictionary[searchQueue.Peek().Name]), GraphList.IndexOf(nextVertex) ]; distanceToSource = (distanceBetweenNeighbors + searchQueue.Peek().Distance);// Calculate distance to head if (( (nextVertex.Neighbor == null) || // IF neighbor is null (nextVertex.Distance > distanceToSource) // OR it has a larger distance than the new vertex ) && ( !nextVertex.Final // AND it is not set to final )) { nextVertex.Neighbor = searchQueue.Peek(); // Set neighbor's neighbor to head nextVertex.Distance = distanceToSource; // Set new distance if (!searchQueue.Contains(nextVertex)) { searchQueue.Enqueue(nextVertex); // Add the neighbor to the priority queue } } distanceBetweenNeighbors = 0; distanceToSource = 0; currentVertices.Add(nextVertex); // add it to the current list } else // If the neighbor is null (does not exist) { if (currentVertices.Count != 0) // If vertices were added to the current list { UpdateFinals(currentVertices); // Update final properties currentVertices.Clear(); // Clear the list } ResetVisited(); // Reset visited properties searchQueue.Dequeue(); // Remove the vertex from the queue } nextVertex = null; // Set neighbor to null } while (searchQueue != null); } catch (Exception DepthFirstException) // Catch possible exceptions { if ((DepthFirstException is KeyNotFoundException) || (DepthFirstException is IndexOutOfRangeException)) { throw new IndexOutOfRangeException("The specified index does not exist"); } } }