Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* ==========================================
* JGraphT : a free Java graph-theory library
* ==========================================
*
* Project Info: http://jgrapht.sourceforge.net/
* Project Creator: Barak Naveh (http://sourceforge.net/users/barak_naveh)
*
* (C) Copyright 2003-2009, by Barak Naveh and Contributors.
*
* This program and the accompanying materials are dual-licensed under
* either
*
* (a) the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation, or (at your option) any
* later version.
*
* or (per the licensee's choosing)
*
* (b) the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation.
*/
/* -------------------------
* FloydWarshallShortestPaths.java
* -------------------------
* (C) Copyright 2009-2009, by Tom Larkworthy and Contributors
*
* Original Author: Tom Larkworthy
* Contributor(s): Soren Davidsen
*
* $Id: FloydWarshallShortestPaths.java 755 2012-01-18 23:50:37Z perfecthash $
*
* Changes
* -------
* 29-Jun-2009 : Initial revision (TL);
* 03-Dec-2009 : Optimized and enhanced version (SD);
*
*/
package org.jgrapht.alg;
import java.util.*;
import org.jgrapht.*;
import org.jgrapht.graph.*;
import org.jgrapht.util.*;
/**
* The
* Floyd-Warshall algorithm finds all shortest paths (all n^2 of them) in
* O(n^3) time. It can also calculate the graph diameter.
*
* @author Tom Larkworthy
* @author Soren Davidsen
*/
public class FloydWarshallShortestPaths
{
private Graph graph;
private List vertices;
private int nShortestPaths = 0;
private double diameter = Double.NaN;
private double [][] d = null;
private int [][] backtrace = null;
private Map, GraphPath> paths = null;
public FloydWarshallShortestPaths(Graph graph)
{
this.graph = graph;
this.vertices = new ArrayList(graph.vertexSet());
}
/**
* @return the graph on which this algorithm operates
*/
public Graph getGraph()
{
return graph;
}
/**
* @return total number of shortest paths
*/
public int getShortestPathsCount()
{
lazyCalculatePaths();
return nShortestPaths;
}
/**
* Calculates the matrix of all shortest paths, but does not populate the
* paths map.
*/
private void lazyCalculateMatrix()
{
if (d != null) {
// already done
return;
}
int n = vertices.size();
// init the backtrace matrix
backtrace = new int[n][n];
for (int i = 0; i < n; i++) {
Arrays.fill(backtrace[i], -1);
}
// initialize matrix, 0
d = new double[n][n];
for (int i = 0; i < n; i++) {
Arrays.fill(d[i], Double.POSITIVE_INFINITY);
}
// initialize matrix, 1
for (int i = 0; i < n; i++) {
d[i][i] = 0.0;
}
// initialize matrix, 2
Set edges = graph.edgeSet();
for (E edge : edges) {
V v1 = graph.getEdgeSource(edge);
V v2 = graph.getEdgeTarget(edge);
int v_1 = vertices.indexOf(v1);
int v_2 = vertices.indexOf(v2);
d[v_1][v_2] = graph.getEdgeWeight(edge);
if (!(graph instanceof DirectedGraph)) {
d[v_2][v_1] = graph.getEdgeWeight(edge);
}
}
// run fw alg
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
double ik_kj = d[i][k] + d[k][j];
if (ik_kj < d[i][j]) {
d[i][j] = ik_kj;
backtrace[i][j] = k;
}
}
}
}
}
/**
* Get the length of a shortest path.
*
* @param a first vertex
* @param b second vertex
*
* @return shortest distance between a and b
*/
public double shortestDistance(V a, V b)
{
lazyCalculateMatrix();
return d[vertices.indexOf(a)][vertices.indexOf(b)];
}
/**
* @return the diameter (longest of all the shortest paths) computed for the
* graph. If the graph is vertexless, return 0.0.
*/
public double getDiameter()
{
lazyCalculateMatrix();
if (Double.isNaN(diameter)) {
diameter = 0.0;
int n = vertices.size();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (!Double.isInfinite(d[i][j]) && (d[i][j] > diameter)) {
diameter = d[i][j];
}
}
}
}
return diameter;
}
private void shortestPathRecur(List edges, int v_a, int v_b)
{
int k = backtrace[v_a][v_b];
if (k == -1) {
E edge = graph.getEdge(vertices.get(v_a), vertices.get(v_b));
if (edge != null) {
edges.add(edge);
}
} else {
shortestPathRecur(edges, v_a, k);
shortestPathRecur(edges, k, v_b);
}
}
/**
* Get the shortest path between two vertices. Note: The paths are
* calculated using a recursive algorithm. It *will* give problems on paths
* longer than the stack allows.
*
* @param a From vertice
* @param b To vertice
*
* @return the path, or null if none found
*/
public GraphPath getShortestPath(V a, V b)
{
lazyCalculatePaths();
return getShortestPathImpl(a, b);
}
private GraphPath getShortestPathImpl(V a, V b)
{
int v_a = vertices.indexOf(a);
int v_b = vertices.indexOf(b);
List edges = new ArrayList();
shortestPathRecur(edges, v_a, v_b);
// no path, return null
if (edges.size() < 1) {
return null;
}
double weight = 0.;
for (E e : edges) {
weight += graph.getEdgeWeight(e);
}
GraphPathImpl path =
new GraphPathImpl(graph, a, b, edges, weight);
return path;
}
/**
* Calculate the shortest paths (not done per default)
*/
private void lazyCalculatePaths()
{
// already we have calculated it once.
if (paths != null) {
return;
}
lazyCalculateMatrix();
Map, GraphPath> sps =
new HashMap, GraphPath>();
int n = vertices.size();
nShortestPaths = 0;
for (int i = 0; i < n; i++) {
V v_i = vertices.get(i);
for (int j = 0; j < n; j++) {
// don't count this.
if (i == j) {
continue;
}
V v_j = vertices.get(j);
GraphPath path = getShortestPathImpl(v_i, v_j);
// we got a path
if (path != null) {
sps.put(new VertexPair(v_i, v_j), path);
nShortestPaths++;
}
}
}
this.paths = sps;
}
/**
* Get shortest paths from a vertex to all other vertices in the graph.
*
* @param v the originating vertex
*
* @return List of paths
*/
public List> getShortestPaths(V v)
{
lazyCalculatePaths();
List> found = new ArrayList>();
// TODO: two-level map for paths so that we don't have to
// iterate over all paths here!
for (VertexPair pair : paths.keySet()) {
if (pair.getFirst().equals(v)) {
found.add(paths.get(pair));
}
}
return found;
}
/**
* Get all shortest paths in the graph.
*
* @return List of paths
*/
public Collection> getShortestPaths()
{
lazyCalculatePaths();
return paths.values();
}
}
// End FloydWarshallShortestPaths.java