programming-examples/java/Graph_Problems_Algorithms/FloydWarshall.java
2019-11-15 12:59:38 +01:00

83 lines
3.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.jwetherell.algorithms.graph;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.jwetherell.algorithms.data_structures.Graph;
/**
* FloydWarshall algorithm is a graph analysis algorithm for finding shortest
* paths in a weighted graph (with positive or negative edge weights).
*
* Worst case: O(V^3)
*
* https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm
*
* @author Justin Wetherell <phishman3579@gmail.com>
*/
public class FloydWarshall {
private FloydWarshall() { }
public static Map<Graph.Vertex<Integer>, Map<Graph.Vertex<Integer>, Integer>> getAllPairsShortestPaths(Graph<Integer> graph) {
if (graph == null)
throw (new NullPointerException("Graph must be non-NULL."));
final List<Graph.Vertex<Integer>> vertices = graph.getVertices();
final int[][] sums = new int[vertices.size()][vertices.size()];
for (int i = 0; i < sums.length; i++) {
for (int j = 0; j < sums[i].length; j++) {
sums[i][j] = Integer.MAX_VALUE;
}
}
final List<Graph.Edge<Integer>> edges = graph.getEdges();
for (Graph.Edge<Integer> e : edges) {
final int indexOfFrom = vertices.indexOf(e.getFromVertex());
final int indexOfTo = vertices.indexOf(e.getToVertex());
sums[indexOfFrom][indexOfTo] = e.getCost();
}
for (int k = 0; k < vertices.size(); k++) {
for (int i = 0; i < vertices.size(); i++) {
for (int j = 0; j < vertices.size(); j++) {
if (i == j) {
sums[i][j] = 0;
} else {
final int ijCost = sums[i][j];
final int ikCost = sums[i][k];
final int kjCost = sums[k][j];
final int summed = (ikCost != Integer.MAX_VALUE &&
kjCost != Integer.MAX_VALUE) ?
(ikCost + kjCost)
:
Integer.MAX_VALUE;
if (ijCost > summed)
sums[i][j] = summed;
}
}
}
}
final Map<Graph.Vertex<Integer>, Map<Graph.Vertex<Integer>, Integer>> allShortestPaths = new HashMap<Graph.Vertex<Integer>, Map<Graph.Vertex<Integer>, Integer>>();
for (int i = 0; i < sums.length; i++) {
for (int j = 0; j < sums[i].length; j++) {
final Graph.Vertex<Integer> from = vertices.get(i);
final Graph.Vertex<Integer> to = vertices.get(j);
Map<Graph.Vertex<Integer>, Integer> map = allShortestPaths.get(from);
if (map == null)
map = new HashMap<Graph.Vertex<Integer>, Integer>();
final int cost = sums[i][j];
if (cost != Integer.MAX_VALUE)
map.put(to, cost);
allShortestPaths.put(from, map);
}
}
return allShortestPaths;
}
}