Fin bilan dijkstra
This commit is contained in:
parent
047a67f73a
commit
8199e93748
2 changed files with 178 additions and 3 deletions
|
@ -1,5 +1,16 @@
|
||||||
package org.insa.graphs.algorithm.shortestpath;
|
package org.insa.graphs.algorithm.shortestpath;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.insa.graphs.algorithm.AbstractInputData.Mode;
|
||||||
|
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.Label;
|
||||||
|
import org.insa.graphs.model.Node;
|
||||||
|
import org.insa.graphs.model.Path;
|
||||||
|
|
||||||
public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||||
|
|
||||||
public DijkstraAlgorithm(ShortestPathData data) {
|
public DijkstraAlgorithm(ShortestPathData data) {
|
||||||
|
@ -9,9 +20,124 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||||
@Override
|
@Override
|
||||||
protected ShortestPathSolution doRun() {
|
protected ShortestPathSolution doRun() {
|
||||||
final ShortestPathData data = getInputData();
|
final ShortestPathData data = getInputData();
|
||||||
ShortestPathSolution solution = null;
|
|
||||||
// TODO:
|
int numberOfNodes = data.getGraph().size();
|
||||||
return solution;
|
|
||||||
|
double shortestCostToDestination = Double.POSITIVE_INFINITY;
|
||||||
|
|
||||||
|
// it's the cost of the last marked node. In order to stop algorithm when it's not
|
||||||
|
// useful
|
||||||
|
double lastMarkedNodeCost = 0;
|
||||||
|
|
||||||
|
// Dijkstra Init
|
||||||
|
Label[] labels = new Label[numberOfNodes];
|
||||||
|
|
||||||
|
|
||||||
|
for(Node node : data.getGraph().getNodes()) {
|
||||||
|
labels[node.getId()] = new Label(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's set the origin cost at 0
|
||||||
|
labels[data.getOrigin().getId()].setNewCost(null, 0d);
|
||||||
|
|
||||||
|
// We need to add a binaryMinHeap to get min at each iteration
|
||||||
|
BinaryHeap<Label> minHeap = new BinaryHeap<Label>();
|
||||||
|
|
||||||
|
// We add into our binaryMinHeap the origin
|
||||||
|
minHeap.insert(labels[data.getOrigin().getId()]);
|
||||||
|
|
||||||
|
// We can start searching for the shortestPath
|
||||||
|
|
||||||
|
// We stop the algorithm when the cost of last marked point is equal to the shortest found path
|
||||||
|
// or if we searched all the graph
|
||||||
|
while(lastMarkedNodeCost < shortestCostToDestination && !minHeap.isEmpty()) {
|
||||||
|
|
||||||
|
//We get the shortest not marked label
|
||||||
|
Label minLabel = minHeap.deleteMin();
|
||||||
|
|
||||||
|
//We mark it
|
||||||
|
minLabel.setMarked();
|
||||||
|
lastMarkedNodeCost = minLabel.getCost();
|
||||||
|
|
||||||
|
//We look at their successors
|
||||||
|
for(Arc successor : minLabel.getCurrent().getSuccessors()) {
|
||||||
|
//We see if we need to update
|
||||||
|
Label label = labels[successor.getDestination().getId()];
|
||||||
|
|
||||||
|
if(!label.isMarked() ) {
|
||||||
|
|
||||||
|
//We calculate new costs
|
||||||
|
double newCost;
|
||||||
|
|
||||||
|
// If the arc can't be reached thanks to transport mode (car, bike)
|
||||||
|
// Then it's like the cost to reach it is equal to infinity
|
||||||
|
if(!data.isAllowed(successor)) {
|
||||||
|
newCost = Double.POSITIVE_INFINITY;
|
||||||
|
}
|
||||||
|
else if(data.getMode() == Mode.TIME) {
|
||||||
|
newCost = minLabel.getCost() + successor.getMinimumTravelTime();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newCost = minLabel.getCost() + successor.getLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(newCost < label.getCost()) {
|
||||||
|
//we need to update !
|
||||||
|
|
||||||
|
//if the result is finite, then we need to remove first
|
||||||
|
//on the heap
|
||||||
|
if(Double.isFinite(label.getCost())) {
|
||||||
|
minHeap.remove(label);
|
||||||
|
}
|
||||||
|
label.setNewCost(successor, newCost);
|
||||||
|
minHeap.insert(label);
|
||||||
|
|
||||||
|
//we see if we have updated the destination
|
||||||
|
|
||||||
|
if(successor.getDestination().equals(data.getDestination())) {
|
||||||
|
shortestCostToDestination = newCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Here we have calculated minimum cost to destination, or no destination is unreachable
|
||||||
|
|
||||||
|
//We see if we find something
|
||||||
|
if(labels[data.getDestination().getId()].getFather() == null) {
|
||||||
|
//here there is no route available
|
||||||
|
return new ShortestPathSolution(data, Status.INFEASIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//There is a path, let's find it
|
||||||
|
|
||||||
|
ArrayList<Arc> path = new ArrayList<Arc>();
|
||||||
|
|
||||||
|
//First arc
|
||||||
|
Arc arc = labels[data.getDestination().getId()].getFather();
|
||||||
|
|
||||||
|
while(arc != null) {
|
||||||
|
//while there is a father
|
||||||
|
//add the arc to the path
|
||||||
|
path.add(arc);
|
||||||
|
arc = labels[arc.getOrigin().getId()].getFather();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to reverse the path to get in the right order
|
||||||
|
Collections.reverse(path);
|
||||||
|
|
||||||
|
// Send the solution
|
||||||
|
return new ShortestPathSolution(data, Status.OPTIMAL, new Path(data.getGraph(), path));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package org.insa.graphs.model;
|
||||||
|
|
||||||
|
public class Label implements Comparable<Label>{
|
||||||
|
|
||||||
|
private Node current;
|
||||||
|
private boolean marked;
|
||||||
|
private double cost;
|
||||||
|
private Arc father;
|
||||||
|
|
||||||
|
|
||||||
|
public Label(Node current) {
|
||||||
|
this.current = current;
|
||||||
|
this.cost = Double.POSITIVE_INFINITY;
|
||||||
|
this.father = null;
|
||||||
|
this.marked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewCost(Arc father, double cost) {
|
||||||
|
this.father = father;
|
||||||
|
this.cost = cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setMarked() {
|
||||||
|
this.marked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMarked() {
|
||||||
|
return this.marked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCost() {
|
||||||
|
return this.cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getCurrent() {
|
||||||
|
return this.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Arc getFather() {
|
||||||
|
return this.father;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Label arg0) {
|
||||||
|
return Double.compare(this.cost, arg0.cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue