Algorithme de Dijkstra et applications

Partie 1 : Graphes, algorithme de Dijsktra et New York


👋 Introduction

L’algorithme de Dijkstra (du nom de son inventeur) sert principalement Ă  trouver le plus court chemin entre une sommet de dĂ©part et un sommet d’arrivĂ© dans un graphe orientĂ© pondĂ©rĂ© par des nombres rĂ©els positifs. Ses applications sont donc diverses et peuvent aller de la simple recherche de chemin dans un graphe Ă  des algorithmes de traitement d’image.

⚖ Graphe pondĂ©rĂ©

Définition formelle

Un graphe G=(V,E)G = (V, E) est un couple comprenant deux ensembles :

  • VV les sommets du graphe (vertices en anglais)
  • EE les arrĂȘtes du graphes (edges en anglais) dont chaque Ă©lĂ©ment est un couple de sommets (u,v)(u, v) (u,v∈Vu, v \in V), uu Ă©tant le sommet de dĂ©part et vv le sommet d’arrivĂ© de l’arĂȘte.

Remarque : Nous prendrons toujours et supposerons à partir de maintenant que V={0,1,
,n−1}V = \{0, 1, 
, n-1\} avec ninNn in \N la taille de VV

Chaque graphe peut ĂȘtre pondĂ©rĂ©, c’est Ă  dire que l’on associe Ă  chaque arrĂȘte une valeur par le biais d’une fonction poids p:E→Rp: E → \reals. Dans notre cas l’ensemble d’arrivĂ© est restreint Ă  R+\reals_+ pour le bon fonctionnement de l’algorithme. Pour simplifier, on suppose aussi que les arĂȘtes sont non orientĂ©es, c’est Ă  dire qu’on ne distingue plus (u,v)(u, v) de (v,u)(v, u) qu’on notera {u,v}\{u, v\}. Voici une reprĂ©sentation d’un graphe non orientĂ© Ă  6 sommets :

drawing

ConcrĂštement, on peut par exemple imaginer que les sommets du graphes reprĂ©sentent des villes et les arrĂȘtes des routes pondĂ©rĂ©es par leur longueur.

Un peu de vocabulaire

Voisin : u∈Vu \in V et v∈Vv \in V sont voisins si {u,v}∈E\{u, v\} \in E

DegrĂ© : Le degrĂ© d’un sommet u∈Su \in S est son nombre de voisins

Chemin : On Appelle chemin de longueur l∈Nl \in \N le couple ordonnĂ©e des sommets (u0,u1,
,ul)(u_0, u_1, 
, u_l) tel que pour tout k∈{0,1,
,l−1},{uk,uk+1}∈Ek \in \{0, 1, 
, l-1\}, \{u_k, u_{k+1} \} \in E

Connexité : Un graphe G=(V,E)G = (V, E) est dit connexe si pour tout u,v∈Eu, v \in E il existe un chemin reliant uu à vv

Représentations mémoire

On peut stocker les deux ensembles VV et EE mais ce n’est pas trĂšs efficace. Dans un premier temps et quitte Ă  avoir une fonction d’étiquetage, on considĂšre que l’ensemble SS est de la forme ⟩0,n−1⟧⟩0, n-1⟧ oĂč nn est le nombre de sommets du graphe.

ReprĂ©sentation sous la forme de listes d’adjacence

Cette représentation mémoire consiste à stocker les sommets voisins dans une liste de listes par exemple en python :

graphe1_listeadj = [[], [], []]

ReprĂ©sentation sous la forme d’une matrice d’adjacence

On peut aussi utiliser une matrice A∈Mn(R)A \in \mathcal{M}_n(\R) avec pour tout u,v∈Vu, v \in V Au,vA_{u,v} qui vaut −1-1 si uu et vv ne sont pas voisins et le poids de l’arĂȘte les reliants si ils sont voisins.

👣 Algorithme de Dijkstra

Une question naturelle se pose alors, Ă©tant donnĂ© un sommet de dĂ©part uu et un sommet d’arrivĂ© vv, existe-t-il un chemin de uu Ă  vv et si oui, quelle est le plus court. Pour le rĂ©soudre, introduisons d’abord une structure de donnĂ©es appelĂ©e file de prioritĂ©.

File de priorité

Une file de prioritĂ© et une structure simple. Elle permet de mettre de cĂŽtĂ© dans un objet appelĂ©e file des Ă©lĂ©ments en leur associant un numĂ©ro de prioritĂ©, et d’extraire par la suite l’élĂ©ment de plus grande prioritĂ©. On est dotĂ© de 4 opĂ©rations appelĂ©es primitives sur cette structure:

file_vide() renvoie la file vide

est_vide(f) renvoie un booléen indiquant si la file f est vide

enfile(f, x, p) qui Ă©tant donnĂ©e une file f, un Ă©lĂ©ment xet une prioritĂ© p, enfile l’élĂ©ment x dans la file f avec la prioritĂ© p (mais ne renvoie rien)

defile(f) renvoie l’élĂ©ment de plus haute prioritĂ© dans la file f et le supprime de cette file

À noter que les deux derniĂšre fonctions on des effets de bords. Leur appel modifie f quand bien mĂȘme enfile ne renvoie rien.

Algorithme de Dijsktra

L’algorithme de Dijkstra est alors le suivant. On commence par une initialisation :

  • on initialise un tableau deja_traite avec les sommets qui ont dĂ©jĂ  Ă©tĂ© traitĂ©s. Ce tableau est un tableau de nn boolĂ©ens tous initialisĂ©s Ă  false.
  • On initialise un tableau prec de taille nn rempli de −1-1 qui servira Ă  reconstruire le plus court chemin entre uu et vv
  • On initialise un tableau dist de taille nn qui stocke la distance du plus court chemin dĂ©couvert jusque lĂ  entre le sommet de dĂ©part et chaque sommet. Ce tableau rempli de +inf⁥+\inf sauf pour le sommet de dĂ©part dont la valeur image vaut 00
  • On initialise une file de prioritĂ© vide dans une variable f
  • On enfile dans cette file f le sommet de dĂ©part avec une prioritĂ© 00

On va alors itĂ©rativement dĂ©filer l’élĂ©ment de plus grande prioritĂ© de f, et si il n’a pas encore Ă©tĂ© traitĂ©, mettre Ă  jour la distance dist des ses voisins au sommet de dĂ©part ainsi que prec si nĂ©cessaire.

Voici un code python de l’algorithme :

def dijkstra(liste_adj, starting_point):
  # Initialisations
  n = len(liste_adj)
  f = file_vide()
  enfile(f, starting_point, 0)
  pred = [-1 for _ in range(n)]
  dist = [float("inf") for _ in range(n)]
  dist[starting_point] = 0
  deja_traite = [False for _ in range(n)]

  # Le traitement
  while not est_vide(f):
    u = defile(f)
    if not dejaTraite[u]:
      for (w, v) in liste_adj[v]:
        if not dejaTraite[v] and dist[u] + w < dist[v]:
          dist[v] = dist[u] + w
          pred[v] = u
          enfile(f, v, dist[u] + w)
    dejaTraite[u] = True

  return dist, pred

đŸ—œ Application Ă  la recherche du plus court chemin dans New York

Donnons nous le graphe de New York : drawing Oui il s’agit bien d’un graphe, juste beaucoup plus grand. Chaque intersection reprĂ©sente un sommet et chaque route une arĂȘte pondĂ©rĂ©e par la distance de celle-ci. On peut alors se donner deux sommets, un de dĂ©part c’est le point bleu du graphe, et un d’arrivĂ©, c’est le point rouge. L’algorithme de Dijkstra et la reconstruction nous permettent alors de trouver le plus court chemin entre le sommet de dĂ©part et d’arrivĂ© :

drawing

VoilĂ , on a pu coder un petit GPS !!

➕ D’autres applications

Redimensionner une image

đŸ—‚ïž Ressources

fin.