public FloydInfo(SharedGraph g) { int l = g.graph.Count; // Adjacency matrix map = new long[l, l]; }
public static FloydInfo AllShortestPaths(SharedGraph g) { FloydInfo fi = new FloydInfo(g); int l = g.graph.Count; // Set distances to zero or 'infinity' for (int i = 0; i < l; i++) { for (int j = 0; j < l; j++) { fi.map[i, j] = (i == j)? 0 : long.MaxValue; } } // Set initial distances between vertices for (int i = 0; i < g.graph.Count; i++) { foreach (Edge e in g.graph[i]) { fi.map[i, e.destination] = e.weight; } } // Perform basic floyd warshall algorithm for (int k = 0; k < l; k++) { for (int i = 0; i < l; i++) { for (int j = 0; j < l; j++) { long far = long.MaxValue; if (fi.map[i, k] == far || fi.map[k, j] == far) { continue; } fi.map[i, j] = Math.Min(fi.map[i, j], fi.map[i, k] + fi.map[k, j]); } } } return(fi); }
/// <summary> /// Method finShortestPath is using Dijkstra's algorithm to find /// shortest path between two vertices. /// </summary> /// <returns> /// It returns instance of Dijkstra class, containing info about /// shortest path. If there is no path between given vertices, /// shortestPath parameter in Dijkstra instance is empty and distance is /// set to long.MaxValue. /// </returns> /// <param name="source"> long that is ID of source vertex of the /// shortest path </param> /// <param name="destination"> long that is ID of destination vertex of /// the shortest path </param> public static DijkstraInfo FindShortestPath(SharedGraph g, int source, int destination) { List <List <Edge> > graph = g.graph; // Create priority queue Heap pq = new Heap(); // 0 - not visited, 1 - in queue, 2 - closed byte [] visited = new byte[graph.Count]; // For every node, remember from where it was visited first int [] backtrack = new int[graph.Count]; for (int i = 0; i < graph.Count; i++) { backtrack[i] = i; } long cost = long.MaxValue; pq.add(source, 0, source); // While there are unprocessed vertices do search while (pq.size() > 0) { /* Take closest reached vertex, mark it as visited and process * its neighbors */ Heap.Vertex top = pq.pop(); visited[top.v] = 2; // Set parent of the current node backtrack[top.v] = top.parent; // If destination was reached, stop the search if (top.v == destination) { cost = Math.Min(cost, top.cost); break; } // for all neighbors for (int i = 0; i < graph[top.v].Count; i++) { int neighbor = graph[top.v][i].destination; long weight = graph[top.v][i].weight; // Skip if the neighbor was already processed if (visited[neighbor] == 2) { continue; } // If neighbor is not visited, add it to queue else if (visited[neighbor] == 0) { long price = top.cost + weight; pq.add(neighbor, price, top.v); visited[neighbor] = 1; } // Upload cost if there was a better path found else if (pq.position.ContainsKey(neighbor)) { pq.decrease_key(neighbor, top.cost + weight, top.v); } } } int parent = destination; List <int> path = new List <int>(); // Reconstruct the shortest path while (backtrack[parent] != parent) { path.Add(parent); parent = backtrack[parent]; } path.Add(source); // Return Dijkstra object with informations about shortest path return(new DijkstraInfo(cost, path)); }