dijkstra: functional

This commit is contained in:
Clement Lacau 2024-04-20 19:18:04 +02:00
parent 6e4c4de7dd
commit 26e5d5dac9

View file

@ -1,7 +1,6 @@
package org.insa.graphs.algorithm.shortestpath;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import org.insa.graphs.algorithm.AbstractSolution.Status;
@ -23,47 +22,50 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
ShortestPathSolution solution = null;
// TODO:
// Heap of "sommets"
BinaryHeap<Label> labels = new BinaryHeap<Label>(); // change to a comparable type
// List of sommets, but with type Label
ArrayList<Label> labels = new ArrayList<Label>();
// Heap of sommets
BinaryHeap<Label> tas = new BinaryHeap<Label>();
Graph graph = data.getGraph();
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;
// Notify observers about the first event (origin processed).
notifyOriginProcessed(data.getOrigin());
// Init Dijkstra
//ArrayList<Label> labels = new ArrayList<Label>();
for (Node node : graph.getNodes()) {
labels.insert(new Label(node));
labels.add(new Label(node));
}
// Nodes set
for (Label label : labels.array) {
label.marked = false;
label.setPathCost(Float.MAX_VALUE);
label.parentNode = null;
}
// Origin set
Label s = labels.array.get(0);
s.setPathCost(0);
labels.insert(s);
boolean trouve = false; // TODO : breaking condition
Label s = new Label(data.getOrigin());
// Add origin in the heap
//Label s = origin;//labels.get(0);
s.setPathCost(0);
tas.insert(s);
// On considère le sommet x à chaque itération
Label x;
while (!labels.isEmpty() && !trouve) {
x = labels.deleteMin();
while (!tas.isEmpty()) {
x = tas.deleteMin();
x.mark();
// y shall be all the successors of x
// A marked node is considered as reached
notifyNodeReached(x.getNode());
// We create a list of node successors of x, instead of a list of Arcs.
float arc_cost = 0;
for (Label y : labels.array) {
if (y.getParentNode() == x.getNode()) {
if (y.isMarked()) {
ArrayList<Node> successors = new ArrayList<Node>();
for (Arc k : x.getNode().getSuccessors()) {
successors.add(k.getDestination());
}
// We loop only on the successors of the node with this for and if.
for (Label y : labels) {
if (successors.contains(y.getNode())) {
if (!y.isMarked()) {
// This loop serves to get the lentgh of the arc as
// we know its origin and destination
for (Arc arc : x.getNode().getSuccessors()) {
@ -71,11 +73,21 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
arc_cost = arc.getLength();
}
}
float new_cost = x.getCost() + arc_cost;
if (y.getCost() > new_cost) {
y.setPathCost(new_cost);
labels.insert(y);
float possible_path_cost = x.getCost() + arc_cost;
if (y.getCost() > possible_path_cost) {
// Mise à jour du label
y.setPathCost(possible_path_cost);
y.setParentNode(x.getNode());
// Si y est déjà dans le tas, on va l'update, pas l'insérer
// On a pas de fonction update donc on fait un remove puis insert
if (tas.array.contains(y)){
tas.remove(y);
tas.insert(y);
}
// il n'y est pas déjà on l'insère
else {
tas.insert(y);
}
}
}
}
@ -84,27 +96,34 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
// Create the path ...
ArrayList<Arc> arcs_path = new ArrayList<>();
Label dest = labels.findMin();
for (Label label : labels.array) {
if (label.getNode() == data.getDestination()){
dest = label;
}
}
Node current = dest.getParentNode();
while (current != null) {
for (Arc arc : current.getSuccessors()) {
if (arc.getDestination() == dest.getNode()) {
// We will find the path using the parent nodes, from the destination to the origin
Node current_node = data.getDestination();
Label current_label = new Label(current_node);
System.out.println(current_node.getId());
while (current_node != null && current_node != data.getOrigin()) {
// Find the label matching the parent node
for (Label label : labels) {
if (label.getNode() == current_node){
current_label = label;
current_node = current_label.getParentNode();
}
}
// Knowing the parent node, get the arc between the parent and
// current node and add it to the path
if (current_node != null){
for (Arc arc : current_node.getSuccessors()) {
if (arc.getDestination().getId() == current_label.getNode().getId() ) {
arcs_path.add(arc);
}
}
for (Label label : labels.array) {
if (label.getNode() == current){
dest = label;
current = label.getParentNode();
break;
}
}
}
}
notifyDestinationReached(data.getDestination());
// Reverse the path...
Collections.reverse(arcs_path);
@ -112,6 +131,10 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
// Create the final solution.
solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcs_path));
/*System.out.println("watch here" + "\n");
for (Arc a : arcs_path){
System.out.println(a.getOrigin().getId() + " --- " + a.getDestination().getId() + "\n");
}*/
return solution;
}