Dijkstra fini
This commit is contained in:
parent
61f932cc65
commit
cd0803a07b
4 changed files with 242 additions and 14 deletions
|
@ -1,5 +1,16 @@
|
||||||
package org.insa.graphs.algorithm.shortestpath;
|
package org.insa.graphs.algorithm.shortestpath;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import org.insa.graphs.algorithm.AbstractSolution;
|
||||||
|
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 class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||||
|
|
||||||
public DijkstraAlgorithm(ShortestPathData data) {
|
public DijkstraAlgorithm(ShortestPathData data) {
|
||||||
|
@ -11,6 +22,81 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||||
final ShortestPathData data = getInputData();
|
final ShortestPathData data = getInputData();
|
||||||
ShortestPathSolution solution = null;
|
ShortestPathSolution solution = null;
|
||||||
// TODO:
|
// TODO:
|
||||||
|
Graph graph = data.getGraph();
|
||||||
|
List<Node> nodes = graph.getNodes();
|
||||||
|
BinaryHeap<Label> tas = new BinaryHeap<Label>();
|
||||||
|
ArrayList<Label> labels = new ArrayList<Label>();
|
||||||
|
boolean notfini = true;
|
||||||
|
|
||||||
|
for (Node n : nodes) {
|
||||||
|
labels.add(new Label(n,null));
|
||||||
|
}
|
||||||
|
|
||||||
|
Node origin = data.getOrigin();
|
||||||
|
notifyOriginProcessed(origin);
|
||||||
|
labels.get(origin.getId()).setCost(0);
|
||||||
|
tas.insert(labels.get(origin.getId()));
|
||||||
|
|
||||||
|
Label currentLabel;
|
||||||
|
while (tas.isEmpty() != true && notfini)
|
||||||
|
{
|
||||||
|
currentLabel = tas.findMin();
|
||||||
|
tas.remove(currentLabel);
|
||||||
|
Node currentNode = currentLabel.getCurrentNode();
|
||||||
|
if (currentNode == data.getDestination())
|
||||||
|
{
|
||||||
|
notfini = false;
|
||||||
|
}
|
||||||
|
labels.get(currentNode.getId()).setMark(true);
|
||||||
|
for (Arc newArc : currentNode.getSuccessors())
|
||||||
|
{
|
||||||
|
if (data.isAllowed(newArc))
|
||||||
|
{
|
||||||
|
Label destLabel = labels.get(newArc.getDestination().getId());
|
||||||
|
if (!destLabel.getMark())
|
||||||
|
{
|
||||||
|
Node destNode = destLabel.getCurrentNode();
|
||||||
|
notifyNodeReached(destNode);
|
||||||
|
Double currentCost = currentLabel.getCost();
|
||||||
|
Double destCost = destLabel.getCost();
|
||||||
|
Double arcCost = data.getCost(newArc);
|
||||||
|
if (destCost > currentCost+ arcCost)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (destCost != Double.MAX_VALUE)
|
||||||
|
{
|
||||||
|
tas.remove(destLabel);
|
||||||
|
}
|
||||||
|
destLabel.setCost(currentCost+arcCost);
|
||||||
|
destLabel.setFatherArc(newArc);
|
||||||
|
tas.insert(destLabel);
|
||||||
|
labels.set(destNode.getId(),destLabel);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notifyNodeMarked(currentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
Arc currentArc=labels.get(data.getDestination().getId()).getFatherArc();
|
||||||
|
if (currentArc == null) {
|
||||||
|
solution = new ShortestPathSolution(data, AbstractSolution.Status.INFEASIBLE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
notifyDestinationReached(data.getDestination());
|
||||||
|
|
||||||
|
ArrayList<Arc> arcs = new ArrayList<>();
|
||||||
|
while (currentArc != null) {
|
||||||
|
arcs.add(currentArc);
|
||||||
|
Arc newArc=labels.get(currentArc.getOrigin().getId()).getFatherArc();
|
||||||
|
currentArc = newArc;
|
||||||
|
}
|
||||||
|
Collections.reverse(arcs);
|
||||||
|
solution = new ShortestPathSolution(data, AbstractSolution.Status.OPTIMAL, new Path(graph, arcs));
|
||||||
|
}
|
||||||
|
|
||||||
return solution;
|
return solution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package org.insa.graphs.algorithm.shortestpath;
|
||||||
|
import org.insa.graphs.model.*;
|
||||||
|
|
||||||
|
public class Label implements Comparable<Label>
|
||||||
|
{
|
||||||
|
|
||||||
|
private Node currentNode;
|
||||||
|
private boolean mark;
|
||||||
|
private double cost;
|
||||||
|
private Arc fatherArc;
|
||||||
|
|
||||||
|
public Label(Node currentNode, Arc fatherArc)
|
||||||
|
{
|
||||||
|
this.currentNode = currentNode;
|
||||||
|
this.fatherArc = fatherArc;
|
||||||
|
this.cost = Double.MAX_VALUE;
|
||||||
|
this.mark = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCost()
|
||||||
|
{
|
||||||
|
return this.cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getMark()
|
||||||
|
{
|
||||||
|
return this.mark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Arc getFatherArc()
|
||||||
|
{
|
||||||
|
return this.fatherArc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getCurrentNode()
|
||||||
|
{
|
||||||
|
return this.currentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCost(double cout)
|
||||||
|
{
|
||||||
|
this.cost = cout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMark(boolean mark)
|
||||||
|
{
|
||||||
|
this.mark = mark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFatherArc(Arc fatherArc)
|
||||||
|
{
|
||||||
|
this.fatherArc = fatherArc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentNode(Node currentNode)
|
||||||
|
{
|
||||||
|
this.currentNode = currentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(Label label)
|
||||||
|
{
|
||||||
|
return Double.compare(getCost(), label.getCost());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -83,7 +83,6 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
||||||
|
|
||||||
this.arraySet(index, x);
|
this.arraySet(index, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal method to percolate down in the heap.
|
* Internal method to percolate down in the heap.
|
||||||
*
|
*
|
||||||
|
@ -137,7 +136,15 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(E x) throws ElementNotFoundException {
|
public void remove(E x) throws ElementNotFoundException {
|
||||||
// TODO:
|
// DONE:
|
||||||
|
int index = array.indexOf(x);
|
||||||
|
if (isEmpty() || index < 0 || index >= this.currentSize) {
|
||||||
|
throw new ElementNotFoundException(x);
|
||||||
|
}
|
||||||
|
E lastItem = this.array.get(--this.currentSize);
|
||||||
|
this.arraySet(index,lastItem);
|
||||||
|
this.percolateUp(index);
|
||||||
|
this.percolateDown(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -30,13 +30,36 @@ public class Path {
|
||||||
* @throws IllegalArgumentException If the list of nodes is not valid, i.e. two
|
* @throws IllegalArgumentException If the list of nodes is not valid, i.e. two
|
||||||
* consecutive nodes in the list are not connected in the graph.
|
* consecutive nodes in the list are not connected in the graph.
|
||||||
*
|
*
|
||||||
* @deprecated Need to be implemented.
|
|
||||||
*/
|
*/
|
||||||
public static Path createFastestPathFromNodes(Graph graph, List<Node> nodes)
|
public static Path createFastestPathFromNodes(Graph graph, List<Node> nodes)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
List<Arc> arcs = new ArrayList<Arc>();
|
List<Arc> arcs = new ArrayList<Arc>();
|
||||||
// TODO:
|
// TODO:
|
||||||
return new Path(graph, arcs);
|
if (nodes.size() == 1) {
|
||||||
|
return new Path(graph,nodes.get(0));
|
||||||
|
}else if (nodes.size() == 0) {
|
||||||
|
return new Path(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodes.size() > 1) {
|
||||||
|
Arc min = null;
|
||||||
|
double mintime = Double.MAX_VALUE;
|
||||||
|
for (int i = 0; i < nodes.size()-1; i++) {
|
||||||
|
for(Arc arc : nodes.get(i).getSuccessors()) {
|
||||||
|
if(arc.getMinimumTravelTime() < mintime && arc.getDestination().equals(nodes.get(i+1))) {
|
||||||
|
min = arc;
|
||||||
|
mintime = arc.getMinimumTravelTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (min == null){
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
arcs.add(min);
|
||||||
|
mintime = Double.MAX_VALUE;
|
||||||
|
min = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Path(graph, arcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,12 +74,37 @@ public class Path {
|
||||||
* @throws IllegalArgumentException If the list of nodes is not valid, i.e. two
|
* @throws IllegalArgumentException If the list of nodes is not valid, i.e. two
|
||||||
* consecutive nodes in the list are not connected in the graph.
|
* consecutive nodes in the list are not connected in the graph.
|
||||||
*
|
*
|
||||||
* @deprecated Need to be implemented.
|
|
||||||
*/
|
*/
|
||||||
public static Path createShortestPathFromNodes(Graph graph, List<Node> nodes)
|
public static Path createShortestPathFromNodes(Graph graph, List<Node> nodes)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
List<Arc> arcs = new ArrayList<Arc>();
|
List<Arc> arcs = new ArrayList<Arc>();
|
||||||
// TODO:
|
// TODO:
|
||||||
|
if (nodes.size() == 1) {
|
||||||
|
return new Path(graph,nodes.get(0));
|
||||||
|
}else if (nodes.size() == 0) {
|
||||||
|
return new Path(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodes.size() > 1) {
|
||||||
|
Arc min = null;
|
||||||
|
float mindistance = Float.MAX_VALUE;
|
||||||
|
|
||||||
|
for(int i=0; i<nodes.size()-1;i++) {
|
||||||
|
for(Arc arc : nodes.get(i).getSuccessors()) {
|
||||||
|
if(arc.getLength() < mindistance && arc.getDestination().equals(nodes.get(i+1))) {
|
||||||
|
min = arc;
|
||||||
|
mindistance = arc.getLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(min == null) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
arcs.add(min);
|
||||||
|
mindistance = Float.MAX_VALUE;
|
||||||
|
min = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
return new Path(graph, arcs);
|
return new Path(graph, arcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,11 +246,24 @@ public class Path {
|
||||||
*
|
*
|
||||||
* @return true if the path is valid, false otherwise.
|
* @return true if the path is valid, false otherwise.
|
||||||
*
|
*
|
||||||
* @deprecated Need to be implemented.
|
|
||||||
*/
|
*/
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
// TODO:
|
// TODO:
|
||||||
return false;
|
if (arcs.size() == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (arcs.get(0).getOrigin() != origin){
|
||||||
|
return false;
|
||||||
|
}else if (arcs.size() == 1){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < arcs.size(); i++) {
|
||||||
|
if (arcs.get(i-1).getDestination() != arcs.get(i).getOrigin()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -210,11 +271,14 @@ public class Path {
|
||||||
*
|
*
|
||||||
* @return Total length of the path (in meters).
|
* @return Total length of the path (in meters).
|
||||||
*
|
*
|
||||||
* @deprecated Need to be implemented.
|
|
||||||
*/
|
*/
|
||||||
public float getLength() {
|
public float getLength() {
|
||||||
// TODO:
|
// TODO:
|
||||||
return 0;
|
float res = 0;
|
||||||
|
for(Arc arc : this.arcs) {
|
||||||
|
res+= arc.getLength();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -225,11 +289,14 @@ public class Path {
|
||||||
* @return Time (in seconds) required to travel this path at the given speed (in
|
* @return Time (in seconds) required to travel this path at the given speed (in
|
||||||
* kilometers-per-hour).
|
* kilometers-per-hour).
|
||||||
*
|
*
|
||||||
* @deprecated Need to be implemented.
|
|
||||||
*/
|
*/
|
||||||
public double getTravelTime(double speed) {
|
public double getTravelTime(double speed) {
|
||||||
// TODO:
|
// TODO:
|
||||||
return 0;
|
double res = 0;
|
||||||
|
for (Arc arc : arcs) {
|
||||||
|
res += arc.getTravelTime(speed);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -238,11 +305,14 @@ public class Path {
|
||||||
*
|
*
|
||||||
* @return Minimum travel time to travel this path (in seconds).
|
* @return Minimum travel time to travel this path (in seconds).
|
||||||
*
|
*
|
||||||
* @deprecated Need to be implemented.
|
|
||||||
*/
|
*/
|
||||||
public double getMinimumTravelTime() {
|
public double getMinimumTravelTime() {
|
||||||
// TODO:
|
// TODO:
|
||||||
return 0;
|
double res = 0;
|
||||||
|
for (Arc arc : arcs) {
|
||||||
|
res += arc.getMinimumTravelTime();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue