algorithme de dijkstra + commentaires
This commit is contained in:
parent
4b9dbd1b30
commit
dab81d1bca
5 changed files with 223 additions and 32 deletions
|
@ -1,17 +1,121 @@
|
|||
package org.insa.graphs.algorithm.shortestpath;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
import org.insa.graphs.algorithm.AbstractSolution.Status;
|
||||
import org.insa.graphs.algorithm.utils.BinaryHeap;
|
||||
import org.insa.graphs.model.Arc;
|
||||
import org.insa.graphs.model.Graph;
|
||||
import org.insa.graphs.model.Node;
|
||||
import org.insa.graphs.model.Path;
|
||||
|
||||
public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||
|
||||
public DijkstraAlgorithm(ShortestPathData data) {
|
||||
super(data);
|
||||
}
|
||||
public DijkstraAlgorithm(ShortestPathData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ShortestPathSolution doRun() {
|
||||
final ShortestPathData data = getInputData();
|
||||
ShortestPathSolution solution = null;
|
||||
// TODO:
|
||||
return solution;
|
||||
}
|
||||
@Override
|
||||
protected ShortestPathSolution doRun() {
|
||||
final ShortestPathData data = getInputData();
|
||||
Graph graph = data.getGraph();
|
||||
|
||||
final int nbNodes = graph.size();
|
||||
|
||||
// Create the heap and a static array to store the labels
|
||||
org.insa.graphs.algorithm.utils.PriorityQueue<Label> labelsHeap = new BinaryHeap<>();
|
||||
Label labelsList[] = new Label[nbNodes];
|
||||
Arrays.fill(labelsList, null);
|
||||
|
||||
//Put the origin in the heap
|
||||
Node origin = data.getOrigin();
|
||||
labelsList[origin.getId()] = new Label(data.getOrigin(), 0, null);
|
||||
labelsHeap.insert(new Label(origin, 0, null));
|
||||
|
||||
// Notify observers about the first event (origin processed).
|
||||
notifyOriginProcessed(data.getOrigin());
|
||||
|
||||
// Initialize array of predecessors.
|
||||
Arc[] predecessorArcs = new Arc[nbNodes];
|
||||
|
||||
Label current, next;
|
||||
|
||||
// While the heap has elements
|
||||
while (!labelsHeap.isEmpty()) {
|
||||
|
||||
// Remove the min
|
||||
current = labelsHeap.findMin();
|
||||
try {
|
||||
labelsHeap.remove(current);
|
||||
} catch (Exception e) {
|
||||
System.out.println("fatal error");
|
||||
}
|
||||
|
||||
current.setMark();
|
||||
|
||||
// Iterate over the arc of the removed element
|
||||
for (Arc arc : graph.get(current.getCurrent().getId()).getSuccessors()) {
|
||||
if (!data.isAllowed(arc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
next = labelsList[arc.getDestination().getId()];
|
||||
|
||||
//If the destination of an arc does not exist or is not marked
|
||||
if ( next != null && next.isMarked()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Either create it or check if the associated cost can be reduced
|
||||
if (next == null) {
|
||||
next = new Label(arc.getDestination(),current.getCost() + data.getCost(arc), arc);
|
||||
|
||||
labelsList[arc.getDestination().getId()] = next;
|
||||
labelsHeap.insert(next);
|
||||
notifyNodeReached(arc.getDestination());
|
||||
|
||||
}else{
|
||||
if (next.getCost() > current.getCost() + data.getCost(arc)) {
|
||||
next.setCost(current.getCost() + data.getCost(arc));
|
||||
next.setFather(arc);
|
||||
notifyNodeReached(arc.getDestination());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ShortestPathSolution solution = null;
|
||||
|
||||
//Check if the destination has been reached from the source
|
||||
if (labelsList[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 = labelsList[data.getDestination().getId()].getFather();
|
||||
while (arc != null) {
|
||||
arcs.add(arc);
|
||||
arc = labelsList[arc.getOrigin().getId()].getFather();
|
||||
}
|
||||
|
||||
// Reverse the path...
|
||||
Collections.reverse(arcs);
|
||||
|
||||
// Create the final solution.
|
||||
solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcs));
|
||||
}
|
||||
|
||||
return solution;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package org.insa.graphs.algorithm.shortestpath;
|
||||
|
||||
import org.insa.graphs.model.Arc;
|
||||
import org.insa.graphs.model.Node;
|
||||
import org.insa.graphs.model.Path;
|
||||
|
||||
public class Label implements Comparable<Label>{
|
||||
private Node sommetCourant;
|
||||
private boolean marque;
|
||||
private double cout;
|
||||
private Arc pere;
|
||||
|
||||
public Label(Node sommetCourant, double cout, Arc pere) {
|
||||
this.sommetCourant = sommetCourant;
|
||||
this.marque = false;
|
||||
this.cout = cout;
|
||||
this.pere = pere;
|
||||
}
|
||||
|
||||
public Node getCurrent() {
|
||||
return this.sommetCourant;
|
||||
}
|
||||
public double getCost() {
|
||||
return this.cout;
|
||||
}
|
||||
public Arc getFather() {
|
||||
return this.pere;
|
||||
}
|
||||
|
||||
public void setMark() {
|
||||
this.marque = true;
|
||||
}
|
||||
|
||||
public void setFather(Arc father) {
|
||||
this.pere = father;
|
||||
}
|
||||
|
||||
public void setCost(double cost) {
|
||||
this.cout = cost;
|
||||
}
|
||||
|
||||
public boolean isMarked() {
|
||||
return this.marque;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ""+this.sommetCourant.getId();
|
||||
}
|
||||
@Override
|
||||
public int compareTo(Label o) {
|
||||
return (int) (this.getCost()-o.getCost() ) ;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
package org.insa.graphs.algorithm.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Implements a binary heap containing elements of type E.
|
||||
|
@ -11,6 +15,9 @@ import java.util.ArrayList;
|
|||
* @author Mark Allen Weiss
|
||||
* @author DLB
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
||||
|
||||
// Number of elements in heap.
|
||||
|
@ -50,6 +57,7 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
|||
else {
|
||||
this.array.set(index, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,13 +144,20 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
|||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Remove the element x from the array if it exists
|
||||
* Raise ElementNotFoundException otherwise
|
||||
*/
|
||||
public void remove(E x) throws ElementNotFoundException {
|
||||
|
||||
|
||||
if(this.isEmpty()){
|
||||
throw new ElementNotFoundException(x);
|
||||
}
|
||||
|
||||
int index = -1;
|
||||
|
||||
//Iterate over the array and check if the x exists
|
||||
for(int i=0; i<this.currentSize;i++) {
|
||||
if(this.array.get(i).equals(x)) {
|
||||
index = i;
|
||||
|
@ -154,8 +169,10 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
|||
throw new ElementNotFoundException(x);
|
||||
}
|
||||
|
||||
//If it exists, it is replaced by the "last" element
|
||||
E lastItem = this.array.get(--this.currentSize);
|
||||
this.arraySet(index, lastItem);
|
||||
//The switched element is then sorted
|
||||
this.percolateDown(index);
|
||||
this.percolateUp(index);
|
||||
|
||||
|
|
|
@ -50,28 +50,38 @@ public class Launch {
|
|||
final String mapName = "/Users/Kevin/Desktop/programmation/java_files/Maps/europe/france/insa.mapgr";
|
||||
final String pathName = "/Users/Kevin/Desktop/programmation/java_files/Paths/path_fr31insa_rangueil_insa.path";
|
||||
|
||||
// Create a graph reader.
|
||||
final GraphReader reader = new BinaryGraphReader(
|
||||
new DataInputStream(new BufferedInputStream(new FileInputStream(mapName))));
|
||||
|
||||
// TODO: Read the graph.
|
||||
final Graph graph = reader.read();
|
||||
final Graph graph;
|
||||
|
||||
// Create the drawing:
|
||||
final Drawing drawing = createDrawing();
|
||||
final Drawing drawing;
|
||||
|
||||
// TODO: Draw the graph on the drawing.
|
||||
drawing.drawGraph(graph);
|
||||
|
||||
try (GraphReader reader = new BinaryGraphReader(new DataInputStream(
|
||||
new BufferedInputStream(new FileInputStream(mapName))))) {
|
||||
|
||||
// TODO: Read the graph.
|
||||
graph = reader.read();
|
||||
|
||||
// Create the drawing:
|
||||
drawing = createDrawing();
|
||||
|
||||
// TODO: Draw the graph on the drawing.
|
||||
drawing.drawGraph(graph);
|
||||
}
|
||||
|
||||
// TODO: Create a PathReader.
|
||||
final PathReader pathReader = new BinaryPathReader(
|
||||
new DataInputStream( new BufferedInputStream(new FileInputStream(pathName))));
|
||||
try (PathReader pathReader = new BinaryPathReader(
|
||||
new DataInputStream( new BufferedInputStream(new FileInputStream(pathName))))) {
|
||||
|
||||
// TODO: Read the path.
|
||||
final Path path = pathReader.readPath(graph);
|
||||
// TODO: Read the path.
|
||||
final Path path = pathReader.readPath(graph);
|
||||
|
||||
// TODO: Draw the path.
|
||||
drawing.drawPath(path);
|
||||
// TODO: Draw the path.
|
||||
drawing.drawPath(path);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -33,10 +33,6 @@ public class Path {
|
|||
public static Path createFastestPathFromNodes(Graph graph, List<Node> nodes)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
Arc currentArc = null;
|
||||
List<Arc> arcs = new ArrayList<Arc>();
|
||||
double travelTime = 9999;
|
||||
|
||||
if(nodes.size() == 0) {
|
||||
return new Path(graph);
|
||||
}
|
||||
|
@ -44,6 +40,11 @@ public class Path {
|
|||
return new Path(graph, nodes.get(0) );
|
||||
}
|
||||
|
||||
Arc currentArc = null;
|
||||
List<Arc> arcs = new ArrayList<Arc>();
|
||||
double travelTime = 9999;
|
||||
|
||||
//Get the arc with the minimum travel time for each node
|
||||
for(int i=0; i<nodes.size()-1;i++) {
|
||||
for(Arc a : nodes.get(i).getSuccessors()) {
|
||||
if(a.getMinimumTravelTime() < travelTime
|
||||
|
@ -52,6 +53,7 @@ public class Path {
|
|||
travelTime = a.getMinimumTravelTime();
|
||||
}
|
||||
}
|
||||
//raise an exception if two consecutive arcs are not linked
|
||||
if(currentArc == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
@ -78,9 +80,7 @@ public class Path {
|
|||
public static Path createShortestPathFromNodes(Graph graph, List<Node> nodes)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
Arc currentArc = null;
|
||||
List<Arc> arcs = new ArrayList<Arc>();
|
||||
float distanceMin = 9999;
|
||||
|
||||
|
||||
if(nodes.size() == 0) {
|
||||
return new Path(graph);
|
||||
|
@ -89,6 +89,11 @@ public class Path {
|
|||
return new Path(graph, nodes.get(0) );
|
||||
}
|
||||
|
||||
Arc currentArc = null;
|
||||
List<Arc> arcs = new ArrayList<Arc>();
|
||||
float distanceMin = 9999;
|
||||
|
||||
//Get the arc with the minimal distance for each node
|
||||
for(int i=0; i<nodes.size()-1;i++) {
|
||||
for(Arc a : nodes.get(i).getSuccessors()) {
|
||||
if(a.getLength() < distanceMin
|
||||
|
@ -97,6 +102,7 @@ public class Path {
|
|||
distanceMin = a.getLength();
|
||||
}
|
||||
}
|
||||
//raise an exception if two consecutive arcs are not linked
|
||||
if(currentArc == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue