Add getNodes() and getSuccessors() methods and remove iterable from Graph and Node.
This commit is contained in:
parent
71a0085d59
commit
d8470055f1
@ -12,88 +12,89 @@ import org.insa.graph.Path;
|
|||||||
|
|
||||||
public class BellmanFordAlgorithm extends ShortestPathAlgorithm {
|
public class BellmanFordAlgorithm extends ShortestPathAlgorithm {
|
||||||
|
|
||||||
public BellmanFordAlgorithm(ShortestPathData data) {
|
public BellmanFordAlgorithm(ShortestPathData data) {
|
||||||
super(data);
|
super(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ShortestPathSolution doRun() {
|
protected ShortestPathSolution doRun() {
|
||||||
|
|
||||||
// Retrieve the graph.
|
// Retrieve the graph.
|
||||||
ShortestPathData data = getInputData();
|
ShortestPathData data = getInputData();
|
||||||
Graph graph = data.getGraph();
|
Graph graph = data.getGraph();
|
||||||
|
|
||||||
final int nbNodes = graph.size();
|
final int nbNodes = graph.size();
|
||||||
|
|
||||||
// Initialize array of distances.
|
// Initialize array of distances.
|
||||||
double[] distances = new double[nbNodes];
|
double[] distances = new double[nbNodes];
|
||||||
Arrays.fill(distances, Double.POSITIVE_INFINITY);
|
Arrays.fill(distances, Double.POSITIVE_INFINITY);
|
||||||
distances[data.getOrigin().getId()] = 0;
|
distances[data.getOrigin().getId()] = 0;
|
||||||
|
|
||||||
// Notify observers about the first event (origin processed).
|
// Notify observers about the first event (origin processed).
|
||||||
notifyOriginProcessed(data.getOrigin());
|
notifyOriginProcessed(data.getOrigin());
|
||||||
|
|
||||||
// Initialize array of predecessors.
|
// Initialize array of predecessors.
|
||||||
Arc[] predecessorArcs = new Arc[nbNodes];
|
Arc[] predecessorArcs = new Arc[nbNodes];
|
||||||
|
|
||||||
// Actual algorithm, we will assume the graph does not contain negative
|
// Actual algorithm, we will assume the graph does not contain negative
|
||||||
// cycle...
|
// cycle...
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (int i = 0; !found && i < nbNodes; ++i) {
|
for (int i = 0; !found && i < nbNodes; ++i) {
|
||||||
found = true;
|
found = true;
|
||||||
for (Node node : graph) {
|
for (Node node: graph.getNodes()) {
|
||||||
for (Arc arc : node) {
|
for (Arc arc: node.getSuccessors()) {
|
||||||
|
|
||||||
// Small test to check allowed roads...
|
// Small test to check allowed roads...
|
||||||
if (!data.isAllowed(arc)) {
|
if (!data.isAllowed(arc)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve weight of the arc.
|
// Retrieve weight of the arc.
|
||||||
double w = data.getCost(arc);
|
double w = data.getCost(arc);
|
||||||
double oldDistance = distances[arc.getDestination().getId()];
|
double oldDistance = distances[arc.getDestination().getId()];
|
||||||
double newDistance = distances[node.getId()] + w;
|
double newDistance = distances[node.getId()] + w;
|
||||||
|
|
||||||
if (Double.isInfinite(oldDistance) && Double.isFinite(newDistance)) {
|
if (Double.isInfinite(oldDistance) && Double.isFinite(newDistance)) {
|
||||||
notifyNodeReached(arc.getDestination());
|
notifyNodeReached(arc.getDestination());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if new distances would be better, if so update...
|
// Check if new distances would be better, if so update...
|
||||||
if (newDistance < oldDistance) {
|
if (newDistance < oldDistance) {
|
||||||
found = false;
|
found = false;
|
||||||
distances[arc.getDestination().getId()] = distances[node.getId()] + w;
|
distances[arc.getDestination().getId()] = distances[node.getId()] + w;
|
||||||
predecessorArcs[arc.getDestination().getId()] = arc;
|
predecessorArcs[arc.getDestination().getId()] = arc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShortestPathSolution solution = null;
|
ShortestPathSolution solution = null;
|
||||||
|
|
||||||
// Destination has no predecessor, the solution is infeasible...
|
// Destination has no predecessor, the solution is infeasible...
|
||||||
if (predecessorArcs[data.getDestination().getId()] == null) {
|
if (predecessorArcs[data.getDestination().getId()] == null) {
|
||||||
solution = new ShortestPathSolution(data, Status.INFEASIBLE);
|
solution = new ShortestPathSolution(data, Status.INFEASIBLE);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
// The destination has been found, notify the observers.
|
// The destination has been found, notify the observers.
|
||||||
notifyDestinationReached(data.getDestination());
|
notifyDestinationReached(data.getDestination());
|
||||||
|
|
||||||
// Create the path from the array of predecessors...
|
// Create the path from the array of predecessors...
|
||||||
ArrayList<Arc> arcs = new ArrayList<>();
|
ArrayList<Arc> arcs = new ArrayList<>();
|
||||||
Arc arc = predecessorArcs[data.getDestination().getId()];
|
Arc arc = predecessorArcs[data.getDestination().getId()];
|
||||||
while (arc != null) {
|
while (arc != null) {
|
||||||
arcs.add(arc);
|
arcs.add(arc);
|
||||||
arc = predecessorArcs[arc.getOrigin().getId()];
|
arc = predecessorArcs[arc.getOrigin().getId()];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverse the path...
|
// Reverse the path...
|
||||||
Collections.reverse(arcs);
|
Collections.reverse(arcs);
|
||||||
|
|
||||||
// Create the final solution.
|
// Create the final solution.
|
||||||
solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcs));
|
solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcs));
|
||||||
}
|
}
|
||||||
|
|
||||||
return solution;
|
return solution;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -77,8 +77,8 @@ public class WeaklyConnectedComponentsAlgorithm
|
|||||||
res.add(new HashSet<Integer>());
|
res.add(new HashSet<Integer>());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Node node: getInputData().getGraph()) {
|
for (Node node: getInputData().getGraph().getNodes()) {
|
||||||
for (Arc arc: node) {
|
for (Arc arc: node.getSuccessors()) {
|
||||||
res.get(node.getId()).add(arc.getDestination().getId());
|
res.get(node.getId()).add(arc.getDestination().getId());
|
||||||
if (arc.getRoadInformation().isOneWay()) {
|
if (arc.getRoadInformation().isOneWay()) {
|
||||||
res.get(arc.getDestination().getId()).add(node.getId());
|
res.get(arc.getDestination().getId()).add(node.getId());
|
||||||
|
@ -2,7 +2,6 @@ package org.insa.graph;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,7 +11,7 @@ import java.util.List;
|
|||||||
* holds a list of nodes and each node holds a list of its successors.
|
* holds a list of nodes and each node holds a list of its successors.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class Graph implements Iterable<Node> {
|
public final class Graph {
|
||||||
|
|
||||||
// Map identifier.
|
// Map identifier.
|
||||||
private final String mapId;
|
private final String mapId;
|
||||||
@ -68,9 +67,13 @@ public final class Graph implements Iterable<Node> {
|
|||||||
return this.nodes.size();
|
return this.nodes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public Iterator<Node> iterator() {
|
* @return List of nodes in this graph (unmodifiable).
|
||||||
return this.nodes.iterator();
|
*
|
||||||
|
* @see Collections#unmodifiableList(List)
|
||||||
|
*/
|
||||||
|
public List<Node> getNodes() {
|
||||||
|
return this.nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,7 +100,7 @@ public final class Graph implements Iterable<Node> {
|
|||||||
}
|
}
|
||||||
for (Node node: nodes) {
|
for (Node node: nodes) {
|
||||||
Node orig = trNodes.get(node.getId());
|
Node orig = trNodes.get(node.getId());
|
||||||
for (Arc arc: node) {
|
for (Arc arc: node.getSuccessors()) {
|
||||||
if (arc.getRoadInformation().isOneWay()) {
|
if (arc.getRoadInformation().isOneWay()) {
|
||||||
Node dest = trNodes.get(arc.getDestination().getId());
|
Node dest = trNodes.get(arc.getDestination().getId());
|
||||||
dest.addSuccessor(new ArcBackward(new ArcForward(orig, dest, arc.getLength(),
|
dest.addSuccessor(new ArcBackward(new ArcForward(orig, dest, arc.getLength(),
|
||||||
|
@ -2,7 +2,7 @@ package org.insa.graph;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing a Node in a {@link Graph}.
|
* Class representing a Node in a {@link Graph}.
|
||||||
@ -13,7 +13,7 @@ import java.util.Iterator;
|
|||||||
* Nodes are comparable based on their ID.
|
* Nodes are comparable based on their ID.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class Node implements Comparable<Node>, Iterable<Arc> {
|
public final class Node implements Comparable<Node> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link the two given nodes with one or two arcs (depending on roadInformation),
|
* 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> {
|
|||||||
return !this.successors.isEmpty();
|
return !this.successors.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public Iterator<Arc> iterator() {
|
* @return List of successors of this node (unmodifiable list).
|
||||||
return Collections.unmodifiableList(this.successors).iterator();
|
*
|
||||||
|
* @see Collections#unmodifiableList(List)
|
||||||
|
*/
|
||||||
|
public List<Arc> getSuccessors() {
|
||||||
|
return Collections.unmodifiableList(this.successors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,7 +65,7 @@ public class NodesInputPanel extends JPanel
|
|||||||
public Node findClosestNode(Point point) {
|
public Node findClosestNode(Point point) {
|
||||||
Node minNode = null;
|
Node minNode = null;
|
||||||
double minDis = Double.POSITIVE_INFINITY;
|
double minDis = Double.POSITIVE_INFINITY;
|
||||||
for (Node node: graph) {
|
for (Node node: graph.getNodes()) {
|
||||||
double dlon = point.getLongitude() - node.getPoint().getLongitude();
|
double dlon = point.getLongitude() - node.getPoint().getLongitude();
|
||||||
double dlat = point.getLatitude() - node.getPoint().getLatitude();
|
double dlat = point.getLatitude() - node.getPoint().getLatitude();
|
||||||
double dis = dlon * dlon + dlat * dlat; // No need to square
|
double dis = dlon * dlon + dlat * dlat; // No need to square
|
||||||
|
@ -679,8 +679,8 @@ public class BasicDrawing extends JPanel implements Drawing {
|
|||||||
this.removeMouseMotionListener(zoomAndPanListener);
|
this.removeMouseMotionListener(zoomAndPanListener);
|
||||||
this.removeMouseWheelListener(zoomAndPanListener);
|
this.removeMouseWheelListener(zoomAndPanListener);
|
||||||
|
|
||||||
for (Node node: graph) {
|
for (Node node: graph.getNodes()) {
|
||||||
for (Arc arc: node) {
|
for (Arc arc: node.getSuccessors()) {
|
||||||
// Draw arcs only if there are one-way arcs or if origin is lower than
|
// Draw arcs only if there are one-way arcs or if origin is lower than
|
||||||
// destination, avoid drawing two-ways arc twice.
|
// destination, avoid drawing two-ways arc twice.
|
||||||
if (arc.getRoadInformation().isOneWay()
|
if (arc.getRoadInformation().isOneWay()
|
||||||
|
@ -62,7 +62,7 @@ public class GraphTest {
|
|||||||
*/
|
*/
|
||||||
private List<Arc> getArcsBetween(Node a, Node b) {
|
private List<Arc> getArcsBetween(Node a, Node b) {
|
||||||
List<Arc> arcs = new ArrayList<>();
|
List<Arc> arcs = new ArrayList<>();
|
||||||
for (Arc arc: a) {
|
for (Arc arc: a.getSuccessors()) {
|
||||||
if (arc.getDestination().equals(b)) {
|
if (arc.getDestination().equals(b)) {
|
||||||
arcs.add(arc);
|
arcs.add(arc);
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ public class NodeTest {
|
|||||||
* @return The first arc between from a to b, or null.
|
* @return The first arc between from a to b, or null.
|
||||||
*/
|
*/
|
||||||
private Arc getFirstArcBetween(Node a, Node b) {
|
private Arc getFirstArcBetween(Node a, Node b) {
|
||||||
for (Arc arc: a) {
|
for (Arc arc: a.getSuccessors()) {
|
||||||
if (arc.getDestination().equals(b)) {
|
if (arc.getDestination().equals(b)) {
|
||||||
return arc;
|
return arc;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user