123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- package org.insa.algo.shortestpath;
-
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
-
- import org.insa.algo.AbstractInputData;
- import org.insa.algo.AbstractSolution.Status;
- import org.insa.graph.Arc;
- import org.insa.graph.Graph;
- import org.insa.graph.Node;
- import org.insa.graph.Path;
-
- public class BellmanFordAlgorithm extends ShortestPathAlgorithm {
-
- public BellmanFordAlgorithm(ShortestPathData data) {
- super(data);
- }
-
- @Override
- protected ShortestPathSolution doRun() {
-
- // Retrieve the graph.
- ShortestPathData data = getInputData();
- Graph graph = data.getGraph();
-
- final int nbNodes = graph.getNodes().size();
-
- // Initialize array of distances.
- double[] distances = new double[nbNodes];
- Arrays.fill(distances, Double.POSITIVE_INFINITY);
- distances[data.getOrigin().getId()] = 0;
-
- // Notify observers about the first event (origin processed).
- notifyOriginProcessed(data.getOrigin());
-
- // Initialize array of predecessors.
- Arc[] predecessorArcs = new Arc[nbNodes];
-
- // Actual algorithm, we will assume the graph does not contain negative cycle...
- boolean found = false;
- for (int i = 0; !found && i < nbNodes; ++i) {
- found = true;
- for (Node node: graph.getNodes()) {
- for (Arc arc: node.getSuccessors()) {
-
- // Small test to check allowed roads...
- if (!data.isAllowed(arc)) {
- continue;
- }
-
- // Retrieve weight of the arc.
- double w = data.getMode() == AbstractInputData.Mode.LENGTH ? arc.getLength()
- : arc.getMinimumTravelTime();
-
- double oldDistance = distances[arc.getDestination().getId()];
- double newDistance = distances[node.getId()] + w;
-
- if (Double.isInfinite(oldDistance) && Double.isFinite(newDistance)) {
- notifyNodeReached(arc.getDestination());
- }
-
- // Check if new distances would be better, if so update...
- if (newDistance < oldDistance) {
- found = false;
- distances[arc.getDestination().getId()] = distances[node.getId()] + w;
- predecessorArcs[arc.getDestination().getId()] = arc;
- }
- }
- }
- }
-
- ShortestPathSolution solution = null;
-
- // Destination has no predecessor, the solution is infeasible...
- if (predecessorArcs[data.getDestination().getId()] == null) {
- solution = new ShortestPathSolution(data, Status.INFEASIBLE);
- }
- else {
-
- // The destination has been found, notify the observers.
- notifyDestinationReached(data.getDestination());
-
- // Create the path from the array of predecessors...
- ArrayList<Arc> arcs = new ArrayList<>();
- Arc arc = predecessorArcs[data.getDestination().getId()];
- while (arc != null) {
- arcs.add(arc);
- arc = predecessorArcs[arc.getOrigin().getId()];
- }
-
- // Reverse the path...
- Collections.reverse(arcs);
-
- // Create the final solution.
- solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcs));
- }
-
- return solution;
- }
-
- }
|