Browse Source

Add getNodes() and getSuccessors() methods and remove iterable from Graph and Node.

Mikaël Capelle 2 years ago
parent
commit
d8470055f1

+ 84
- 83
src/main/org/insa/algo/shortestpath/BellmanFordAlgorithm.java View File

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

+ 2
- 2
src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsAlgorithm.java View File

@@ -77,8 +77,8 @@ public class WeaklyConnectedComponentsAlgorithm
77 77
             res.add(new HashSet<Integer>());
78 78
         }
79 79
 
80
-        for (Node node: getInputData().getGraph()) {
81
-            for (Arc arc: node) {
80
+        for (Node node: getInputData().getGraph().getNodes()) {
81
+            for (Arc arc: node.getSuccessors()) {
82 82
                 res.get(node.getId()).add(arc.getDestination().getId());
83 83
                 if (arc.getRoadInformation().isOneWay()) {
84 84
                     res.get(arc.getDestination().getId()).add(node.getId());

+ 9
- 6
src/main/org/insa/graph/Graph.java View File

@@ -2,7 +2,6 @@ package org.insa.graph;
2 2
 
3 3
 import java.util.ArrayList;
4 4
 import java.util.Collections;
5
-import java.util.Iterator;
6 5
 import java.util.List;
7 6
 
8 7
 /**
@@ -12,7 +11,7 @@ import java.util.List;
12 11
  * holds a list of nodes and each node holds a list of its successors.
13 12
  *
14 13
  */
15
-public final class Graph implements Iterable<Node> {
14
+public final class Graph {
16 15
 
17 16
     // Map identifier.
18 17
     private final String mapId;
@@ -68,9 +67,13 @@ public final class Graph implements Iterable<Node> {
68 67
         return this.nodes.size();
69 68
     }
70 69
 
71
-    @Override
72
-    public Iterator<Node> iterator() {
73
-        return this.nodes.iterator();
70
+    /**
71
+     * @return List of nodes in this graph (unmodifiable).
72
+     * 
73
+     * @see Collections#unmodifiableList(List)
74
+     */
75
+    public List<Node> getNodes() {
76
+        return this.nodes;
74 77
     }
75 78
 
76 79
     /**
@@ -97,7 +100,7 @@ public final class Graph implements Iterable<Node> {
97 100
         }
98 101
         for (Node node: nodes) {
99 102
             Node orig = trNodes.get(node.getId());
100
-            for (Arc arc: node) {
103
+            for (Arc arc: node.getSuccessors()) {
101 104
                 if (arc.getRoadInformation().isOneWay()) {
102 105
                     Node dest = trNodes.get(arc.getDestination().getId());
103 106
                     dest.addSuccessor(new ArcBackward(new ArcForward(orig, dest, arc.getLength(),

+ 9
- 5
src/main/org/insa/graph/Node.java View File

@@ -2,7 +2,7 @@ package org.insa.graph;
2 2
 
3 3
 import java.util.ArrayList;
4 4
 import java.util.Collections;
5
-import java.util.Iterator;
5
+import java.util.List;
6 6
 
7 7
 /**
8 8
  * Class representing a Node in a {@link Graph}.
@@ -13,7 +13,7 @@ import java.util.Iterator;
13 13
  * Nodes are comparable based on their ID.
14 14
  *
15 15
  */
16
-public final class Node implements Comparable<Node>, Iterable<Arc> {
16
+public final class Node implements Comparable<Node> {
17 17
 
18 18
     /**
19 19
      * Link the two given nodes with one or two arcs (depending on roadInformation),
@@ -107,9 +107,13 @@ public final class Node implements Comparable<Node>, Iterable<Arc> {
107 107
         return !this.successors.isEmpty();
108 108
     }
109 109
 
110
-    @Override
111
-    public Iterator<Arc> iterator() {
112
-        return Collections.unmodifiableList(this.successors).iterator();
110
+    /**
111
+     * @return List of successors of this node (unmodifiable list).
112
+     * 
113
+     * @see Collections#unmodifiableList(List)
114
+     */
115
+    public List<Arc> getSuccessors() {
116
+        return Collections.unmodifiableList(this.successors);
113 117
     }
114 118
 
115 119
     /**

+ 1
- 1
src/main/org/insa/graphics/NodesInputPanel.java View File

@@ -65,7 +65,7 @@ public class NodesInputPanel extends JPanel
65 65
         public Node findClosestNode(Point point) {
66 66
             Node minNode = null;
67 67
             double minDis = Double.POSITIVE_INFINITY;
68
-            for (Node node: graph) {
68
+            for (Node node: graph.getNodes()) {
69 69
                 double dlon = point.getLongitude() - node.getPoint().getLongitude();
70 70
                 double dlat = point.getLatitude() - node.getPoint().getLatitude();
71 71
                 double dis = dlon * dlon + dlat * dlat; // No need to square

+ 2
- 2
src/main/org/insa/graphics/drawing/components/BasicDrawing.java View File

@@ -679,8 +679,8 @@ public class BasicDrawing extends JPanel implements Drawing {
679 679
         this.removeMouseMotionListener(zoomAndPanListener);
680 680
         this.removeMouseWheelListener(zoomAndPanListener);
681 681
 
682
-        for (Node node: graph) {
683
-            for (Arc arc: node) {
682
+        for (Node node: graph.getNodes()) {
683
+            for (Arc arc: node.getSuccessors()) {
684 684
                 // Draw arcs only if there are one-way arcs or if origin is lower than
685 685
                 // destination, avoid drawing two-ways arc twice.
686 686
                 if (arc.getRoadInformation().isOneWay()

+ 1
- 1
src/test/org/insa/graph/GraphTest.java View File

@@ -62,7 +62,7 @@ public class GraphTest {
62 62
      */
63 63
     private List<Arc> getArcsBetween(Node a, Node b) {
64 64
         List<Arc> arcs = new ArrayList<>();
65
-        for (Arc arc: a) {
65
+        for (Arc arc: a.getSuccessors()) {
66 66
             if (arc.getDestination().equals(b)) {
67 67
                 arcs.add(arc);
68 68
             }

+ 1
- 1
src/test/org/insa/graph/NodeTest.java View File

@@ -54,7 +54,7 @@ public class NodeTest {
54 54
      * @return The first arc between from a to b, or null.
55 55
      */
56 56
     private Arc getFirstArcBetween(Node a, Node b) {
57
-        for (Arc arc: a) {
57
+        for (Arc arc: a.getSuccessors()) {
58 58
             if (arc.getDestination().equals(b)) {
59 59
                 return arc;
60 60
             }

Loading…
Cancel
Save