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 BellmanFordAlgorithm(ShortestPathData data) {
|
||||
super(data);
|
||||
}
|
||||
public BellmanFordAlgorithm(ShortestPathData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ShortestPathSolution doRun() {
|
||||
@Override
|
||||
protected ShortestPathSolution doRun() {
|
||||
|
||||
// Retrieve the graph.
|
||||
ShortestPathData data = getInputData();
|
||||
Graph graph = data.getGraph();
|
||||
// Retrieve the graph.
|
||||
ShortestPathData data = getInputData();
|
||||
Graph graph = data.getGraph();
|
||||
|
||||
final int nbNodes = graph.size();
|
||||
final int nbNodes = graph.size();
|
||||
|
||||
// Initialize array of distances.
|
||||
double[] distances = new double[nbNodes];
|
||||
Arrays.fill(distances, Double.POSITIVE_INFINITY);
|
||||
distances[data.getOrigin().getId()] = 0;
|
||||
// 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());
|
||||
// Notify observers about the first event (origin processed).
|
||||
notifyOriginProcessed(data.getOrigin());
|
||||
|
||||
// Initialize array of predecessors.
|
||||
Arc[] predecessorArcs = new Arc[nbNodes];
|
||||
// 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) {
|
||||
for (Arc arc : node) {
|
||||
// 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;
|
||||
}
|
||||
// Small test to check allowed roads...
|
||||
if (!data.isAllowed(arc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Retrieve weight of the arc.
|
||||
double w = data.getCost(arc);
|
||||
double oldDistance = distances[arc.getDestination().getId()];
|
||||
double newDistance = distances[node.getId()] + w;
|
||||
// Retrieve weight of the arc.
|
||||
double w = data.getCost(arc);
|
||||
double oldDistance = distances[arc.getDestination().getId()];
|
||||
double newDistance = distances[node.getId()] + w;
|
||||
|
||||
if (Double.isInfinite(oldDistance) && Double.isFinite(newDistance)) {
|
||||
notifyNodeReached(arc.getDestination());
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
ShortestPathSolution solution = null;
|
||||
|
||||
// Destination has no predecessor, the solution is infeasible...
|
||||
if (predecessorArcs[data.getDestination().getId()] == null) {
|
||||
solution = new ShortestPathSolution(data, Status.INFEASIBLE);
|
||||
} else {
|
||||
// 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());
|
||||
// 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()];
|
||||
}
|
||||
// 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);
|
||||
// Reverse the path...
|
||||
Collections.reverse(arcs);
|
||||
|
||||
// Create the final solution.
|
||||
solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcs));
|
||||
}
|
||||
// Create the final solution.
|
||||
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>());
|
||||
}
|
||||
|
||||
for (Node node: getInputData().getGraph()) {
|
||||
for (Arc arc: node) {
|
||||
for (Node node: getInputData().getGraph().getNodes()) {
|
||||
for (Arc arc: node.getSuccessors()) {
|
||||
res.get(node.getId()).add(arc.getDestination().getId());
|
||||
if (arc.getRoadInformation().isOneWay()) {
|
||||
res.get(arc.getDestination().getId()).add(node.getId());
|
||||
|
@ -2,7 +2,6 @@ package org.insa.graph;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
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.
|
||||
*
|
||||
*/
|
||||
public final class Graph implements Iterable<Node> {
|
||||
public final class Graph {
|
||||
|
||||
// Map identifier.
|
||||
private final String mapId;
|
||||
@ -68,9 +67,13 @@ public final class Graph implements Iterable<Node> {
|
||||
return this.nodes.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Node> iterator() {
|
||||
return this.nodes.iterator();
|
||||
/**
|
||||
* @return List of nodes in this graph (unmodifiable).
|
||||
*
|
||||
* @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) {
|
||||
Node orig = trNodes.get(node.getId());
|
||||
for (Arc arc: node) {
|
||||
for (Arc arc: node.getSuccessors()) {
|
||||
if (arc.getRoadInformation().isOneWay()) {
|
||||
Node dest = trNodes.get(arc.getDestination().getId());
|
||||
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.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class representing a Node in a {@link Graph}.
|
||||
@ -13,7 +13,7 @@ import java.util.Iterator;
|
||||
* 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),
|
||||
@ -107,9 +107,13 @@ public final class Node implements Comparable<Node>, Iterable<Arc> {
|
||||
return !this.successors.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Arc> iterator() {
|
||||
return Collections.unmodifiableList(this.successors).iterator();
|
||||
/**
|
||||
* @return List of successors of this node (unmodifiable list).
|
||||
*
|
||||
* @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) {
|
||||
Node minNode = null;
|
||||
double minDis = Double.POSITIVE_INFINITY;
|
||||
for (Node node: graph) {
|
||||
for (Node node: graph.getNodes()) {
|
||||
double dlon = point.getLongitude() - node.getPoint().getLongitude();
|
||||
double dlat = point.getLatitude() - node.getPoint().getLatitude();
|
||||
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.removeMouseWheelListener(zoomAndPanListener);
|
||||
|
||||
for (Node node: graph) {
|
||||
for (Arc arc: node) {
|
||||
for (Node node: graph.getNodes()) {
|
||||
for (Arc arc: node.getSuccessors()) {
|
||||
// Draw arcs only if there are one-way arcs or if origin is lower than
|
||||
// destination, avoid drawing two-ways arc twice.
|
||||
if (arc.getRoadInformation().isOneWay()
|
||||
|
@ -62,7 +62,7 @@ public class GraphTest {
|
||||
*/
|
||||
private List<Arc> getArcsBetween(Node a, Node b) {
|
||||
List<Arc> arcs = new ArrayList<>();
|
||||
for (Arc arc: a) {
|
||||
for (Arc arc: a.getSuccessors()) {
|
||||
if (arc.getDestination().equals(b)) {
|
||||
arcs.add(arc);
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class NodeTest {
|
||||
* @return The first arc between from a to b, or null.
|
||||
*/
|
||||
private Arc getFirstArcBetween(Node a, Node b) {
|
||||
for (Arc arc: a) {
|
||||
for (Arc arc: a.getSuccessors()) {
|
||||
if (arc.getDestination().equals(b)) {
|
||||
return arc;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user