No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BellmanFordAlgorithm.java 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package org.insa.algo.shortestpath;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.Collections;
  5. import org.insa.algo.AbstractInputData;
  6. import org.insa.algo.AbstractSolution.Status;
  7. import org.insa.graph.Arc;
  8. import org.insa.graph.Graph;
  9. import org.insa.graph.Node;
  10. import org.insa.graph.Path;
  11. public class BellmanFordAlgorithm extends ShortestPathAlgorithm {
  12. public BellmanFordAlgorithm(ShortestPathData data) {
  13. super(data);
  14. }
  15. @Override
  16. protected ShortestPathSolution doRun() {
  17. // Retrieve the graph.
  18. ShortestPathData data = getInputData();
  19. Graph graph = data.getGraph();
  20. final int nbNodes = graph.size();
  21. // Initialize array of distances.
  22. double[] distances = new double[nbNodes];
  23. Arrays.fill(distances, Double.POSITIVE_INFINITY);
  24. distances[data.getOrigin().getId()] = 0;
  25. // Notify observers about the first event (origin processed).
  26. notifyOriginProcessed(data.getOrigin());
  27. // Initialize array of predecessors.
  28. Arc[] predecessorArcs = new Arc[nbNodes];
  29. // Actual algorithm, we will assume the graph does not contain negative cycle...
  30. boolean found = false;
  31. for (int i = 0; !found && i < nbNodes; ++i) {
  32. found = true;
  33. for (Node node: graph) {
  34. for (Arc arc: node) {
  35. // Small test to check allowed roads...
  36. if (!data.isAllowed(arc)) {
  37. continue;
  38. }
  39. // Retrieve weight of the arc.
  40. double w = data.getMode() == AbstractInputData.Mode.LENGTH ? arc.getLength()
  41. : arc.getMinimumTravelTime();
  42. double oldDistance = distances[arc.getDestination().getId()];
  43. double newDistance = distances[node.getId()] + w;
  44. if (Double.isInfinite(oldDistance) && Double.isFinite(newDistance)) {
  45. notifyNodeReached(arc.getDestination());
  46. }
  47. // Check if new distances would be better, if so update...
  48. if (newDistance < oldDistance) {
  49. found = false;
  50. distances[arc.getDestination().getId()] = distances[node.getId()] + w;
  51. predecessorArcs[arc.getDestination().getId()] = arc;
  52. }
  53. }
  54. }
  55. }
  56. ShortestPathSolution solution = null;
  57. // Destination has no predecessor, the solution is infeasible...
  58. if (predecessorArcs[data.getDestination().getId()] == null) {
  59. solution = new ShortestPathSolution(data, Status.INFEASIBLE);
  60. }
  61. else {
  62. // The destination has been found, notify the observers.
  63. notifyDestinationReached(data.getDestination());
  64. // Create the path from the array of predecessors...
  65. ArrayList<Arc> arcs = new ArrayList<>();
  66. Arc arc = predecessorArcs[data.getDestination().getId()];
  67. while (arc != null) {
  68. arcs.add(arc);
  69. arc = predecessorArcs[arc.getOrigin().getId()];
  70. }
  71. // Reverse the path...
  72. Collections.reverse(arcs);
  73. // Create the final solution.
  74. solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcs));
  75. }
  76. return solution;
  77. }
  78. }