![JAR search and dependency download from the Maven repository](/logo.png)
net.sf.javagimmicks.graph.routing.DijkstraRouteFinder Maven / Gradle / Ivy
package net.sf.javagimmicks.graph.routing;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.javagimmicks.graph.AbstractRouteFinder;
import net.sf.javagimmicks.graph.DefaultRoute;
import net.sf.javagimmicks.graph.Edge;
import net.sf.javagimmicks.graph.Graph;
import net.sf.javagimmicks.graph.Route;
import net.sf.javagimmicks.graph.WeightedEdge;
public class DijkstraRouteFinder> extends AbstractRouteFinder
{
public static > DijkstraRouteFinder createInstance(Graph graph)
{
return new DijkstraRouteFinder(graph);
}
public DijkstraRouteFinder(Graph graph)
{
super(graph);
}
public Route findRoute(V source, V target)
{
final Map> result = new HashMap>();
findRoutes(_graph, source, result, target);
return result.get(target);
}
public Map> findRoutes(V source)
{
final Map> result = new HashMap>();
findRoutes(_graph, source, result, null);
return result;
}
public static > void findRoutes(Graph graph, V source, Map> routes, V optionalTargetVertex)
{
final Map costs = new HashMap();
costs.put(source, 0.0);
final Map previous = new HashMap();
doFindRoutes(graph, costs, previous, optionalTargetVertex);
if(optionalTargetVertex == null)
{
for(V target : previous.keySet())
{
createAddRoute(routes, costs, previous, target);
}
}
else
{
createAddRoute(routes, costs, previous, optionalTargetVertex);
}
}
protected static > void doFindRoutes(final Graph graph, final Map costs, final Map previous, V optionalTargetVertex)
{
final List vertexList = new ArrayList(graph.vertexSet());
sortVertecesByCost(vertexList, costs);
while(!vertexList.isEmpty())
{
final V currentVertex = vertexList.remove(0);
final Double currentCost = costs.get(currentVertex);
if(currentCost == null)
{
break;
}
for(E edge : graph.edgesOf(currentVertex))
{
final V targetVertex = edge.getOutgoingVertex(currentVertex);
final double targetNewCost = currentCost +
((edge instanceof WeightedEdge, ?>) ? ((WeightedEdge)edge).getCost() : 1.0);
final Double targetCurrentCost = costs.get(targetVertex);
if(targetCurrentCost == null || targetNewCost < targetCurrentCost)
{
costs.put(targetVertex, targetNewCost);
previous.put(targetVertex, edge);
sortVertecesByCost(vertexList, costs);
}
if(optionalTargetVertex != null && optionalTargetVertex.equals(targetVertex))
{
return;
}
}
}
}
protected static > void createAddRoute(final Map> routes, final Map costs, final Map previous, V target)
{
// Skip if route is already there
if(routes.containsKey(target))
{
return;
}
final E edge = previous.get(target);
// Trivial case - the source vertex itself
if(edge == null)
{
routes.put(target, new DefaultRoute(target, target));
return;
}
// Get the source vertex and (optionally build the route for it)
final V source = edge.getOutgoingVertex(target);
createAddRoute(routes, costs, previous, source);
// Build a new route by adding the current edge to the route of the previous node
final Route sourceRoute = routes.get(source);
final DefaultRoute newRoute = new DefaultRoute(sourceRoute.getSourceVertex(), target);
newRoute.addAll(sourceRoute);
newRoute.add(edge);
routes.put(target, newRoute);
}
protected static void sortVertecesByCost(final List vertexList, final Map costs)
{
Collections.sort(vertexList, new DistComparator(costs));
}
protected static final class DistComparator implements Comparator
{
protected final Map _costs;
public DistComparator(Map costs)
{
_costs = costs;
}
public int compare(V v1, V v2)
{
Double d1 = _costs.get(v1);
Double d2 = _costs.get(v2);
if(d1 == null)
{
return d2 == null ? 0 : 1;
}
else if(d2 == null)
{
return -1;
}
else
{
return d1.compareTo(d2);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy