README.md 4,12 ko
Newer Older
by183440's avatar
by183440 a validé
# TP3-Plus-Courts-Chemins Yacine Belmokhtar

## Introduction
Dans ce TP nous devons implémenter l'algorithme de Dijkstra de façon naïve sur un graphe généré aléatoirement. Ensuite comparer l'algorithme implémenté et l'algorithme présent dans GraphStream.

## Génération de graphe

Pour générer les différents graphes, j'ai utilisé `RandomGenerator` de GraphStream qui me permet de créer des graphes de tailles différentes.  
``Generator gen = new RandomGenerator(degreMoyen, false, true);``                                                                                    
Le constructeur prend en paramètre:
- un double qui contient le degré moyen du graphe
- true si on veut qu'à chaque étape l'algorithme retire
- true si l'on veut que le graphe soit orienté, false si l'on veut que le graphe ne soit pas orienté

```java
    Graph g = new SingleGraph("Graphe aléatoire");
    g.setAttribute("ui.quality");
    g.setAttribute("ui.antialias");

    Generator gen = new RandomGenerator(degreMoyen,false, true);
    gen.addSink(g);
    gen.begin();
    for(int i=0; i<nbSommet; i++)
    gen.nextEvents();

    gen.end();
```

## Dijkstra naïve

J'ai créé une classe `MonDijkstra` où se trouve une méthode `Dijkstra(Graph g)` qui permet de parcourir le graphe et de lui appliquer l'algorithme de Dijkstra.
Dans un premier temps j'ai crée des méthodes pour alléger la méthode `Dijkstra(Graph g)`. Ces méthodes sont:
- `getNodes(Graph g)` qui permet de me retourner une ArrayList de noeud présent dans le graphe
- `sommetMin(Node n)` qui me permet de récupérer le noeud minimum présent dans l'ArrayList

Tout d'abord, je récupère tout les noeuds du graphe dans une ArrayList en utilisant la méthode `getNodes(Graph g)`. Ensuite, je récupère le noeud minimum en utilisant la méthode `sommetMin(Node n)` et je boucle tant que le noeud n'est pas null.
Je retire le noeud actuelle de l'ArrayList. Je lui ajoute un attribut "marque" qui est à `true`.
Puis je boucle sur les voisins du noeud actuel. Je récupère la distance de l'arc, le poids du noeud actuel et le poids du voisin.

SI le poids du voisin est plus grand que l'addition entre la distance de l'arc et le poids du noeud actuel ET qu'il ne possède pas l'attribut "marque" ALORS je change le poids du voisin et lui ajoute un attribut "pere" qui contient le noeud qui permet de garder le chemin.



## Dijkstra de GraphStream

La classe Dijkstra de GraphStream permet de trouver le plus court chemin entre deux noeuds dans le graphe. Cette classe permet d'initialiser le noeud de départ``dijkstra.setSource(graphe.getNode(0));``.

Pour l'utiliser il faut lui donner le graphe que l'on veut utiliser ainsi que le noeud de départ.
Exemple:

```java
   Dijkstra dijkstra = new Dijkstra(Dijkstra.Element.EDGE, null, "distance");
    dijkstra.init(graphe);
    dijkstra.setSource(graphe.getNode(0));
    dijkstra.compute();
```

## Tests et Résultats

J'ai testé sur des graphes de taille: 10, 50, 100, 500, 1 000, 5 000, 10 000.

| Nombre de noeud              | Degré Moyen |                                
|:-----------------------------|:------------|
| 10,50                        | 9           |
| 100, 500, 1000, 5000         | 30          |
| 10 000                       | 50          |

J'ai aussi calculé le temps d'exécution des deux algorithmes de Dijkstra pour savoir lequel des deux est le plus efficace.
``System.currentTimeMillis()`` qui me permet de récupérer le temps en millisecondes à un instant t.


![image](graphe/Graphe.png)

Avec le graphe, nous pouvons remarquer que le temps d'exécution augmente avec le nombre de noeud.
En ce qui concerne la méthode naïve le temps d'exécution pour un petit nombre de noeud est équivalente à celle de GraphStream.
by183440's avatar
by183440 a validé
Par contre, dès lors qu'on passe à un nombre de noeud beaucoup plus élevé le temps d'exécution augmente drastiquement. Le temps d'exécution de Dijkstra naïve est exponentiel.
by183440's avatar
by183440 a validé

## Conclusion

Bien que la version de Dijkstra naïve fonctionne on peut remarquer que son temps d'exécution augmente très vite en fonction du nombre de noeud, comparé à celle de GraphStream qui augmente certe mais de façon linéaire.