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;
|
||||
|
||||
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 DijkstraAlgorithm(ShortestPathData data) {
|
||||
|
@ -9,9 +20,124 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
|||
@Override
|
||||
protected ShortestPathSolution doRun() {
|
||||
final ShortestPathData data = getInputData();
|
||||
ShortestPathSolution solution = null;
|
||||
// TODO:
|
||||
return solution;
|
||||
|
||||
int numberOfNodes = data.getGraph().size();
|
||||
|
||||
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