Compare commits
10 commits
DijkstraFi
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
d2a9172b7b | ||
|
60a9d2e296 | ||
|
66782dd9c6 | ||
4e73e48272 | |||
810c66710a | |||
|
2d43e8cb47 | ||
|
47150a44b1 | ||
|
f023a2ae70 | ||
|
d46ea7fcb4 | ||
|
8168b86d09 |
20 changed files with 516 additions and 142 deletions
|
@ -7,4 +7,5 @@
|
|||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="11" project-jdk-type="JavaSDK" />
|
||||
</project>
|
77
DeLorean.java
Normal file
77
DeLorean.java
Normal file
|
@ -0,0 +1,77 @@
|
|||
// pseudo code du rapport sur le problme ouvert
|
||||
|
||||
|
||||
public class DeLoreanShortestPath extends ShortestPathAlgorithm {
|
||||
public DijkstraAlgorithm(ShortestPathData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
ShortestPathSolution solution;
|
||||
|
||||
// on pourra par exemple mettre le graphe des stations dans data
|
||||
final ShortestPathData data = getInputData();
|
||||
Graph gr = data.getGraph();
|
||||
StationGraph grS = data.getStationGraph();
|
||||
double maximumDist = ... //(ici 200000, on pourrait passer cette variable dans data puisque certains voitures n'auront pas la même autonomie)
|
||||
|
||||
/*On part du principe ici que le coût en temps prend déjà en compte les 10 minutes de rechargement. Il suffirait si ce n'est pas le cas de regarder si la destination de l'arc est la destination finale et si ce n'est pas le cas de rajouter 10 au coût temporel*/
|
||||
|
||||
// on récupère la destination et l'origine
|
||||
NodeStation nodeA = getNodeStationFromNode(...)
|
||||
NodeStation nodeB = getNodeStationFromNode(...)
|
||||
|
||||
//On récupère la liste des nodes correspondantes aux stations (stockée dans notre graphe des stations).
|
||||
arrayList<NodeStation> list = getNodeStationsFromNode(...)
|
||||
|
||||
/*
|
||||
int UpdateGraphIsodistance(Node,double,Graph)
|
||||
est une méthode de la classe StationGraph qui met à jour le StationGraph par rapport à l'Isodistance autour de A dans le graphe graph. Elle renvoie le nombre d'arrêtes crées (-1 si aucune).*/
|
||||
// on calcule l'Isodistance de A
|
||||
if (grS.UpdateIsodistance(NodeA,maximumDist,gr) != -1){
|
||||
|
||||
// A.hasSuccessor(B) itère sur les successeurs d'un NodeStation (A) et vérifie si l'un d'entre eux est B
|
||||
if(!NodeA.hasSuccessor(NodeB)){
|
||||
// on calcule l'Isodistance de B
|
||||
if (grS.UpdateIsodistance(NodeB,maximumDist,gr) != -1){
|
||||
|
||||
/*StationAStarAlgorithm(ShortestPathData, double) hérite de AStar et ne fait que s'adapter aux classes "Station" pour rechercher quel est le plus court chemin sur le graphe des stations*/
|
||||
|
||||
StationAStarAlgorithm AAlgo = new StationAStarAlgorithm(data);
|
||||
StationPath aStarResult = AAlgo.doRun();
|
||||
arrayList<ArcStation> way = aStarResult.getStationArc();
|
||||
Path[] pathArray = new Path[way.size()];
|
||||
|
||||
int i = 0;
|
||||
for(ArcStation i : way){
|
||||
if (data.getMode() == AbstractInputData.Mode.TIME) {
|
||||
pathArray[i] = way.getTimePath()
|
||||
// à noter qu'on pourrait également retourner le path renvoyé par un ModifiedAStarAlgorithm lancé en temps si le choix a été fait de ne pas stocker dans les arc le chemin correspondant.
|
||||
} else {
|
||||
pathArray[i] = way.getLengthPath()
|
||||
}
|
||||
}
|
||||
// à noter également que si l'on choisit de stocker des listes d'Arc plutôt que des Path il suffira de faire remplacer le Path.concatenate(...) par un new Path(gr, arcs)
|
||||
|
||||
|
||||
// il nous faut maintenant concaténer les chemins entre chaque station
|
||||
solution = new ShortestPathSolution(data, AbstractSolution.Status.OPTIMAL, Path.concatenate(pathArray));
|
||||
|
||||
|
||||
} else {
|
||||
// aucune solution car aucune NodeS dans l'isodistance de B
|
||||
|
||||
solution = new ShortestPathSolution(data, AbstractSolution.Status.INFEASIBLE);
|
||||
}
|
||||
} else {
|
||||
/*ModifiedAStarAlgorithm(ShortestPathData, double) hérite de AStar et ne change que le fait qu'un arc n'est inséré que si son coût depuis l'origine est inférieur à la valeur passée en argument du constructeur */
|
||||
|
||||
|
||||
// pas besoin de stations car B est dans l'isodistance de A
|
||||
ModifiedAStarAlgorithm AAlgo = new ModifiedAStarAlgorithm(data, maximumDist);
|
||||
solution = AAlgo.doRun();
|
||||
}
|
||||
} else {
|
||||
// aucune solution car aucune NodeS dans l'isodistance de A
|
||||
solution = new ShortestPathSolution(data, AbstractSolution.Status.INFEASIBLE);
|
||||
}
|
||||
}
|
102
README.md
102
README.md
|
@ -1,62 +1,64 @@
|
|||
# Graph & Algorithm project — INSA Toulouse
|
||||
**[ LEJEUNE Aurelia & R.LACROIX ]**
|
||||
|
||||
## How to start?
|
||||
## Part 2
|
||||
|
||||
You will not be able to use this repository to save your work, you need to copy / import / fork it to
|
||||
your favorite Git platform.
|
||||
- ✅ [First UML diagram](answers.md)
|
||||
|
||||
### Importing to [Github](https://github.com), [Bitbucket](https://bitbucket.org) or [Gitlab](https://gitlab.com):
|
||||
|
||||
You first need to register and then log in to the platform you want. The steps to import the project are detailed below:
|
||||
- ✅ Path class implementation
|
||||
- ✅ createFastestPathFromNodes
|
||||
- ✅ createShortestPathFromNodes
|
||||
- ✅ isValid
|
||||
- ✅ getLength
|
||||
- ✅ getTravelTime
|
||||
- ✅ getMinimumTravelTime
|
||||
|
||||
#### Github
|
||||
|
||||
1. In the upper-right corner of any page, click the **"+"** icon, then click **Import repository**, or go to [https://github.com/new/import](https://github.com/new/import).
|
||||
2. Paste the following URL in the first input:
|
||||
[https://gitea.typename.fr/INSA/be-graphes.git](https://gitea.typename.fr/INSA/be-graphes.git)
|
||||
3. Choose the name you want for the repository.
|
||||
4. Click *Begin import*.
|
||||
5. Wait for completion... Done!
|
||||
## Part 3
|
||||
|
||||
#### Bitbucket
|
||||
- ✅ [Second UML diagram](answers.md)
|
||||
|
||||
1. On the left panel of any page, click the **"+"** icon, then **Repository**, and then **Import**, or directly go to [https://bitbucket.org/repo/import](https://bitbucket.org/repo/import).
|
||||
2. Paste the following URL in the first input (select Git as source if not already selected):
|
||||
[https://gitea.typename.fr/INSA/be-graphes.git](https://gitea.typename.fr/INSA/be-graphes.git)
|
||||
3. Choose the name you want for repository, and select Git as the *Version control system*.
|
||||
4. Click *Import repository*.
|
||||
5. Wait for completion... Done!
|
||||
|
||||
#### Gitlab
|
||||
|
||||
1. In the upper-right corner of any page, click the **"+"** icon, then **New project**, or directly go to [https://gitlab.com/projects/new](https://gitlab.com/projects/new).
|
||||
2. Select the **Import project** tab, and then click **Repo by URL** (right-most option).
|
||||
3. Paste the following URL in the first input:
|
||||
[https://gitea.typename.fr/INSA/be-graphes.git](https://gitea.typename.fr/INSA/be-graphes.git)
|
||||
4. Choose the name you want for the repository.
|
||||
5. Click *Create project*.
|
||||
6. Wait for completion... Done!
|
||||
|
||||
### Importing to another repository provider *[not recommended]*:
|
||||
|
||||
1. Create a new **empty** repository (no README, no LICENSE) on your provider. Let's assume the URL of your repository is `$URL_REPOSITORY`.
|
||||
2. Clone this repository somewhere:
|
||||
|
||||
```bash
|
||||
git clone https://gitea.typename.fr/INSA/be-graphes.git
|
||||
```
|
||||
- ✅ BinaryHeap implementation
|
||||
- ✅ implemented the remove() method
|
||||
- ✅ improved the method by using a hashmap
|
||||
|
||||
3. Go inside the newly cloned repository and update the **remote**:
|
||||
|
||||
```bash
|
||||
cd be-graphes
|
||||
git remote set-url origin $URL_REPOSITORY
|
||||
```
|
||||
|
||||
4. Push to your repository:
|
||||
|
||||
```bash
|
||||
push -u origin master
|
||||
```
|
||||
|
||||
Another way is to do a bare clone and then mirror it to your repository: [https://help.github.com/articles/importing-a-git-repository-using-the-command-line/](https://help.github.com/articles/importing-a-git-repository-using-the-command-line/)
|
||||
- ✅ Created Label
|
||||
- ✅ Attributes
|
||||
- ✅ currNode
|
||||
- ✅ marked
|
||||
- ✅ cost
|
||||
- ✅ father
|
||||
- ✅ Methods
|
||||
- ✅ getCost
|
||||
- ✅ compareTo
|
||||
|
||||
|
||||
- ✅ implemented Dijkstra
|
||||
- ✅ handling special types of paths (pedestrians, car roads etc)
|
||||
- ✅ added notifyNodeReached to show reached nodes on map
|
||||
- ✅ Testings (lots of)
|
||||
|
||||
## Part 4
|
||||
|
||||
- ✅ Modified Label
|
||||
- ✅ included getTotalCost
|
||||
|
||||
|
||||
- ✅ Created LabelStar (inherits from Label)
|
||||
- ✅ (new) Attributes
|
||||
- ✅ crowCost
|
||||
- ✅ Methods
|
||||
- ✅ getTotalCost
|
||||
|
||||
|
||||
- ✅ Modified Dijkstra (modularity)
|
||||
|
||||
|
||||
- ✅ implemented A-Star
|
||||
- ✅ built upon Dijkstra with another Label type
|
||||
|
||||
|
||||
- ✅ More and More testing (see the video).
|
BIN
UML1.png
Normal file
BIN
UML1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 117 KiB |
BIN
UML2.png
Normal file
BIN
UML2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 147 KiB |
|
@ -1 +0,0 @@
|
|||
<mxfile host="app.diagrams.net" modified="2022-03-28T08:39:48.312Z" agent="5.0 (X11)" etag="hLIc4Ae_8JBWeFUL2CPZ" version="17.2.4" type="device"><diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">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</diagram></mxfile>
|
|
@ -1 +0,0 @@
|
|||
<mxfile host="app.diagrams.net" modified="2022-03-25T15:17:15.240Z" agent="5.0 (X11)" etag="R9Cimn6XBIiNxGwcqEMN" version="17.2.3" type="device"><diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">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</diagram></mxfile>
|
|
@ -4,9 +4,9 @@ On a une liste de liste et non une matrice. L'avantage est de prendre bien moins
|
|||
|
||||
## Diagram UML
|
||||
Diagrame UML : <br>
|
||||
<img src="./img.png">
|
||||

|
||||
|
||||
## deuxieme diagram UML
|
||||
|
||||
Diagrame UML : <br>
|
||||
<img src="./img2.png">
|
||||

|
|
@ -23,5 +23,22 @@
|
|||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="target/generated-sources/annotations">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="ignore_optional_problems" value="true"/>
|
||||
<attribute name="m2e-apt" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="ignore_optional_problems" value="true"/>
|
||||
<attribute name="m2e-apt" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
|
|
@ -1,9 +1,48 @@
|
|||
package org.insa.graphs.algorithm.shortestpath;
|
||||
|
||||
import org.insa.graphs.algorithm.AbstractInputData;
|
||||
import org.insa.graphs.algorithm.AbstractSolution;
|
||||
import org.insa.graphs.algorithm.utils.BinaryHeap;
|
||||
import org.insa.graphs.algorithm.utils.Label;
|
||||
import org.insa.graphs.algorithm.utils.LabelStar;
|
||||
import org.insa.graphs.model.Arc;
|
||||
import org.insa.graphs.model.Graph;
|
||||
import org.insa.graphs.model.Node;
|
||||
import org.insa.graphs.model.Path;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
public class AStarAlgorithm extends DijkstraAlgorithm {
|
||||
|
||||
public AStarAlgorithm(ShortestPathData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
|
||||
// only difference with Dijkstra : using different labels
|
||||
@Override
|
||||
protected void initLabel(){
|
||||
int i = 0;
|
||||
|
||||
// usefull for the estimated crowlength time,
|
||||
// if there are no maximal speed we use 130 km/h
|
||||
double maxSpeed = 130;
|
||||
|
||||
if (data.getMode() == AbstractInputData.Mode.TIME){
|
||||
if (gr.getGraphInformation().hasMaximumSpeed()){
|
||||
maxSpeed = gr.getGraphInformation().getMaximumSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
// initialization close to Dijkstra's
|
||||
for (Node l : gr.getNodes()){
|
||||
if (data.getMode() == AbstractInputData.Mode.TIME){
|
||||
labels[i] = new LabelStar(l, false, null,data.getDestination(), maxSpeed);
|
||||
} else {
|
||||
labels[i] = new LabelStar(l, false, null,data.getDestination());
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.insa.graphs.algorithm.shortestpath;
|
|||
import org.insa.graphs.algorithm.AbstractSolution;
|
||||
import org.insa.graphs.algorithm.utils.BinaryHeap;
|
||||
import org.insa.graphs.algorithm.utils.Label;
|
||||
import org.insa.graphs.algorithm.utils.LabelStar;
|
||||
import org.insa.graphs.model.Arc;
|
||||
import org.insa.graphs.model.Graph;
|
||||
import org.insa.graphs.model.Node;
|
||||
|
@ -14,50 +15,78 @@ import java.util.List;
|
|||
|
||||
public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||
|
||||
/* === Used for testing purposes ===
|
||||
private long nodes = 0;
|
||||
*/
|
||||
|
||||
public DijkstraAlgorithm(ShortestPathData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortestPathSolution doRun() {
|
||||
final ShortestPathData data = getInputData();
|
||||
Graph gr = data.getGraph();
|
||||
final ShortestPathData data = getInputData();
|
||||
Graph gr = data.getGraph();
|
||||
|
||||
// array containing all the labels
|
||||
Label[] labels = new Label[gr.size()];
|
||||
// array containing all the labels
|
||||
Label[] labels = new Label[gr.size()];
|
||||
|
||||
|
||||
//initialization of the labels
|
||||
// initialization (separate so that it can be overridden by the A*)
|
||||
protected void initLabel(){
|
||||
int i = 0;
|
||||
for (Node l : gr.getNodes()){
|
||||
labels[i] = new Label(l, false, null);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortestPathData getInputData() {
|
||||
return super.getInputData();
|
||||
}
|
||||
|
||||
public ShortestPathSolution doRun() {
|
||||
|
||||
//initialization of the labels
|
||||
initLabel();
|
||||
|
||||
// initialization of the heap & the first node
|
||||
BinaryHeap<Label> pQueue = new BinaryHeap<Label>();
|
||||
labels[data.getOrigin().getId()].setCost(0);
|
||||
|
||||
pQueue.insert(labels[data.getOrigin().getId()]);
|
||||
|
||||
boolean found = false;
|
||||
double prev = 0;
|
||||
// Pathfinding
|
||||
/* === Used for testing purposes ===
|
||||
double prev = 0;
|
||||
*/
|
||||
|
||||
// Pathfinding : we iterate while there are still nodes
|
||||
// to find and we have not found the destination yet
|
||||
while(!pQueue.isEmpty() && !found){
|
||||
|
||||
Label labelX = pQueue.deleteMin();
|
||||
|
||||
if (labelX.getCost()<prev){System.out.println(labelX.getCost()-prev);}
|
||||
prev = labelX.getCost();
|
||||
/* === Used for testing purposes ===
|
||||
if (labelX.getCost()<prev){System.out.println(labelX.getCost()-prev);}
|
||||
prev = labelX.getCost();
|
||||
*/
|
||||
|
||||
/* === Used for testing purposes ===
|
||||
nodes++;
|
||||
*/
|
||||
|
||||
labelX.setMarked(true);
|
||||
notifyNodeReached(labelX.getCurrNode());
|
||||
found = (data.getDestination() == labelX.getCurrNode());
|
||||
notifyNodeReached(labelX.getCurrNode()); // displaying function
|
||||
|
||||
for (Arc y : labelX.getCurrNode().getSuccessors()){
|
||||
found = (data.getDestination() == labelX.getCurrNode()); // check for destination reaching
|
||||
|
||||
for (Arc y : labelX.getCurrNode().getSuccessors()){ // iterate over all the successors
|
||||
Label labelY = labels[y.getDestination().getId()];
|
||||
if (!labelY.isMarked() && data.isAllowed(y)){
|
||||
|
||||
if (!labelY.isMarked() && data.isAllowed(y)){ // check for path types
|
||||
|
||||
if (labelY.getCost() > labelX.getCost()+data.getCost(y)){
|
||||
// updating the label with a better cost
|
||||
if (labels[labelY.getCurrNode().getId()].getCost() != Double.POSITIVE_INFINITY) {
|
||||
pQueue.remove(labelY);
|
||||
}
|
||||
|
@ -73,7 +102,7 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
|||
ShortestPathSolution solution = null;
|
||||
|
||||
// Destination has no predecessor, the solution is infeasible...
|
||||
if (!found || labels[data.getDestination().getId()] == null) {
|
||||
if (!found || labels[data.getDestination().getId()] == null || data.getDestination().getId()==data.getOrigin().getId()) {
|
||||
solution = new ShortestPathSolution(data, AbstractSolution.Status.INFEASIBLE);
|
||||
}
|
||||
else {
|
||||
|
@ -95,7 +124,9 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
|||
// Create the final solution.
|
||||
solution = new ShortestPathSolution(data, AbstractSolution.Status.OPTIMAL, new Path(gr, arcs));
|
||||
}
|
||||
|
||||
/* === Used for testing purposes ===
|
||||
System.out.print(" ... number of nodes : "+nodes);
|
||||
*/
|
||||
return solution;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
package org.insa.graphs.algorithm.utils;
|
||||
import java.util.HashMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
@ -16,6 +17,9 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
|||
// Number of elements in heap.
|
||||
private int currentSize;
|
||||
|
||||
// a hash map for the element - index link
|
||||
private HashMap<E, Integer> map;
|
||||
|
||||
// The heap array.
|
||||
protected final ArrayList<E> array;
|
||||
|
||||
|
@ -25,6 +29,7 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
|||
public BinaryHeap() {
|
||||
this.currentSize = 0;
|
||||
this.array = new ArrayList<E>();
|
||||
this.map = new HashMap<E, Integer>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,6 +40,7 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
|||
public BinaryHeap(BinaryHeap<E> heap) {
|
||||
this.currentSize = heap.currentSize;
|
||||
this.array = new ArrayList<E>(heap.array);
|
||||
this.map = new HashMap<E, Integer>(heap.map);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,6 +56,9 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
|||
else {
|
||||
this.array.set(index, value);
|
||||
}
|
||||
|
||||
// we need to add the correspondence between index - value
|
||||
map.put(value,index);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,15 +146,42 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
|||
|
||||
@Override
|
||||
public void remove(E x) throws ElementNotFoundException {
|
||||
// index of is not optimized but it's better than nothing. We will come back to improve it if we have time at the end
|
||||
int i = this.array.indexOf(x);
|
||||
if (i == -1 || i > this.currentSize - 1) {
|
||||
/* LEGACY CODE :
|
||||
Index of is not optimized but it's better than nothing. We will come back to improve it if we have time at the end
|
||||
int i = this.array.indexOf(x);
|
||||
*/
|
||||
|
||||
|
||||
int i = -1;
|
||||
|
||||
// check if it is in the hashMap
|
||||
if (this.map.get(x) != null){
|
||||
i = this.map.get(x);
|
||||
} else {
|
||||
throw new ElementNotFoundException(x);
|
||||
}
|
||||
|
||||
// check if the value makes sense
|
||||
if (i > this.currentSize - 1 || i == -1) {
|
||||
throw new ElementNotFoundException(x);
|
||||
}
|
||||
|
||||
// we decrement the index of the last element and set our value to be after this one
|
||||
E lastItem = this.array.get(--this.currentSize);
|
||||
|
||||
this.arraySet(i, lastItem);
|
||||
|
||||
// need to update the heap
|
||||
this.percolateDown(i);
|
||||
this.percolateUp(i);
|
||||
|
||||
|
||||
|
||||
// since we removed the element we need to make sure it's not referenced in the hashMap (hence putting it to -1)
|
||||
// since usually (not sure for the case of java, depends on how collisions are handled) the deletion of a pair
|
||||
// costs more than changing its value so could just set it to -1 but keeping it increases the chances of collisions
|
||||
// We therefore chose to remove it
|
||||
this.map.remove(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -161,6 +197,7 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
|||
E lastItem = this.array.get(--this.currentSize);
|
||||
this.arraySet(0, lastItem);
|
||||
this.percolateDown(0);
|
||||
this.map.remove(minItem);
|
||||
return minItem;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@ public class Label implements Comparable<Label> {
|
|||
return(this.cost);
|
||||
}
|
||||
|
||||
public double getTotalCost(){
|
||||
return(this.cost);
|
||||
}
|
||||
|
||||
public Node getCurrNode() {
|
||||
return currNode;
|
||||
}
|
||||
|
@ -44,13 +48,25 @@ public class Label implements Comparable<Label> {
|
|||
}
|
||||
|
||||
public int compareTo(Label other) {
|
||||
if (this.cost < other.getCost()) {
|
||||
// compares the total cost
|
||||
if (this.getTotalCost() < other.getTotalCost()) {
|
||||
return -1;
|
||||
} else {
|
||||
if (this.cost > other.getCost()) {
|
||||
if (this.getTotalCost() > other.getTotalCost()) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
} else { // same total cost ==> tie breaker : Crowcost
|
||||
|
||||
double thisCrowCost = this.getTotalCost()-this.getCost();
|
||||
double otherCrowCost = other.getTotalCost()-other.getCost();
|
||||
if (thisCrowCost < otherCrowCost) {
|
||||
return -1;
|
||||
} else {
|
||||
if (thisCrowCost > otherCrowCost) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package org.insa.graphs.algorithm.utils;
|
||||
|
||||
import org.insa.graphs.algorithm.AbstractInputData;
|
||||
import org.insa.graphs.algorithm.shortestpath.ShortestPathData;
|
||||
import org.insa.graphs.model.Arc;
|
||||
import org.insa.graphs.model.Node;
|
||||
|
||||
public class LabelStar extends Label{
|
||||
|
||||
private double crowCost; // used for the approximate crow distance
|
||||
|
||||
|
||||
// we can either run the A* with respect to time or to distance hence the 2 separate constructors
|
||||
public LabelStar(Node currNode, boolean marked, Arc father, Node dest, double maxSpeed){
|
||||
super(currNode,marked,father);
|
||||
this.crowCost = currNode.getPoint().distanceTo(dest.getPoint())/(maxSpeed*3.6);
|
||||
}
|
||||
|
||||
public LabelStar(Node currNode, boolean marked, Arc father, Node dest){
|
||||
super(currNode,marked,father);
|
||||
this.crowCost = currNode.getPoint().distanceTo(dest.getPoint());
|
||||
}
|
||||
|
||||
public double getTotalCost(){
|
||||
return(this.getCost() + this.crowCost);
|
||||
}
|
||||
}
|
|
@ -28,5 +28,22 @@
|
|||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="target/generated-sources/annotations">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="ignore_optional_problems" value="true"/>
|
||||
<attribute name="m2e-apt" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="ignore_optional_problems" value="true"/>
|
||||
<attribute name="m2e-apt" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
|
|
@ -10,11 +10,7 @@ import javax.swing.JFrame;
|
|||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.insa.graphs.algorithm.*;
|
||||
import org.insa.graphs.algorithm.shortestpath.DijkstraAlgorithm;
|
||||
import org.insa.graphs.algorithm.shortestpath.BellmanFordAlgorithm;
|
||||
import org.insa.graphs.algorithm.shortestpath.ShortestPathAlgorithm;
|
||||
import org.insa.graphs.algorithm.shortestpath.ShortestPathData;
|
||||
import org.insa.graphs.algorithm.shortestpath.ShortestPathSolution;
|
||||
import org.insa.graphs.algorithm.shortestpath.*;
|
||||
import org.insa.graphs.gui.drawing.Drawing;
|
||||
import org.insa.graphs.gui.drawing.components.BasicDrawing;
|
||||
import org.insa.graphs.model.Graph;
|
||||
|
@ -25,7 +21,17 @@ import org.insa.graphs.model.io.BinaryPathReader;
|
|||
import org.insa.graphs.model.io.GraphReader;
|
||||
import org.insa.graphs.model.io.PathReader;
|
||||
|
||||
// for colouring
|
||||
import java.time.Duration;
|
||||
import java.util.Random;
|
||||
import java.awt.Color;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Launch {
|
||||
private static int verbose = 1;
|
||||
private static long timeA = 0;
|
||||
private static long timeD = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Drawing inside a JFrame an return it.
|
||||
|
@ -51,6 +57,8 @@ public class Launch {
|
|||
return basicDrawing;
|
||||
}
|
||||
|
||||
|
||||
// generates a path with the chosen algorithm
|
||||
public static Path createTestPath(Graph graph,int idOrigin,int idDest,String algo){
|
||||
Node A = graph.get(idOrigin);
|
||||
Node B = graph.get(idDest);
|
||||
|
@ -59,29 +67,37 @@ public class Launch {
|
|||
ShortestPathSolution sol;
|
||||
ShortestPathData data= new ShortestPathData(graph,A,B,ins);
|
||||
|
||||
switch (algo){
|
||||
switch (algo){ // we chose the algo we want
|
||||
case "A*":
|
||||
System.out.println("not yet implemented");
|
||||
AStarAlgorithm AAlgo = new AStarAlgorithm(data);
|
||||
sol = AAlgo.doRun();
|
||||
resu = sol.getPath();
|
||||
|
||||
break;
|
||||
case "D":
|
||||
DijkstraAlgorithm algorithm = new DijkstraAlgorithm(data);
|
||||
sol = algorithm.doRun();
|
||||
DijkstraAlgorithm DAlgo = new DijkstraAlgorithm(data);
|
||||
sol = DAlgo.doRun();
|
||||
resu = sol.getPath();
|
||||
|
||||
break;
|
||||
|
||||
case "BF":
|
||||
BellmanFordAlgorithm BF = new BellmanFordAlgorithm(data);
|
||||
sol = BF.doRun();
|
||||
resu = sol.getPath();
|
||||
|
||||
break;
|
||||
default:
|
||||
System.out.println("no known algorithm");
|
||||
if (verbose == 1) { System.out.println("no known algorithm");}
|
||||
break;
|
||||
}
|
||||
|
||||
return resu;
|
||||
|
||||
}
|
||||
public static int comparePath(Path p1, Path p2,boolean time){
|
||||
// true if both are null or if they have
|
||||
// - the same time cost
|
||||
// - the same length
|
||||
if (p1 == null){
|
||||
if (p2 == null){
|
||||
return 1;
|
||||
|
@ -93,57 +109,106 @@ public class Launch {
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
if(time)
|
||||
if (Double.compare(p1.getMinimumTravelTime(),p2.getMinimumTravelTime())==0) {
|
||||
|
||||
|
||||
if(time) {
|
||||
if (Double.compare(p1.getMinimumTravelTime(), p2.getMinimumTravelTime()) == 0) {
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
if (Float.compare(p1.getLength(),p2.getLength())==0) {
|
||||
}else{
|
||||
if (Float.compare(p1.getLength(), p2.getLength()) == 0) {
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void displayResult(String algo, int justeD, int nbTest, long time){
|
||||
if (verbose == 1) {
|
||||
System.out.println(
|
||||
algo + " : number of good tests : " + Integer.toString(justeD) + "/"
|
||||
+ Integer.toString(nbTest * 2) + ". Total execution time : " + Long.toString(time) + "ms");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private static int test(Graph graph){
|
||||
int Id1 = (int) Math.floor(Math.random()*graph.size());
|
||||
int Id2 = (int) Math.floor(Math.random()*graph.size());
|
||||
private static int test(Graph graph, String testType,Drawing drawing, int id1, int id2){
|
||||
int resu = 0;
|
||||
System.out.println("testing with nodes " + Id1 + " and " + Id2);
|
||||
if (comparePath(createTestPath(graph, Id1, Id2, "D"),createTestPath(graph, Id1, Id2, "BF"), true) == 0) {
|
||||
resu++;
|
||||
long endTime;
|
||||
long startTime;
|
||||
if (verbose == 1) { System.out.print("testing " + testType +" with nodes " + id1 + " and " + id2);}
|
||||
|
||||
Path pathAlgo = null;
|
||||
|
||||
if (testType == "A*"){
|
||||
|
||||
// times the run of the algorithm
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
pathAlgo = createTestPath(graph, id1, id2, "A*");
|
||||
endTime = System.currentTimeMillis();
|
||||
|
||||
if (verbose == 2){System.out.println(endTime-startTime);}
|
||||
timeA += (endTime-startTime);
|
||||
} else {
|
||||
|
||||
// times the run of the algorithm
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
pathAlgo = createTestPath(graph, id1, id2, "D");
|
||||
endTime = System.currentTimeMillis();
|
||||
timeD += (endTime-startTime);
|
||||
if (verbose == 2){if (pathAlgo != null) {System.out.print(pathAlgo.getLength()+","+(endTime-startTime) + ",");}}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Path pathBF = createTestPath(graph, id1, id2, "BF");
|
||||
|
||||
|
||||
// tests if the results are the same in terms of time and length
|
||||
if (comparePath(pathAlgo, pathBF, true) == 1) {
|
||||
resu++;
|
||||
}
|
||||
|
||||
if (comparePath(createTestPath(graph, Id1, Id2, "D"),createTestPath(graph, Id1, Id2, "BF"), false) == 0) {
|
||||
resu++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (comparePath(pathAlgo, pathBF,false) == 1) {
|
||||
resu++;
|
||||
}
|
||||
|
||||
// draw the path created on the map (purely visual)
|
||||
Path drawPath = pathAlgo;
|
||||
if (drawPath != null){
|
||||
if (!drawPath.isEmpty()){
|
||||
try {
|
||||
if (testType == "A*") {
|
||||
drawing.drawPath(drawPath, new Color(150, 0, 150));
|
||||
} else {
|
||||
drawing.drawPath(drawPath, new Color(20, 200, 20));
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
if (verbose == 1) { System.out.println(" ... Done (length : " + Float.toString(drawPath.getLength()) + " found in " + Long.toString(endTime-startTime) + " ms)");}
|
||||
}
|
||||
}
|
||||
return resu;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// === these file are local the paths need to be adapted ===
|
||||
// Due to the size of the files we chose not to include these in the git repository
|
||||
|
||||
// Visit these directory to see the list of available files on Commetud.
|
||||
final String mapName = "/home/rlacroix/Bureau/3MIC/Be Graphe/mapinsa/insa.mapgr";
|
||||
final String pathName = "/home/rlacroix/Bureau/3MIC/Be Graphe/mapinsa/path_fr31insa_rangueil_r2.path";
|
||||
//final String mapName = "/home/rlacroix/Bureau/3MIC/Be Graphe/mapinsa/insa.mapgr";
|
||||
//final String mapName = "/home/rlacroix/Bureau/3MIC/Be Graphe/mapinsa/carre-dense.mapgr";
|
||||
final String mapName = "/home/rlacroix/Bureau/3MIC/Be Graphe/mapinsa/california.mapgr";
|
||||
//final String pathName = "/home/rlacroix/Bureau/3MIC/Be Graphe/mapinsa/path_fr31insa_rangueil_r2.path";
|
||||
|
||||
// Create a graph reader.
|
||||
final GraphReader reader = new BinaryGraphReader(
|
||||
|
@ -158,27 +223,47 @@ public class Launch {
|
|||
// 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))));
|
||||
//final PathReader pathReader = new BinaryPathReader(
|
||||
// new DataInputStream(new BufferedInputStream(new FileInputStream(pathName))));
|
||||
|
||||
// TODO: Read the path.
|
||||
final Path path = pathReader.readPath(graph);
|
||||
//final Path path = pathReader.readPath(graph);
|
||||
|
||||
// TODO: Draw the path.
|
||||
drawing.drawPath(path);
|
||||
|
||||
System.out.println("==TESTS==");
|
||||
//drawing.drawPath(path);
|
||||
|
||||
|
||||
int nbTest = 1000;
|
||||
int juste = 0;
|
||||
|
||||
int nbTest = 2000;
|
||||
int justeD = 0;
|
||||
int justeA = 0;
|
||||
|
||||
if (verbose == 1) { System.out.println("== LAUNCHING " + nbTest + " TESTS ==");}
|
||||
|
||||
for (int i = 0; i < nbTest; i++){
|
||||
juste += test(graph);
|
||||
// picks two nodes at random
|
||||
int id1 = (int) Math.floor(Math.random()*graph.size());
|
||||
int id2 = (int) Math.floor(Math.random()*graph.size());
|
||||
|
||||
if (i%10 == 0){
|
||||
// cleans the board every 10 runs and display the comparative runtimes
|
||||
drawing.clearOverlays();
|
||||
displayResult("Dijkstra",justeD,i,timeD);
|
||||
displayResult("A*",justeA,i,timeA);
|
||||
if (verbose == 1) { System.out.println("A* takes "+ Long.toString(100*(timeA+1)/(timeD+1)) +"% of Dijkstra's execution time");}
|
||||
}
|
||||
if (verbose == 1) { System.out.println("Test number " + Integer.toString(i));}
|
||||
justeD += test(graph,"D",drawing, id1, id2);
|
||||
justeA += test(graph,"A*",drawing,id1, id2);
|
||||
}
|
||||
System.out.println(
|
||||
"nmber of good tests : " + Integer.toString(juste) + "/" + Integer.toString(nbTest*2)
|
||||
);
|
||||
if (verbose == 1) { System.out.println("===== Final Results =====");}
|
||||
displayResult("Dijkstra",justeD,nbTest,timeD);
|
||||
displayResult("A*",justeA,nbTest,timeA);
|
||||
if (verbose == 1) { System.out.println("A* takes "+ Long.toString(100*timeA/timeD) +"% of Dijkstra's execution time");}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,5 +23,22 @@
|
|||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="target/generated-sources/annotations">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="ignore_optional_problems" value="true"/>
|
||||
<attribute name="m2e-apt" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="ignore_optional_problems" value="true"/>
|
||||
<attribute name="m2e-apt" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
|
|
@ -36,16 +36,19 @@ public class Path {
|
|||
if (nodes.size() == 1) {
|
||||
return new Path(graph, nodes.get(0));
|
||||
}
|
||||
if (nodes.size() == 1) {
|
||||
return new Path(graph);
|
||||
}
|
||||
|
||||
List<Arc> arcs = new ArrayList<Arc>();
|
||||
for (int i = 0 ; i < nodes.size(); i++) {
|
||||
|
||||
// we iterate over the list of nodes
|
||||
for (int i = 0 ; i < nodes.size(); i++) {
|
||||
Node currNode = nodes.get(i);
|
||||
if (i < nodes.size() -1) {
|
||||
|
||||
if (i < nodes.size() -1) { // if it's not the last
|
||||
Node nextNode = nodes.get(i+1);
|
||||
if (currNode.hasSuccessors()) {
|
||||
Arc better = null;
|
||||
|
||||
// we compare all the edges to pick the best one
|
||||
for (Arc j : currNode.getSuccessors()) {
|
||||
if (j.getDestination() == nextNode) {
|
||||
if (better == null || better.getMinimumTravelTime() > j.getMinimumTravelTime()) {
|
||||
|
@ -53,6 +56,8 @@ public class Path {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If it exists we add it else we throw an exception
|
||||
if (better == null) {
|
||||
throw (new IllegalArgumentException());
|
||||
} else {
|
||||
|
@ -80,19 +85,23 @@ public class Path {
|
|||
*/
|
||||
public static Path createShortestPathFromNodes(Graph graph, List<Node> nodes)
|
||||
throws IllegalArgumentException {
|
||||
//
|
||||
if (nodes.size() == 1) {
|
||||
return new Path(graph, nodes.get(0));
|
||||
}
|
||||
if (nodes.size() == 1) {
|
||||
return new Path(graph);
|
||||
}
|
||||
|
||||
List<Arc> arcs = new ArrayList<Arc>();
|
||||
|
||||
// we iterate over the list of nodes
|
||||
for (int i = 0 ; i < nodes.size(); i++) {
|
||||
Node currNode = nodes.get(i);
|
||||
if (i < nodes.size() -1) {
|
||||
|
||||
if (i < nodes.size() -1) { // if it's not the last
|
||||
Node nextNode = nodes.get(i+1);
|
||||
if (currNode.hasSuccessors()) {
|
||||
Arc better = null;
|
||||
|
||||
// we compare all the edges to pick the best one
|
||||
for (Arc j : currNode.getSuccessors()) {
|
||||
if (j.getDestination() == nextNode) {
|
||||
if (better == null || better.getLength() > j.getLength()) {
|
||||
|
@ -100,6 +109,8 @@ public class Path {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If it exists we add it else we throw an exception
|
||||
if (better == null) {
|
||||
throw (new IllegalArgumentException());
|
||||
} else {
|
||||
|
@ -253,17 +264,14 @@ public class Path {
|
|||
*/
|
||||
public boolean isValid() {
|
||||
Arc old = null;
|
||||
// it is empty
|
||||
if (this.isEmpty()) {
|
||||
// it is empty so true
|
||||
return true;
|
||||
}
|
||||
// Origin is ok
|
||||
if ((this.origin != null) && (this.arcs.size() == 0)) {
|
||||
// only origin is ok: single node (without arcs)
|
||||
return true;
|
||||
}
|
||||
if (this.arcs.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
// destination of the first one is the origin of the second node
|
||||
if (this.arcs.get(0).getOrigin() == this.origin) {
|
||||
for (Arc a : this.arcs) {
|
||||
|
@ -292,6 +300,7 @@ public class Path {
|
|||
*/
|
||||
public float getLength() {
|
||||
float acc = 0;
|
||||
// sum all of the lengths
|
||||
for (Arc l : this.arcs) {
|
||||
acc += l.getLength();
|
||||
}
|
||||
|
@ -309,7 +318,7 @@ public class Path {
|
|||
*
|
||||
*/
|
||||
public double getTravelTime(double speed) {
|
||||
double speed2 = speed * 1000/3600;
|
||||
double speed2 = speed * 1000/3600; // conversion from km/h to m/s
|
||||
return (this.getLength()/speed2);
|
||||
}
|
||||
|
||||
|
@ -322,6 +331,7 @@ public class Path {
|
|||
*/
|
||||
public double getMinimumTravelTime() {
|
||||
float acc = 0;
|
||||
// sum all of the minimum travel times
|
||||
for (Arc l : this.arcs) {
|
||||
acc += l.getMinimumTravelTime();
|
||||
}
|
||||
|
|
BIN
img.png
BIN
img.png
Binary file not shown.
Before Width: | Height: | Size: 130 KiB |
BIN
img2.png
BIN
img2.png
Binary file not shown.
Before Width: | Height: | Size: 40 KiB |
Loading…
Reference in a new issue