Planche 1

Cours 8
Graphes orientés
Files de priorité

Jean-Jacques.Levy@inria.fr
http://jeanjacqueslevy.net
tel: 01 39 63 56 89

secrétariat de l'enseignement:
Catherine Bensoussan
cb@lix.polytechnique.fr
Aile 00, LIX
tel: 01 69 33 34 67

http://www.enseignement.polytechnique.fr/informatique/


Planche 2

Plan

  1. Files de priorité
  2. Heapsort
  3. Plus court chemin
  4. Composantes fortement connexes
  5. Warshall

Planche 3

Structure de tas

Représentation par des arbres binaires quasi-parfaits, dont tout noeud a une valeur supérieure à celle de ses fils.

Arbres représentés par des tableaux, ``
tas'' (heap).



Planche 4

Files de priorités

Représentation et ajout d'un élément

class FileP {
  int[] t; int taille;
  FileP (int n) { t = new int[n]; taille = 0; }

  static void ajouter (FileP f, int v)  {
    if (f.taille >= f.t.length)
      throw new Error ("File pleine.");
    ++f.taille; int i = f.taille - 1;
    while( i > 0 && f.t[(i - 1)/2] < v ) {
        f.t[i] = f.t[(i - 1)/2]; 
        i = (i - 1)/2;
    }
    f.t[i] = v;
  }

  static int premier (FileP f) { return f.t[0]; }

Planche 5

Ajout


Planche 6

Files de priorités

static int supprimer (FileP f) {
  if (f.taille <= 0) 
    throw new Error ("File vide.");
  int res = f.t[0]; 
  f.t[0] = f.t[f.taille - 1]; --f.taille;
  int v = f.t[0]; int i;
  for (i = 0; 2*i + 1 < f.taille; ) {
      int j = 2*i + 1;
      if (j + 1 < f.taille && f.t[j + 1] > f.t[j])   ++j;
      if (v >= f.t[j])  break;
      f.t[i] = f.t[j]; i = j;
  }
  f.t[i] = v;
  return res;
}

Exercice 1Complexité de l'ajout et de la suppression?


Planche 7

Suppression


Planche 8

Le tri par tas

static void triParTas (int[ ] a) {
  FileP f = new FileP (a.length);
  for (int i = 0; i < a.length; ++i)
    ajouter (f, a[i]);
  for (int i = a.length - 1; i >= 0; --i)
    a[i] = supprimer(f);
}


Planche 9

Optimalité du tri
Théorème 1 Le tri de n éléments, fondé uniquement sur les comparaisons des éléments deux à deux, fait au moins O(n log n) comparaisons.

Démonstration
Tout arbre de décision pour trier n éléments a n! feuilles représentant toutes les permutations possibles. Un arbre binaire de n! feuilles a une hauteur de l'ordre de log n! » n log n par la formule de Stirling.



Planche 10

Tri topologique
Tester si un graphe
G=(V,E) est acyclique et donner une liste des noeuds á ni | i=1..nñ dans un ordre compatible avec celui du graphe (ni successeur de nj implique i < j).


(tri topologique
= trouver un ordre total compatible avec un ordre partiel donné)
Planche 11

Tri topologique
Ordre de lecture
des chapîtres
du livre de
H. P. Barendregt
The l-calculus:
its syntax and semantics
North-Holland, 1980


Planche 12

Détection de cycles dans un graphe orienté

static boolean acyclique (Graphe g) {
  int n = g.succ.length;
  boolean[] vu = new boolean[n];
  boolean[] enCours = new boolean[n];
  for (int i=0; i < g.succ.length; ++i) vu[i] = enCours[i] = false;
  for (int i=0; i < g.succ.length; ++i)
    if ( !vu[i] && cycliqueEn (g, i, vu, enCours) ) 
        return false;
  return true;
}

static boolean cycliqueEn (Graphe g, int i, boolean[] vu, boolean[] enCours) {
  enCours[i] = true;
  for (Liste ls = g.succ[i]; ls != null; ls = ls.suivant) {
    int x = ls.val;
    if ( enCours[x] || !vu[x] && cycliqueEn (g, x, vu, enCours) )
        return true;
  }
  enCours[i] = false; vu[i] = true; 
  return false;
}

Planche 13

Exercice 2Programmer le tri topologique. Complexité?

Fermeture transitive
Le graphe est représenté par sa matrice
M de connexion (matrice d'adjacence). Il s'agit de calculer
M* = M0 + M + M2 + M3 + ···
Les chemins dont tous les noeuds sont distincts ont une longueur strictement inférieure à n. Il suffit de calculer
M* = M0 + M + M2 + M3 + ··· Mn-1
La multiplication de matrice n × n a une complexité O(n3). La fermeture transitive peut donc se faire en O(n4) opérations.

Faire mieux?



Planche 14

Algorithme de Warshall


Enumération des chemins selon
le plus grand des noeuds intermédiaires par lesquels ils passent.
C-1 = M
Ck = Ck-1 È {(x,y) | (x,k) Î Ck-1, (k,y) Î Ck-1 }


static Graphe fermetureTransitive (Graphe g) {
  int n = g.m.length;
  Graphe c = copieGraphe (g);
  for (int k = 0; k < n; ++k)
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j)
          c.m[i][j] = c.m[i][j] || (c.m[i][k] && c.m[k][j]);
  return c;
}

Exercice 3Complexité?


Planche 15

Composante fortement connexe

Dans un graphe non orienté, connexité
= facile. Dans un graphe orienté, composantes fortement connexes = parties maximales où toute paire de noeuds distincts est reliée par un chemin.



Planche 16

Points d'attache   (cf. biconnexité)



Planche 17

Calcul des composantes fortement connexes


static int attache (Graphe g, int k) {
  num[k] = ++id; Pile.empiler(k, p);
  int min = id; 
  for (Liste ls = g.succ[k]; ls != null; ls = ls.suivant) {
    int x = ls.val; int m;
    if (num[x] == -1) m = attache (g, x);
    else m = num[x];
    if (m < min) min = m;
  }
  if (min == num[k]) {
    int y;
    do {
      y = Pile.depiler(p);
      System.out.print (y + " ");
      num[y] = g.succ.length;
    } while (y != k);        
    System.out.println();
  }
  return min;
}

Planche 18

Graphe valué


Chaque arc a un poids (distance).


Planche 19

Plus court chemin dans un graphe

Planche 20

Algorithme de Dijkstra

static int[] plusCourtChemin (GrapheV g, int s, int d) {
  int n = g.succ.length; FileP q = new FileP (n);
  int[] dMin = new int[n]; int[] prec = new int[n];
  for (int i = 0; i < n; ++i) { dMin[i] = Integer.MAX_VALUE; prec[i] = -1; }
  dMin[s] = 0;
  FileP.ajouter (s, 0, q);
  while (q.taille != 0) {
    int k = FileP.supprimer (q);
    if (k == d) return prec;
    for (ListeSucc ls = g.succ[k]; ls != null; ls = ls.suivant) {
      int x = ls.val; int w = ls.dist;
      if (dMin[x] > dMin[k] + w) {
        dMin[x] = dMin[k] + w;
        FileP.modifier (x, dMin[x]);
        prec[x] = k;      
      }
    }
  }
  return prec;
}

Planche 21

Algorithme de Dijkstra -- bis

Exercice 4Complexité de l'algorithme de Dijkstra
Exercice 5Complexité en recherchant le minimum simplement (sans file de priorité)?
Exercice 6Comment transformer l'algorithme de Dijkstra pour le trouver le plus court chemin d'un noeud à tous les autres dans le graphe.
Exercice 7Idem en plus court chemin depuis tous les noeuds jusqu'à un même noeud destination.
Exercice 8Idem pour les plus courts chemins entre tous les noeuds.


Planche 22

En TD -- problèmes


This document was translated from LATEX by HEVEA.