Cours 4

Plan

Les tours de Hanoi

La récursivité (qui existe aussi en Pascal et C) est proche de l'induction mathématique. Elle ne se contente pas de calculer des suites récurrentes. Exemple des tours de Hanoi.

Transporter N rondelles de la pile i à la pile j en ne mettant jamais une petite sous une plus grosse, avec (i,j dans {1, 2, 3}).

Si N = 0, ne rien faire. Si N > 0, alors on résoud le pb avec N-1 rondelles de i à la troisième pile k=6-i-j. On prend la grosse rondelle en bas de i et on la met sur j (qui est alors vide). On met alors les N-1 rondelles de k sur i.

Ecrire donc le programme correspondant (en moins de 5 lignes). On réalise alors que la récursion est un mécanisme très général.

Problèmes indécidables

Y-a-t'il des problèmes sans solution algorithmique?

Qques exemples:

1- Faire un programme qui teste si un autre termine. Sinon on aboutit à une contradiction:

let test_terminaison (u) = 
    begin
    (* test_terminaison (u) = true si u() termine  *)
    (*                        false sinon          *)
    (* Source du programme brevete' par le vendeur *)
    end;;

let rec d () =
    while test_terminaison(d) do ()  
    done ;;
Alors d() termine si et seulement si d() ne termine pas!

2- Considérer des dominos carré dont chacun des 4 cotés est coloré. On suppose qu'on peut prendre des dominos en nombre arbitraire dans un type fini donné à l'avance. Peut-on recouvrir toute surface avec des carrés compatibles, c'est a` dire dont les cote's qui se touchent sont de me^mes couleurs? Peut-on recouvrir le plan avec des carrés compatibles?

3- Problème de correspondance de Post. Soient 2 ensembles finis de mots avec des lettres de l'alphabet. Existe-t-il 2 chaines identiques formés uniquement avec un nombre arbitraire de mots de chacun des 2 types?

Ne pas confondre avec des problèmes décidables, mais de complexité très élevée.

Il existe aussi des pbs plus indécidables que les autres. Cf le livre de Rogers. (La récursivité sera vu dans le cours de Stern en majeure Math et Informatique, M1).

Premier exemple de diviser pour régner

Les éléments d'un tableau sont des nombre entiers relatifs. Trouver les sommes maximales de sous-séquences consécutives. (livre de Bentley, Programming Pearls)

let maximum a =
  let n = vect_length a in
  let res = ref 0 
  and s = ref 0 in
  begin
     for g = 0 to n-1 do 
        for d = g to n-1 do
           s := 0;
           for i = g to d do
               s := !s + a.(i);
           done;
           res := max (!res, !s)
        done
     done;
     !res
  end
;;
Complexité?

Minimum partiels (bis)

let maximum a =
  let n = vect_length a in
  let res = ref 0 
  and s = ref 0 in
  begin
     for g = 0 to n-1 do 
        s := 0;
        for d = g to n-1 do
               s := !s + a.(i);
               res := max (!res, !s)
           done
        done
     done;
     !res
  end
;;
Complexité?

Minimum partiels (ter)

let max (x, y) = if x < y then y else x ;;

let rec maximum a g d =
  let n = vect_length a in
  let res = ref 0  
  and s = ref 0 and maxG = ref 0 and maxD = ref 0 
  and maxACheval = ref 0 and maxAGauche = ref 0 and maxADroite = ref 0
  in
   if g > d then 0
   else 
   if g = d then max (0, a.(g))
   else 
   let m = (g + d) / 2 in
   begin
      s := 0; maxG := 0;
      for i = m downto g do
           s := !s + a.(i);
           maxG := max(!maxG, !s);
      done;
      s := 0; maxD := 0;
      for i = m+1 to d do
           s := !s + a.(i);
           maxD := max(!maxD, !s);
      done;
      let maxACheval = !maxG + !maxD  and
          maxAGauche = maximum a g m  and
          maxADroite = maximum a (m+1) d
      in
      max(maxACheval, max(maxAGauche, maxADroite))
   end ;;
Complexité?

Tri récursif -- Quicksort, Merge sort

Principe: on coupe en 2, on trie les 2 moitiés et on réarrange le résultat. C'est le principe du tri fusion, qui est ttefois un peu plus du^r à programmer que QuickSort (Hoare, 1960), où on essaie de deviner une bonne décomposition.

Quicksort. On prend un élément au hasard, on le met en place avec à sa gauche des plus petits ou égal, et à sa droite des plus grands ou égal et on recommencre récursivement sur les 2 moitiés.

let rec quick_sort g d =
  if g < d then begin
    let v = a.(g)
    and m = ref g in
    for i = g + 1 to d do
       if a.(i) < v then begin
          m := !m + 1;
          let x = a.(!m) in
          a.(!m) <- a.(i); a.(i) <- x
       end
    done;
    let x = a.(!m) in
    a.(!m) <- a.(g); a.(g) <- x;
    quick_sort g (!m - 1);
    quick_sort (!m + 1) d
  end;;
Complexité en 1.38 N log N ( cf polycopié).

Entrées graphiques

Pour lire des points à la souris, on peut faire de l'attente active (polling) avec des événements multiplexés clavier/souris:

 
let wait_button_down() =
   while not button_down() do () done;;

let wait_button_up() =
   while button_down() do () done;;

let get_next_point () =
   begin
   wait_button_down();
   wait_button_up();
   mouse_pos()
   end;;
et on s'arrête qd on met le curseur dans une zone spécifique de l'écran. Il y a plus sophistiqué (et non séquentiel)
   let e = wait_next_event [Button_down; Key_pressed] in
     if e.keypressed then begin
        match e.key with 
          'q' -> ....

     end else
     if e.button then begin

Courbes de Bézier

L'ingénieur Bézier de Renault a défini des courbes intéressantes pour la conception des carosseries de voitures. Ces courbes sont aussi utilisées en PostScript (pour les imprimantes laser) et dans MetaFont (pour générer les polices de caractères de TeX).

Les cubiques de Bézier (splines) sont données par 4 points, A, B, C, D. La cubique est tangente en A et D, les vecteurs {AB} et {CD} représentent les valeurs des dérivées en A et D. La cubique est tjrs inscrite dans le quadrilatère ABCD.

On peut les dessiner très facilement avec une méthode Diviser pour Régner. En effet, il existe une définition récursive simple. En posant A1=A et D2=D et en prenant les milieux:

et en considérant les courbes de Bézier pour A1 B1 C1 D1 et A2 B2 C2 D2, on obtient un tracé récursif. (Il suffit de s'arrêter pour un quadrilatère petit, ou mieux de petite hauteur).

Un expert est Lyle Ramshaw (DEC/SRC Tech Report 19). On en parle au cours Graphique de Puech et Sillion dans la majeure Math et Info, M1.

Exercices en TD