www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

rapport.tex (124163B)


      1 \documentclass{article}
      2 
      3 \usepackage[utf8]{inputenc}
      4 \usepackage[T1]{fontenc}
      5 \usepackage[frenchb]{babel}
      6 \usepackage{tikz}
      7 \usepackage{amsmath}
      8 \usepackage{listings}
      9 \usepackage{amssymb}
     10 \usepackage{pdfpages}
     11 \usetikzlibrary{chains,positioning,matrix,arrows,decorations,calc,fit}
     12 %\usepackage{hyperref}
     13 \usetikzlibrary{chains,positioning,matrix,arrows,decorations,calc}
     14 \title{Rapport de projet : FMIN105\\ Cours algorithmique / complexité / calculabilité}
     15 \author{\textsc{Bonavero} Yoann \\ \textsc{Brun} Bertrand \\ \textsc{Charron} John \\ \textsc{Dupéron} Georges}
     16 \date{}
     17 
     18 \lstset{
     19   language=C,    %% Preload
     20   language=Lisp, %% Preload + default
     21   showspaces=false,
     22   showstringspaces=false,
     23   showtabs=false,
     24   tabsize=4,
     25   columns=flexible% if this is not enough, use columns=fullflexible.
     26 }
     27 
     28 \setlength{\parindent}{0pt}
     29 \setlength{\parskip}{2ex}
     30 
     31 \newcounter{exocount}
     32 \setcounter{exocount}{0}
     33 
     34 \newcounter{enoncecount}
     35 \setcounter{enoncecount}{0}
     36 
     37 \newenvironment{enonce}
     38 {
     39 \stepcounter{enoncecount}
     40 \bf\small \arabic{enoncecount}.
     41 \begin{bf}
     42 }
     43 {
     44 \end{bf}
     45 }
     46 
     47 
     48 \newcounter{sousenoncecount}
     49 \setcounter{sousenoncecount}{0}
     50 \newenvironment{sousenonce}
     51 {
     52 \stepcounter{sousenoncecount}
     53 \bf\small (\alph{sousenoncecount})
     54 \begin{bf}
     55 }
     56 {
     57 \end{bf}
     58 }
     59 
     60 \begin{document}
     61 \includepdf{couverture.pdf}
     62 \setcounter{page}{0}
     63 \pagestyle{empty}
     64 \thispagestyle{empty}
     65 \tableofcontents
     66 \pagestyle{empty}
     67 \thispagestyle{empty}
     68 \newpage
     69 \pagestyle{plain}
     70 
     71 
     72 \section{Descriptif des tâches}
     73 Vos résultats seront présentés en procédant à la rédaction d'un mémoire dont la qualité influencera la note finale. Ce manuscrit sera rendu le jour de la soutenance. La soutenance consiste à présenter résultats pratiques (choix du langage, choix des structures de données, résultats obtenus, tests sur un grand jeu de données, analyse de ceux-ci ...). Vous aurez 15 minutes au maximum, questions comprises. Vous avez la possibilité d'utiliser des transparents.
     74 
     75 
     76 \section{Partie théorique}
     77 \subsection{Partie algorithmique}
     78 
     79 \subsubsection*{Exercice \stepcounter{exocount}\bf\small \arabic{exocount} -- Modélisation et résolution d'un problème d'ordonnancement par un problème de flot maximum : ordonnancement avec coûts dépendants des dates de début}
     80 \addcontentsline{toc}{subsubsection}{Exercice \arabic{exocount} -- Modélisation et résolution d'un problème d'ordonnancement par un problème de flot maximum : ordonnancement avec coûts dépendants des dates de début}
     81 
     82 
     83 
     84 \begin{figure}[h!]
     85   \centering
     86   \begin{tikzpicture}[node distance=3cm]
     87     \node (J1) {$J_{1}$};
     88     \node (J2) [above of=J1] {$J_{2}$};
     89     \node (J3) [right of=J1] {$J_{3}$};
     90     \draw[->] (J1) -- (J2);
     91     \draw[->] (J1) -- (J3);
     92     \draw[->] (J3) -- (J2);
     93   \end{tikzpicture}
     94   \caption{Graphe G}
     95   \label{fig:graphe-g}
     96 \end{figure}
     97 
     98 \begin{enonce}
     99 Construire le graphe $G^*$ pour $n = 3$, $T = 5$, $p_1 = 1$, $p_2 = 2$, $p_3 = 1$, 
    100 $E = \{(1,2), (1,3), (3,2)\}$ et les coûts suivants :
    101 \end{enonce}
    102 
    103 \begin{figure}[ht!]
    104   \centering
    105 	\begin{tabular}{cccccc}
    106 	\hline	
    107 	$i,t$ & 0 & 1 & 2 & 3 & 4\\
    108 	\hline
    109 	1 & 0 & 2 & 5 & 0 & 1\\
    110 	2 & 1 & 1 & 2 & 4 & -\\
    111 	3 & 1 & 10 & 2 & 3 & 3\\
    112 	\hline
    113 \end{tabular}
    114 \end{figure}
    115 
    116 \begin{figure}[ht!]
    117   \centering
    118   \colorlet{affectation}{green!75!black}
    119   \colorlet{auxiliaire}{black}
    120   \colorlet{précédence}{blue}
    121   \begin{tikzpicture}[
    122       affectation/.style = {
    123         draw=affectation,
    124         ->
    125       },
    126       auxiliaire/.style = {
    127         draw=auxiliaire,
    128         ->
    129       },
    130       précédence/.style = {
    131         draw=précédence,
    132         ->
    133       },
    134       capacité/.style = {
    135         fill=white,
    136         font=\footnotesize
    137       },
    138       capacité affectation/.style = {
    139         text=affectation,
    140         capacité
    141       },
    142       capacité auxiliaire/.style = {
    143         text=auxiliaire,
    144         capacité
    145       },
    146       capacité précédence/.style = {
    147         text=précédence,
    148         capacité
    149       }
    150     ]
    151     
    152     \matrix[matrix of math nodes, nodes in empty cells, row sep=1cm, column sep=0.9cm] (m) {
    153       & v_{1,0} & v_{1,1} & v_{1,2} & v_{1,3} & v_{1,4} & v_{1,5} & \\
    154       s & v_{3,0} & v_{3,1} & v_{3,2} & v_{3,3} & v_{3,4} & v_{3,5} & t \\
    155       & v_{2,0} & v_{2,1} & v_{2,2} & v_{2,3} & v_{2,4} & & \\
    156     };
    157     
    158     %% Penser a rajouter les J1, J2 et J3 a gauche du graphe.
    159     
    160   	\draw[affectation] (m-1-2)-- node[capacité affectation]{0} (m-1-3);
    161 	\draw[affectation] (m-1-3)-- node[capacité affectation]{2} (m-1-4);
    162 	\draw[affectation] (m-1-4)-- node[capacité affectation]{5} (m-1-5);
    163 	\draw[affectation] (m-1-5)-- node[capacité affectation]{0} (m-1-6);
    164 	\draw[affectation] (m-1-6)-- node[capacité affectation]{1} (m-1-7);
    165 
    166 	\draw[affectation] (m-2-2)-- node[capacité affectation]{1} (m-2-3);
    167 	\draw[affectation] (m-2-3)-- node[capacité affectation]{10} (m-2-4);
    168 	\draw[affectation] (m-2-4)-- node[capacité affectation]{2} (m-2-5);
    169 	\draw[affectation] (m-2-5)-- node[capacité affectation]{3} (m-2-6);
    170 	\draw[affectation] (m-2-6)-- node[capacité affectation]{3} (m-2-7);
    171 
    172 	\draw[affectation] (m-3-2)-- node[capacité affectation]{1} (m-3-3);
    173 	\draw[affectation] (m-3-3)-- node[capacité affectation]{1} (m-3-4);
    174 	\draw[affectation] (m-3-4)-- node[capacité affectation]{2} (m-3-5);
    175 	\draw[affectation] (m-3-5)-- node[capacité affectation]{4} (m-3-6);
    176 	
    177   	\draw[auxiliaire] (m-2-1)-- node[capacité auxiliaire]{$\infty$} (m-1-2);
    178   	\draw[auxiliaire] (m-2-1)-- node[capacité auxiliaire]{$\infty$} (m-2-2);
    179   	\draw[auxiliaire] (m-2-1)-- node[capacité auxiliaire]{$\infty$} (m-3-2);
    180   	\draw[auxiliaire] (m-1-7)-- node[capacité auxiliaire]{$\infty$} (m-2-8);
    181   	\draw[auxiliaire] (m-2-7)-- node[capacité auxiliaire]{$\infty$} (m-2-8);
    182   	\draw[auxiliaire] (m-3-6)--(m-3-7.center)-- node[capacité auxiliaire]{$\infty$} (m-2-8);
    183 	
    184 	\draw[précédence] (m-1-2)-- node[capacité précédence]{$\infty$} (m-2-3);
    185 	\draw[précédence] (m-1-3)-- node[capacité précédence]{$\infty$} (m-2-4);
    186 	\draw[précédence] (m-1-4)-- node[capacité précédence]{$\infty$} (m-2-5);
    187 	\draw[précédence] (m-1-5)-- node[capacité précédence]{$\infty$} (m-2-6);
    188 	\draw[précédence] (m-1-6)-- node[capacité précédence]{$\infty$} (m-2-7);
    189     
    190 	\draw[précédence] (m-2-2)-- node[capacité précédence]{$\infty$} (m-3-3);
    191 	\draw[précédence] (m-2-3)-- node[capacité précédence]{$\infty$} (m-3-4);
    192 	\draw[précédence] (m-2-4)-- node[capacité précédence]{$\infty$} (m-3-5);
    193 	\draw[précédence] (m-2-5)-- node[capacité précédence]{$\infty$} (m-3-6);
    194 
    195 	\draw[précédence] (m-1-2)-- node[capacité précédence,pos=0.3]{$\infty$} (m-3-3);
    196 	\draw[précédence] (m-1-3)-- node[capacité précédence,pos=0.3]{$\infty$} (m-3-4);
    197 	\draw[précédence] (m-1-4)-- node[capacité précédence,pos=0.3]{$\infty$} (m-3-5);
    198 	\draw[précédence] (m-1-5)-- node[capacité précédence,pos=0.3]{$\infty$} (m-3-6);
    199   \end{tikzpicture}
    200   \caption{Graphe $G^*(X^*, E^*)$}
    201   \label{fig:graphe-g*}
    202 \end{figure}
    203 
    204 
    205 
    206 \begin{enonce}
    207 Montrer qu'il existe une coupe dans $G^*$ de capacité minimale de laquelle sort un et un seul arc d'affectation par job.
    208 \end{enonce}
    209 
    210 Démonstration par construction~: 
    211 On effectue un tri topologique sur le graphe des contraintes de précédence $G(\{J_1, \dots, J_n\}, E)$. Ce tri topologique nous donne un
    212 ensemble ordonné de n\oe uds $(J_{a1}, \dots, J_{an})$. On a donc~:
    213 $$\forall j < i \quad (J_{aj}, J_{ai}) \not\in E$$
    214 On transforme ensuite $G$ en un graphe de flots $G^*(X^*,E^*)$ à l'aide de l'algorithme fourni dans le sujet. 
    215 Considérons les arcs entre les $v_{ai,t}$~: 
    216 \begin{itemize}
    217 	\item Arcs d'affectation~: ces arcs sont entre des sommets $v_{ai,t}$ et $v_{aj,t'}$ avec $ai = aj$
    218 	\item Arcs de précédences~: ces arcs sont entre des sommets $v_{ai,t}$ et $v_{aj,t'}$ avec $ai < aj$, car grâce au tri topologique, il
    219       n'existe pas d'arcs entre des sommets $J_{ai}$ et $J_{aj}$ avec $aj < ai$, et de plus il n'y a pas de boucle (donc pas d'arc
    220       $(J_{ai},J_{ai})$ dans $E$, donc pas d'arc $(v_{ai,t}, v_{ai,t'})$ dans $E^*$).
    221 	\item Arcs auxiliaires~: ces arcs ne sont pas entre des sommets $v_{ai,t}$.
    222 \end{itemize}
    223 
    224 Soit un $(s-t)-\mathrm{coupe}$ minimale, entre les ensembles de noeuds $S$ et $T$. Etant donné que cette coupe est minimale, aucun arc de
    225 capacité infinie n'a son origine dans $S$ et son extremité dans $\overline{S}$. Autrement dit, en fonction des noeuds présents dans S, on
    226 est donc \og obligé\fg{} d'inclure dans $S$ toutes les extrémités des arcs de capacité infinie et dont l'origine est dans $S$. On va donc
    227 construire $S$ itérativement en suivant cette règle.
    228 
    229 \begin{itemize}
    230 \item $s \in S$ et tous les arcs sortants de $s$ sont les arcs auxiliaires de capacité infinie qui pointent sur tous les $v_{ai,0}$. On
    231   les inclut donc dans $S$.
    232 \item Pour chaque $v_{ai,t}$ dans $S$ on n'a pas besoin de suivre les arcs d'affectation car ils sont de capacité finie. Comme ces arcs
    233   d'affectation \og restent sur la même ligne\fg, à partir du moment où un $v_{ai,t}$ est présent dans $S$, les arcs d'affectation ne nous
    234   obligent pas à inclure les $v_{ai,t'}$ avec $t' > t$.
    235 \item Par contre les arcs de précédence nous obligent, lorsqu'on inclut un $v_{ai,t}$, d'inclure tous les $v_{aj,t'}$ qui sont à l'extrêmité
    236   d'un arc de précédence partant de ce $v_{ai,t}$.
    237 \end{itemize}
    238 
    239 Puisque la coupe est minimale et que tous les $v_{ai,0}$ font partie de $S$, lorsqu'un $v_{ai,t}$ fait partie de S, alors tous les
    240 $v_{ai,t'}$ avec $0 \leq t' \leq t$ font aussi partie de $S$ (car sinon on ajoute le coût des arcs d'affectation intermédiaires).
    241 
    242 On a donc $s \in S$ et
    243 \begin{equation}
    244 \forall ai \quad \exists t \quad (0 <= t' <= t) \Leftrightarrow (v_{ai,t} \in S)
    245 \label{eq:tous-t-debut-ligne}
    246 \end{equation}
    247 
    248 Il ne sort donc qu'un et un seul arc d'affectation par job dans toute coupe minimale.
    249 
    250 Évidemment, cette coupe minimale ne peut exister que s'il y a «suffisemment de temps pour tout faire», autrement dit, si la somme des durées
    251 d'exécution des tâches est supérieure au temps disponible, on ne pourra pas effectuer toutes les tâches.
    252 
    253 \begin{enonce}
    254 Montrer que l'on peut associer un ordonnancement réalisable (qui respecte toutes les contraintes) à toute 
    255 coupe de capacité finie minimale dans le graphe. Quel est le coût de cet ordonnancement ? 
    256 \end{enonce}
    257 
    258 Dans l'exercice précédent, on a montré que de toute coupe minimale sort un et un seul arc d'affectation par job.
    259 
    260 On cherche à associer un ordonancement réalisable à toute coupe minimale.
    261 
    262 On va construire cet ordonancement de la manière suivante~: à chaque
    263 fois qu'un arc d'affectation $v_{ai,t}, v_{ai,t+1}$ traverse la coupe,
    264 on exécute le job $ai$ à l'instant $t$ dans l'ordonancement. 
    265 
    266 \textbf{Cherchons un ordonancement}, un ensemble de paires $(\text{tâche},\text{date de début})$ respectant les dépendances.
    267 Autrement dit, chaque tâche apparaît après ses dépendances dans la suite.
    268 
    269 Soit $te(ai) = t$ la fonction qui à un job $ai$ associe son temps de début d'exécution $t$.
    270 Nous allons montrer que~:
    271 $$(\exists ai,t,aj,t' \quad (v_{ai,t},v_{aj,t'}) \in E^*) \qquad \Rightarrow \qquad (te(ai) > te(aj) \quad \Leftrightarrow \quad ai > aj)$$
    272 Cela signifie que s'il existe un arc de précédence entre deux noeuds, alors le job qui
    273 correspond au noeud «le plus haut» s'exécute avant le job qui correspond au
    274 noeud «le plus bas».
    275 
    276 En effet, si $t = te(ai)$ est le temps de début d'exécution du job $ai$, alors c'est que $v_{ai,t}, v_{ai,t+1}$
    277 traverse la coupe, et donc :
    278 \begin{equation}
    279   \forall tt \quad v_{ai,tt} \in S \Leftrightarrow tt <= t
    280   \label{eq:tous-t-avant-exec}
    281 \end{equation}
    282 
    283 Il en va de même pour $\forall tt' <= t' \quad v_{aj,tt'} \in S$.
    284 
    285 Comme il y a un arc d'affectation du job $ai$ vers le job $aj$,
    286 $$\exists\ {} tdest > t \quad (v_{ai,t},v_{aj,tdest}) \in E^*$$
    287 et vu que la capacité de cet arc de précédence est infinie, $tdest \in S$. En utilisant les équations \ref{eq:tous-t-debut-ligne} et
    288 \ref{eq:tous-t-avant-exec}, on peut affirmer que $tdest <= t$. Nous avons donc bien montré que l'arc d'affectation entre la tâche $ai$ et la
    289 tâche $aj$ «forçait» $aj$ à s'exécuter après $ai$.
    290 
    291 Grâce au tri topoligique, nous pouvons affirmer que tous les arcs de précédence entrants dans le noeud $v_{ai,te(ai)}$ viennent d'une ligne
    292 «plus haute», autrement dit d'un noeud $v_{aj,t'}$ avec $aj < ai$. Et grâce à ce que nous avons prouvé précédemment,
    293 on sait que $te(aj) < te(ai)$.
    294 
    295 \textbf{On cherche un ordonancement réalisable}, c'est-à-dire pour lequel
    296 toutes les tâches peuvent être menées à bout durant le temps
    297 imparti.
    298 
    299 
    300 La propriété énoncée dans la question 2 de l'exercice 1 nous indique que de toute coupe minimale sort un et un seul arc d'affectation par
    301 job. Cela signifie que chaque job a commencé à être exécuté. Comme il exite un noeud pour le job $aj$ à l'instant $t$ si et seulement s'il y
    302 a le temps de l'exécuter (\ogà chaque date de début possible\fg), cela signifie que tous les jobs commencés ont eu le temps d'être terminés
    303 et, comme nous venons de voir, que tous les jobs ont pu être commencés -- ils ont tous pu être terminés -- et, par conséquent,
    304 l'ordonancement est réalisable.
    305 
    306 \begin{enonce}
    307 Montrer qu'à tout ordonnancement réalisable correspond une coupe dont la capacité est égale au coût de l'ordonnancement.
    308 \end{enonce}
    309 
    310 On construit la coupe à partir de l'ordonancement de la même manière
    311 qu'on a construit l'ordonancement à partir de la coupe dans l'exercice
    312 précédent, mais en suivant l'algorithme dans l'autre sens.
    313 
    314 Si on exécute le job $ai$ à l'instant $t$ dans l'ordonancement, alors
    315 tous les noeuds $v_{ai,t'}$ avec $t' \leq t$ sont dans la partie \og
    316 gauche\fg{} de la coupe. De plus, $s$ appartient lui aussi à la partie
    317 gauche de la coupe et aucun arc de précédence ne sort de la coupe.
    318 
    319 La capacité de cette coupe est la somme de la capacité de tous les
    320 arcs qui sortent de la coupe, c'est-à-dire la somme des capacités des
    321 arcs $v_{ai,t}, v_{ai,t+1}$. Comme la capacité de ces arcs est égale au
    322 coût d'exécution de la tâche $ai$ à l'instant $t$, on a bien égalité entre
    323 la somme des capacités et la somme des coûts de démarrage des jobs,
    324 donc la capacité de la coupe est égale au coût de l'ordonancement.
    325 
    326 
    327 \subsubsection*{Exercice \stepcounter{exocount}\bf\small \arabic{exocount} -- Coupes et chemins arc-disjoints}
    328 \addcontentsline{toc}{subsubsection}{Exercice \arabic{exocount} -- Coupes et chemins arc-disjoints}
    329 \setcounter{enoncecount}{0}
    330 
    331 \begin{enonce}
    332 Calculer le nombre maximum des chemins d'arcs disjoints à partir de la source jusqu'au puits dans le réseau donné par la figure 1. 
    333 \end{enonce}
    334 
    335 Il existe un ensemble de chemins d'arcs disjoints de cardinal 3~:
    336 
    337 $$
    338 \begin{array}{ccccccc}
    339   1 & \rightarrow & 2 & \rightarrow & 3 & \rightarrow & 6 \\
    340   1 & \rightarrow & 3 & \rightarrow & 4 & \rightarrow & 6 \\
    341   1 & \rightarrow & 4 & \rightarrow & 5 & \rightarrow & 6 \\
    342 \end{array}
    343 $$
    344 
    345 Cherchons s'il en existe un de cardinal 4. Voici la liste des chemins
    346 obtenue par un parcours en profondeur (en prennant toujours en premier
    347 les sommets voisins avec le numéro le plus petit possible)~:
    348 
    349 %% TODO~: numéroter les "équations" «proprement». Mais il semble que LaTeX ne permette pas de numéroter les lignes d'une matrice sans se casser la tête :-(
    350 %% Ou sinon, il faut utilise \begin{align}/\end{align}, mais On ne peut pas choisir l'espacement des colonnes (et il est beaucoup trop gros à ce moment-là.
    351 $$
    352 \begin{array}{cccccccccccr}
    353   1 & \rightarrow & 2 & \rightarrow & 3 & \rightarrow & 4 & \rightarrow & 5 & \rightarrow & 6 & \quad (A) \\
    354   1 & \rightarrow & 2 & \rightarrow & 3 & \rightarrow & 4 & \rightarrow & 6 &             &   & \quad (B) \\
    355   1 & \rightarrow & 2 & \rightarrow & 3 & \rightarrow & 6 &             &   &             &   & \quad (C) \\
    356   1 & \rightarrow & 3 & \rightarrow & 4 & \rightarrow & 5 & \rightarrow & 6 &             &   & \quad (D) \\
    357   1 & \rightarrow & 3 & \rightarrow & 4 & \rightarrow & 6 &             &   &             &   & \quad (E) \\
    358   1 & \rightarrow & 3 & \rightarrow & 6 &             &   &             &   &             &   & \quad (F) \\
    359   1 & \rightarrow & 4 & \rightarrow & 5 & \rightarrow & 6 &             &   &             &   & \quad (G) \\
    360   1 & \rightarrow & 4 & \rightarrow & 6 &             &   &             &   &             &   & \quad (H) \\
    361 \end{array}
    362 $$
    363 
    364 Voyons les ensembles qui contiennent le chemin $A$~: On ne peut pas
    365 prendre les chemins $B$ et $C$ car ils ont l'arc $(1,2)$ en commun
    366 avec $A$. On ne peut pas prendre non plus les chemin $D$ et $G$ car
    367 ils ont l'arc $(5,6)$ en commun avec $A$ ni le chemin $E$ à cause de
    368 l'arc $(3,4)$. Il ne reste plus que les chemins $F$ et $H$ qu'on
    369 pourrait peut-être prendre si on prend $A$, mais le cardinal de
    370 l'ensemble serait alors 3, donc on n'améliorerait pas le résultat
    371 existant. En conséquence, ce n'est pas la peine de chercher si ces chemins
    372 sont \og compatibles\fg{} avec $A$.
    373 
    374 Procédons de la même manière pour $B$ (sachant que $A$ ne peut pas
    375 faire partie de l'ensemble). Si on a le chemin $B$, alors on ne peut
    376 pas avoir~:
    377 \begin{itemize}
    378   \item $C$ (arc $(2,3)$),
    379   \item $D$ (arc $(3,4)$),
    380   \item $E$ (arc $(3,4)$),
    381   \item $H$ (arc $(4,6)$).
    382 \end{itemize}
    383 À partir de ce moment, il ne reste plus que $F$ et $G$, l'ensemble
    384 serait de cardinal 3, donc $B$ ne peut pas être dans un ensemble de
    385 cardinal 4.
    386 
    387 Passons à $D$ avec $A$ et $B$ exclus. On ne peut pas avoir~:
    388 \begin{itemize}
    389 \item $E$ (arc $(3,4)$),
    390 \item $F$ (arc $(1,3)$),
    391 \item $G$ (arc $(4,5)$).
    392 \end{itemize}
    393 Donc $D$ n'est pas dans l'ensemble.
    394 
    395 Passons à $F$ avec $A,B,D$ exclus. On ne peut pas avoir~:
    396 \begin{itemize}
    397 \item $C$ (arc $(3,6)$),
    398 \item $E$ (arc $(1,3)$).
    399 \end{itemize}
    400 Donc $F$ n'est pas dans l'ensemble.
    401 
    402 Comme $A,B,D,F$ ne sont pas dans l'ensemble et que nous avons
    403 seulement 8 candidats, la seule possibilité qui reste pour un ensemble
    404 de cardinal 4 est $C,E,G,H$. Or, dans cet ensemble, l'arête $(1,4)$
    405 est commune à $G$ et $H$, donc on ne peut pas construire un ensemble
    406 de chemins d'arcs disjoints de taille 4 ni de taille supérieure
    407 à 4.
    408 
    409 Conclusion~: Le nombre maximum de chemins d'arcs disjoints est 3.
    410 
    411 \begin{enonce}
    412 Enumérer tous les s-t-coupes dans le réseau donnés par la figure 1. Pour chaque s-t-coupe $[S,\overline{S}]$, énumérer les sommets, les arcs avants et les arcs arrières.
    413 \end{enonce}
    414 
    415 % Code LISP pour générer le tableau ci-après :
    416 
    417 % (defun S (n p)
    418 %   (if p
    419 %       (format t "         ~a  " n)
    420 %       (format t "\\phantom{~a} " n)))
    421 
    422 % (defun Sbar (n p)
    423 %   (S-n-p n (not p)))
    424 
    425 % (defun print-arcs (arcs)
    426 %   (when arcs
    427 %     (when (car arcs)
    428 %       (format t "(~a,~a)" (caar arcs) (cdar arcs))
    429 %       (unless (endp (cdr arcs))
    430 %         (format t ", ")))
    431 %     (print-arcs (cdr arcs))))
    432 
    433 % (defun print-arcs-if-not-nil (arcs)
    434 %   (print-arcs (remove-if-not #'identity arcs)))
    435 
    436 % (defun print-line (l nodes edges)
    437 %   (let ((num-and-pred (pairlis nodes (mapcar #'list l))))
    438 %     ;; (cdr (butlast)) pour ne pas imprimer les 1ers et derniers qui sont fixes.
    439 %     (format t "~a " (car nodes))
    440 %     (mapcar #'S (cdr (butlast nodes)) (cdr (butlast l)))
    441 %     (format t "& ")
    442 %     (mapcar #'Sbar (cdr (butlast nodes)) (cdr (butlast l)))
    443 %     (format t "~a " (car (last nodes)))
    444 %     (format t "& ${")
    445 %     (print-arcs-if-not-nil
    446 %      (mapcar (lambda (arc)
    447 %                (and (cadr (assoc (car arc) num-and-pred))
    448 %                     (not (cadr (assoc (cdr arc) num-and-pred)))
    449 %                     arc))
    450 %              edges))
    451 %     (format t "}$ & ${")
    452 %     (print-arcs-if-not-nil
    453 %      (mapcar (lambda (arc)
    454 %                (and (cadr (assoc (cdr arc) num-and-pred))
    455 %                     (not (cadr (assoc (car arc) num-and-pred)))
    456 %                     arc))
    457 %              edges))
    458 %     (format t "}$ \\\\~%")))
    459 
    460 % (defun range (n)
    461 %   (loop for i from 0 below n collect i))
    462 
    463 % (defun print-s-t-cuts (nodes edges)
    464 %   (loop
    465 %      for i from 0 below (expt 2 (- (length nodes) 2))
    466 %      do (print-line (append
    467 %                      '(t) ;; Source : toujours t
    468 %                      (mapcar (lambda (n)
    469 %                                (/= 0 (logand i (expt 2 n))))
    470 %                              (range (- (length nodes) 2)))
    471 %                      '(nil)) ;; Target : toujours nil
    472 %                     nodes
    473 %                     edges)))
    474 
    475 % (print-s-t-cuts
    476 %  '(1 2 3 4 5 6)
    477 % '((1 . 2)
    478 %   (1 . 3)
    479 %   (1 . 4)
    480 %   (2 . 3)
    481 %   (3 . 4)
    482 %   (3 . 6)
    483 %   (4 . 5)
    484 %   (4 . 6)
    485 %   (5 . 6)))
    486 
    487 \begin{tabular}{|l|l|l|l|}
    488   \hline
    489   $S$ & $\overline{S}$ & Arcs avants & Arcs arrières \\
    490   \hline
    491   \hline
    492   1 \phantom{2} \phantom{3} \phantom{4} \phantom{5} &          2           3           4           5  6 & ${(1,2), (1,3), (1,4)}$               & ${}$             \\
    493   1          2  \phantom{3} \phantom{4} \phantom{5} & \phantom{2}          3           4           5  6 & ${(1,3), (1,4), (2,3)}$               & ${}$             \\
    494   1 \phantom{2}          3  \phantom{4} \phantom{5} &          2  \phantom{3}          4           5  6 & ${(1,2), (1,4), (3,4), (3,6)}$        & ${(2,3)}$        \\
    495   1          2           3  \phantom{4} \phantom{5} & \phantom{2} \phantom{3}          4           5  6 & ${(1,4), (3,4), (3,6)}$               & ${}$             \\
    496   1 \phantom{2} \phantom{3}          4  \phantom{5} &          2           3  \phantom{4}          5  6 & ${(1,2), (1,3), (4,5), (4,6)}$        & ${(3,4)}$        \\
    497   1          2  \phantom{3}          4  \phantom{5} & \phantom{2}          3  \phantom{4}          5  6 & ${(1,3), (2,3), (4,5), (4,6)}$        & ${(3,4)}$        \\
    498   1 \phantom{2}          3           4  \phantom{5} &          2  \phantom{3} \phantom{4}          5  6 & ${(1,2), (3,6), (4,5), (4,6)}$        & ${(2,3)}$        \\
    499   1          2           3           4  \phantom{5} & \phantom{2} \phantom{3} \phantom{4}          5  6 & ${(3,6), (4,5), (4,6)}$               & ${}$             \\
    500   1 \phantom{2} \phantom{3} \phantom{4}          5  &          2           3           4  \phantom{5} 6 & ${(1,2), (1,3), (1,4), (5,6)}$        & ${(4,5)}$        \\
    501   1          2  \phantom{3} \phantom{4}          5  & \phantom{2}          3           4  \phantom{5} 6 & ${(1,3), (1,4), (2,3), (5,6)}$        & ${(4,5)}$        \\
    502   1 \phantom{2}          3  \phantom{4}          5  &          2  \phantom{3}          4  \phantom{5} 6 & ${(1,2), (1,4), (3,4), (3,6), (5,6)}$ & ${(2,3), (4,5)}$ \\
    503   1          2           3  \phantom{4}          5  & \phantom{2} \phantom{3}          4  \phantom{5} 6 & ${(1,4), (3,4), (3,6), (5,6)}$        & ${(4,5)}$        \\
    504   1 \phantom{2} \phantom{3}          4           5  &          2           3  \phantom{4} \phantom{5} 6 & ${(1,2), (1,3), (4,6), (5,6)}$        & ${(3,4)}$        \\
    505   1          2  \phantom{3}          4           5  & \phantom{2}          3  \phantom{4} \phantom{5} 6 & ${(1,3), (2,3), (4,6), (5,6)}$        & ${(3,4)}$        \\
    506   1 \phantom{2}          3           4           5  &          2  \phantom{3} \phantom{4} \phantom{5} 6 & ${(1,2), (3,6), (4,6), (5,6)}$        & ${(2,3)}$        \\
    507   1          2           3           4           5  & \phantom{2} \phantom{3} \phantom{4} \phantom{5} 6 & ${(3,6), (4,6), (5,6)}$               & ${}$             \\
    508   \hline
    509 \end{tabular}
    510 
    511 \begin{enonce}
    512 Vérifier que le nombre maximum de chemins d'arcs disjoints à partir du sommet source jusqu'au puits est égal au nombre minimum d'arcs avant dans une s-t-coupe.
    513 \end{enonce}
    514 
    515 D'après notre conclusion de la question 1, on  a uniquement trois chemins d'arcs disjoints et d'après le tableau de la question 2, on constate que le nombre minimum d'arcs avant est de 3. On peut donc vérifier que le nombre maximum d'arcs disjoints est égal au nombre minimum d'arcs avants. 
    516 
    517 \subsection{Partie complexité}
    518 
    519 \subsubsection*{Exercice \stepcounter{exocount}\bf\small \arabic{exocount} -- Sur quelques réductions}
    520 \addcontentsline{toc}{subsubsection}{Exercice \arabic{exocount} -- Sur quelques réductions}
    521 \setcounter{enoncecount}{0}
    522 
    523 \begin{enonce}
    524 On vous demande de rappeler la réduction de SAT à 3-SAT.
    525 \end{enonce}
    526 
    527 \begin{sousenonce}
    528 Enoncer SAT et 3-SAT.
    529 \end{sousenonce}
    530 
    531 SAT est une abbrévation pour 'problème de satisfiabilité'. En logique propositionnelle, résoudre un problème SAT consiste à déterminer s'il existe une assignation des variables booléennes telle qu'une formule logique sous forme normale conjonctive s'évalue à vrai. Si tel est le cas, la formule est dite 'satisfiable', sinon elle est 'insatisfiable'. Etant donné le résultat booléen ('satisfiable' ou 'insatisfiable') de ce genre de problème, il s'agit bien d'un problème de décision.  
    532 
    533 On appelle 2-sat un problème dont chaque clause de la formule logique en question contient au plus 2 littéraux, 3-sat un problème SAT dans lequel chaque clause de la formule logique en question contient au plus 3 littéraux. Un problème 2-sat est polynomial et NL-complet alors qu'un problème 3-sat est NP-complet.
    534 
    535 Un exemple d'un problème 3-SAT est le suivant :
    536 
    537 $(v_{1} \vee v_{2} \vee v_{3}) \wedge (v_{4} \vee v_{5} \vee v_{6}) \wedge (v_{7} \vee v_{8} \vee v_{9}) \wedge$ ...	
    538 
    539 où chaque v est une variable ou la négation d'une variable, chaque variable pouvant figurer plusieurs fois dans l'expression. 
    540 
    541 \begin{sousenonce}
    542 Définir la réduction.
    543 \end{sousenonce}
    544 
    545 En théorie de complexité, une 'réduction' est la transformation d'un problème en un autre problème. Selon la transformation utilisée, la réduction peut être utilisée afin de définir une classe de complexité à un ensemble de problèmes. Problème A est réductible à Problème B si les solutions au Problème B existent et donnent des solutions au Problème A à chaque fois que A a des solutions. Par conséquent, la solution de A ne peut pas être plus difficile que la solution de B. 
    546 
    547 Il peut être utile de résoudre un problème qui est similaire à un problème que l'on a déjà résolu. Dans ce cas, une méthode efficace de résoudre le nouveau problème est de transformer chaque instance du nouveau problème en une instance d'un problème que l'on sait résoudre et puis de résoudre chaque instance à l'aide de solutions existantes afin d'obtenir une solution finale. Une autre stratégie est de subdiviser un problème en plusieurs sous-problèmes que l'on sait résoudre, d'où le terme 'réduction'.
    548 
    549 Une autre application des 'réductions' est son application aux problèmes qui sont difficiles à résoudre. Lorsque l'on a un problème qui a été prouvé difficile à résoudre et que nous avons un nouveau problème similaire, nous pouvons faire l'hypothèse que le nouveau problème, lui aussi, est difficile à résoudre. Le raisonnement est l'inverse de celui des problèmes qui peuvent être résolu aisément. 
    550 
    551 Un exemple simple est de passer de la multiplication à la quadrature. Supposons que nous ne sommes capable que d'effectuer l'addition, la soustraction la quadrature et la division. Avec ces quatre opérations, nous pouvons trouver le produit de deux nombres quelconques :
    552 
    553 
    554 $$(a \times b) = \dfrac{(a + b)^2 - a^2 - b^2}{2}$$
    555 
    556 
    557 Lorsqu'il est possible de réduire un problème difficile en un problème que l'on sait résoudre, la difficulté demeure souvent dans la réduction elle-même.
    558 
    559 Pour la réduction de SAT à 3-SAT, on prend chaque clause de littéraux du problème SAT et on la transforme en une ou plusieurs clauses de la manière suivante~:
    560 
    561 \begin{itemize}
    562 \item Si la clause possède 3 littéraux ou moins, on la laisse telle quelle. Elle est déjà sous forme 3-SAT.
    563 \item Sinon, soient $l_1, \dots, l_n$ les littéraux de la clause, on construit plusieurs clauses ainsi~:
    564 $$
    565 (l_1, l_2, z_1), (\lnot z_1, l_3, z_2), (\lnot z_2, l_4, z_3), \dots, (\lnot z_{i-2}, l_{i}, z_{i-1}), \dots, (\lnot z_{n-3}, l_{n-1}, l_{n})
    566 $$
    567 \end{itemize}
    568 
    569 Les littéraux $z_i$, qui n'était pas présents dans la clause d'origine, sont ajoutés afin de pouvoir subdiviser une clause en deux ou
    570 plusieurs clauses et afin de les relier. Par exemple, la clause $(a \vee \lnot b \vee c \vee d)$ sera transformée en deux clauses~: $(a
    571 \vee \lnot b \vee z_1) \wedge (\lnot z_1 \vee c \vee d)$ ; la clause ${\lnot a \vee b \vee \lnot c \vee d \vee e}$ sera transformée en trois
    572 clauses, à savoir $(\lnot a \vee b \vee z_1) \wedge (\lnot z_1 \vee \lnot c \vee z_2) \wedge (\lnot z_2 \vee d \vee e)$.
    573 
    574 L'ensemble des clauses ainsi créées sont équivalentes à l'ensemble des clauses d'origines correspondant car, à chaque fois, soit un des littéraux d'origine vérifie la clause et $z_i$ peut être faux, ce qui permet à $\lnot z_i$ de valider la clause suivante, de proche en proche, soit aucun des littéraux d'origine ne vérifie la clause, auquel cas, si on prend un $z_i$ faux, la clause est fausse, et si on prend un $z_i$ vrai, la clause suivante 
    575 contiendra $\lnot z_i$ qui sera faux, et le résultat dépendra des littéraux de la ou des clause(s) suivante(s).
    576 
    577 Si l'on souhaite que le résultat soit strictement 3-SAT (toutes les clauses contenant exactement 3 littéraux, on applique les transformations suivantes~:
    578 \begin{itemize}
    579 \item Les clauses qui contiennent un seul littéral, ${l_1}$, sont transformées en ${l_1, l_1, l_1}$.
    580 \item Les clauses qui contiennent exactement deux littéraux, ${l_1, l_2}$ sont transformées en ${l_1, l_2, l_1}$.
    581 \end{itemize}
    582 
    583 Cette transformation est linéaire en complexité. En effet, on ne considère chaque littéral qu'une fois et on ajoute $n-3$ littéraux pour chaque clause. Il s'agit de complexité polynomiale.
    584 
    585 \begin{sousenonce}
    586 Justifier alors que 3-SAT est NP-complet (sachant que SAT est NP-complet).
    587 \end{sousenonce}
    588 
    589 Vu que SAT est np-complet et que 3-SAT sait faire ce que sait faire SAT, avec une transformation polynomiale, 3-SAT (y compris la transformation) est au moins aussi dur que SAT. La difficulté peut résider dans la transformation 3-SAT ou les deux.
    590 
    591 Vu que la difficulté ne s'est pas cachée dans la transformation, qui est polynomiale alors que SAT est np-complet, 3-SAT est np-complet lui aussi.  
    592 
    593 \begin{sousenonce}
    594   Application : si un ensemble de clauses contient $n_v$ variables, $n_1$ clauses à un littéral, $n_2$ clauses à 2 littéraux, $n_3$ clauses
    595   à 3 littéraux, $n_4$ clauses à 4 littéraux, $n_5$ clauses à 5 littéraux (et pas d'autres clauses), combien le système obtenu par votre
    596   réduction contient-il de variables et de clauses ? Vous devrez bien sûr justifier votre réponse.
    597 \end{sousenonce}
    598 
    599 Le système obtenu par la réduction contient :
    600 \begin{itemize}
    601 \item Une variable supplémentaire pour chaque clause à 4 littéraux.
    602 \item Deux variables supplémentaires pour chaque clause à 5 littéraux.
    603 \item Soit au total $n_v + n_4 + 2n_5$ variables.
    604 \end{itemize}
    605 
    606 De plus, les expansions sont les suivantes :
    607 \begin{itemize}
    608 \item Un littéral : 1 clause
    609 \item Deux littéraux : 1 clause
    610 \item Trois littéraux : 1 clause
    611 \item Quatre littéraux : 2 clauses
    612 \item Cinq littéraux : 3 clause
    613 \item Soit au total $n_1 + n_2 + n_3 + 2n_4 + 3n_5$ clauses.
    614 \end{itemize}
    615 
    616 
    617 
    618 \begin{enonce}
    619 Pourquoi le principe de la réduction ne permet-il pas de réduire 3-SAT à 2-SAT et de prouver que 2-SAT est NP-complet ? (Il ne s'agit pas
    620 d'expliquer pourquoi 2-SAT n'est pas NP-complet, mais pourquoi cette réduction ne marche pas).
    621 \end{enonce}
    622 
    623 Tentons de réduire la clause $(a \vee b \vee c)$ de manière similaire à l'algorithme donné pour la réduction de SAT à 3-SAT~. 
    624 
    625 On a $(a \vee z_1) \wedge (\lnot z_1 \vee b)$. A partir de là, on ne peut insérer de variable permettant de faire la liaison entre la clause
    626 qui contient $b$ et celle qui contient $c$, donc on ne peut pas appliquer cette réduction.
    627 
    628 \begin{enonce}
    629 Il s'agit de prouver que 2-SAT est un problème polynomial. Vous avez un article en français expliquant cette preuve à \\ http://philippe.gambette.free.fr/SCOL/Graphes
    630 \end{enonce}
    631 \setcounter{sousenoncecount}{0}
    632 
    633 \begin{sousenonce}
    634   Vous commencerez par fabriquer trois ensembles de deux clauses, le premier valide, le deuxième insatisfiable et le troisième contingent,
    635   et pour chacun de ces ensembles de clauses vous construirez le graphe correspondant. Vous expliquerez comment apparaît sur chacun des
    636   trois graphes la validité de l'ensemble de clauses corresponsdantes.
    637 \end{sousenonce}
    638 
    639 Philippe Gambette, dans son article intitulé 'Un graphe pour résoudre 2-SAT', donne une explication succincte de l'agorithme d'Aspvall, Plass et Tarjan.
    640 
    641 Une formule logique en forme normale conjonctive contenant des clauses à deux littéraux est transformé en un problème de graphe orienté. On
    642 doit tout d'abord établir si la formule admet un modèle, et ensuite, si tel est le cas, donner un modèle quelconque.
    643 
    644 \begin{enumerate}
    645 \item L'algorithme de construction de graphe : 
    646 \begin{enumerate}
    647 \item On crée un graphe avec $2n$ sommets ($n$ étant ici le nombre littéraux distincts de la formule) contenant tous les littéraux de la
    648   formule ainsi que les négations de ces littéraux.
    649 \item On prend chaque clause de la formule que l'on traduit en implications dans les deux sens : $(a \vee b)$ 
    650 se transforme en deux clauses : $(\neg a \Rightarrow b)$ et ($\neg b \Rightarrow a)$.
    651 \item On crée des arcs correspondant aux implications créées à l'étape précédente (arc ($\neg a 
    652 \rightarrow b$) et ($\neg b \rightarrow a$))
    653 \end{enumerate}
    654 \item On effectue un tri topologique en numérotant les sommets de $1$ à $n$.
    655 \item En ordre inverse, du sommet $n$ au sommet $1$ du graphe, on affecte à tout noeud $x$ la valeur VRAI et au noeud $\neg x$ la valeur
    656   FAUX, c'est-à-dire dans l'ordre inverse du tri topologique.
    657 \end{enumerate}  	
    658 
    659 S'il existe une composante fortement connexe contenant un littéral et sa négation, la formule est insatisfiable étant donné qu'on a $x_{i}
    660 \Leftrightarrow \neg x_{i}$ sinon, la formule est satisfiable, c'est-à-dire soit contingente soit valide. L'algorithme ne nous donne aucune
    661 information pour distinguer une formule contingente et une formule valide, il nous donne une ou deux informations : (1) il nous dit si la
    662 formule admet un modèle, et (2) si oui, il nous donne un modèle~: le modèle est assuré car le graphe en question ne contient aucun arc $VRAI
    663 \rightarrow FAUX$.
    664 
    665 Prenons trois exemples~: une formule insatisfiable, une formule contingente et une formule valide.
    666 
    667 \begin{figure}[ht!]
    668   \centering
    669   \begin{tikzpicture}[
    670       node distance=2.5cm,
    671       lettre/.style={
    672         draw,
    673         circle,
    674         minimum size=1cm
    675       }
    676     ]
    677     \node[lettre] (nx1) {$\lnot x_1$} ;
    678     \node[lettre, below of=nx1] (x1) {$x_1$} ;
    679     \node[coordinate,xshift=0.1cm] (x1r) at (x1.north) {};
    680     \node[coordinate,xshift=-0.1cm] (x1l) at (x1.north) {};
    681     \node[coordinate,xshift=0.1cm] (nx1r) at (nx1.south) {};
    682     \node[coordinate,xshift=-0.1cm] (nx1l) at (nx1.south) {};
    683     \draw[->] (x1r) -- (nx1r);
    684     \draw[->] (nx1l) -- (x1l);
    685 
    686   \end{tikzpicture}
    687   \caption{Clause insatisfiable : $(x_{1} \vee x_{1}) \wedge (\neg x_{1} \vee \neg x_{1})$}
    688   \label{fig:clause-insat}
    689 \end{figure}
    690 
    691 \paragraph*{Clause insatisfiable $(x_{1} \vee x_{1}) \wedge (\neg x_{1} \vee \neg x_{1})$~:}
    692 
    693 Le résultat de l'application de l'algorithme décrit ci-dessus est un graphe orienté cyclique. Il est impossible d'effectuer un tri
    694 topologique étant donné qu'un tri topologique ne peut être effectué que sur un graphe acyclique orienté. Ce graphe contient un composant
    695 fortement connexe contenant un littéral et sa négation, et la formule associée est, par conséquent, insatisfiable. Il est impossible
    696 d'attribuer un ordre aux sommets pour ensuite affecter des valeurs aux littéraux correspondant aux sommets car la formule admet aucun
    697 modèle. Pour cette raison, les arcs de ce graphe n'ont pas été numérotés ni affectés des valeurs $VRAI$ ou $FAUX$. En somme, l'algorithme
    698 nous dit simplement que ce graphe n'admet aucun modèle.
    699 
    700 \begin{figure}[ht!]
    701   \centering
    702   \begin{tikzpicture}[
    703       start chain=circle placed {at=(\tikzchaincount*-45+22.5+90:2.5)},
    704       lettre/.style={
    705         on chain,
    706         draw,
    707         circle,
    708         minimum size=1cm
    709       },
    710       chiffre/.style={
    711         node distance = 0.75cm
    712       },
    713       arr/.style={
    714         ->,
    715         >=triangle 90
    716       }
    717     ]
    718     \node[lettre] (1) {$\lnot x1$} ;
    719     \node[lettre] (5) {$x2$} ;
    720     \node[lettre] (3) {$\lnot x2$} ;
    721     \node[lettre] (6) {$x3$} ;
    722     \node[lettre] (4) {$\lnot x3$} ;
    723     \node[lettre] (7) {$x4$} ;
    724     \node[lettre] (2) {$\lnot x4$} ;
    725     \node[lettre] (8) {$x1$} ;
    726     
    727     \node[right of=1] {\textcolor{red}{faux}} ;
    728     \node[right of=5] {\textcolor{green!75!black}{vrai}} ;
    729     \node[right of=3] {\textcolor{red}{faux}} ;
    730     \node[right of=6] {\textcolor{green!75!black}{vrai}} ;
    731     \node[left  of=4] {\textcolor{red}{faux}} ;
    732     \node[left  of=7] {\textcolor{green!75!black}{vrai}} ;
    733     \node[left  of=2] {\textcolor{red}{faux}} ;
    734     \node[left  of=8] {\textcolor{green!75!black}{vrai}} ;
    735     
    736     \node[chiffre, above right of=1] {1} ;
    737     \node[chiffre, above right of=5] {5} ;
    738     \node[chiffre, below right of=3] {3} ;
    739     \node[chiffre, below right of=6] {6} ;
    740     \node[chiffre, below left of=4]  {4} ;
    741     \node[chiffre, below left of=7]  {7} ;
    742     \node[chiffre, above left of=2]  {2} ;
    743     \node[chiffre, above left of=8]  {8} ;
    744 
    745     \draw[arr] (1) -- (5) ;
    746     \draw[arr] (3) -- (8) ;
    747     \draw[arr] (2) -- (6) ;
    748     \draw[arr] (4) -- (7) ;
    749   \end{tikzpicture}
    750   \caption{Clause contingente : $(x_{1} \vee x_{2}) \wedge (x_{3} \vee x_{4})$}
    751   \label{fig:clause-conting}
    752 \end{figure}
    753 
    754 % \includegraphics[height=2in, width = 3in]{img/contingente.png
    755 
    756 \paragraph*{Clause contingente $(x_{1} \vee x_{2}) \wedge (x_{3} \vee x_{4})$~:}
    757 Le graphe de la figure \ref{fig:clause-conting} ne contient aucune composante fortement connexe contenant un littéral et sa négation, donc
    758 la formule associée admet bien un modèle. Ce modèle est le résultat du tri topologique effectué et les valeurs $VRAI$ et $FAUX$ affectées à
    759 des sommets par notre algorithme. Il existe aucun arc qui part d'un sommet étiqueté $VRAI$ vers un sommet étiqueté $FAUX$ et, en effet, les
    760 valeurs attribuées aux arcs donnent bien un modèle.
    761 
    762 
    763 
    764 \begin{figure}[ht!]
    765   \centering
    766   \begin{tikzpicture}[
    767       start chain=circle placed {at=(\tikzchaincount*-90+180:1.6)},
    768       lettre/.style={
    769         on chain,
    770         draw,
    771         circle,
    772         minimum size=1cm
    773       },
    774       chiffre/.style={
    775         node distance = 0.75cm
    776       },
    777       arr/.style={
    778         ->,
    779         >=triangle 90
    780       }
    781     ]
    782     \node[lettre] (1) {$\lnot x1$} ;
    783     \node[lettre] (2) {$x1$}  ;
    784     \node[lettre] (3) {$\lnot x2$} ;
    785     \node[lettre] (4) {$x2$}  ;
    786     
    787     \node[right of=1] {\textcolor{green!75!black}{vrai}} ;
    788     \node[right of=2] {\textcolor{red}{faux}} ;
    789     \node[right of=3] {\textcolor{green!75!black}{vrai}} ;
    790     \node[left  of=4] {\textcolor{red}{faux}} ;
    791     
    792     \node[chiffre, above right of=1] {1} ;
    793     \node[chiffre, below right of=2] {2} ;
    794     \node[chiffre, below right of=3]  {3} ;
    795     \node[chiffre, below left of=4]  {4} ;
    796 
    797 	\path
    798        (1) edge[loop above] (1)
    799        (2) edge[loop above]  (2)
    800        (3) edge[loop below] (3)
    801        (4) edge[loop above] (4) ;
    802   \end{tikzpicture}
    803   \caption{Clause valide :  $(x_{1} \vee \neg x_{1}) \wedge (x_{2} \vee \neg x_{2})$}
    804   \label{fig:clause-valide}
    805 \end{figure}
    806 
    807 % \includegraphics[height=2in, width = 3in]{img/valide.png}
    808 
    809 \paragraph*{Clause valide $(x_{1} \vee \neg x_{1}) \wedge (x_{2} \vee \neg x_{2})$~:}
    810 L'application de l'algorithme de transformation en graphe d'une formule valide nous donne un graphe ne contenant que des boucles à chaque
    811 sommet. Nous pouvons donc numéroter les arcs de n'importe quel façon. Ce étant, nous pouvous aussi affecter n'importe quelles valeurs aux
    812 sommets (hormis la même valeur à un littéral et sa négation, bien entendu) et la formule sera toujours vraie.
    813 
    814 L'objectif de cet algorithme n'est pas de dire si une formule satisfiable est contingente ou valide. Toutefois, si le résultat de
    815 l'algorithme est un graphe ne comportant que des boucles à chaque sommet, la formule associée est satisfiable et valide. Autrement, et si le
    816 graphe ne contient aucune composante fortement connexe contenant un littéral et sa négation, la formule est contingente.
    817 
    818 
    819 \begin{sousenonce}
    820 Vous expliciterez ensuite l'algorithme de transformation et vous évaluerez sa complexité.
    821 \end{sousenonce}
    822 
    823 L'algorithme de transformation est expliqué plus haut, sous le nom \og L'algorithme de construction de graphe\fg{}
    824 
    825 On pose~:
    826 
    827 c = nb clauses \\
    828 l = nb littéraux
    829 
    830 En triant la liste des sommets du graphe (coût $n \log n$ pour le tri), on peut effectuer les opérations de recherche d'un littéral (ou de sa négation) par dichotomie (coût $\log n$), donc les $c \times l$ et $O(l \times l)$ (1.a, 1.c, 3.) ci-dessous deviennent respectivement $O(c \log l)$ et $O(l \log l)$
    831 
    832 
    833 \begin{itemize}
    834 \item 1.a : $O(c \times l)$ car pour chaque littéral qu'on insère, il faut chercher s'il existe déjà.
    835 \item 1.b : $O(c)$ une opération pour chaque clause
    836 \item 1.c : $O(c \times l)$ pour chaque clause, on cherche ses 2 littéraux et leur négation dans le graphe
    837 \item 2. : $O(card(V) + card(E))$, comme $card(V) = 2l$ et $card(E) <= 2c$ (inférieur ou égal à cause des doublons potentiels qui n'ajoutent rien au graphe)., on a $O(l+c)$
    838 \item 3. : $O(l \times l)$ car pour chaque littéral qu'on rencontre on devra chercher sa négation dans tout le graphe.
    839 \end{itemize}
    840 
    841 Comme $l <= 2c$, tous les l ci-dessus peuvent être transformés en c.
    842 
    843 Donc, on prend le coût le plus élevé~:
    844 $$
    845 O(c^2 + c + c^2 + 2c + c^2) = O(c^2)
    846 $$
    847 
    848 On a donc bien un coût polynomial.
    849 
    850 De plus, si on trie le graphe, on a (le premier $c \log c$ est la création du graphe en maintenant sa liste de sommets triés (tri par insertion)):
    851 $$
    852 O(c \log c + c + c \log c + 2c + c \log c) = O(c \log c)
    853 $$
    854 
    855 
    856 \begin{sousenonce}
    857 Vous expliciterez ensuite l'algorithme d'exploration du graphe et vous évaluerez sa complexité
    858 en fonction de la taille de l'ensemble de clauses initial.
    859 \end{sousenonce}
    860 
    861 L'algorithme a déjà été expliqué plus haut à la question 3(a).
    862 
    863 Pour la partie «trouver un modèle» de l'algorithme, le tri topologique se fait en $O(V + E)$ en faisant un parcours en profondeur. Ensuite, on parcourt chaque littéral auquel on n'a pas encore affecté de valeur~; on lui affecte VRAI et on affecte FAUX à sa négation. Cela coûte
    864 $O(V^2)$ car pour chaque littéral, il faudra chercher sa négation dans $V$ et le coût total est donc $O(V + E + V^2) = O(V^2 + E)$.
    865 
    866 On peut toutefois trier les noeuds de $V$ et faire une recherche par dichotomie, ce qui coûte alors $O(V \log V)$ pour le tri et la
    867 recherche coûte alors $O(\log V)$, soit $O(V \log V)$ pour toute la phase d'affectation des valeurs. Le coût total de cette partie est donc
    868 $O(V + E + V \log V + V \log V)$, soit $O(E + V \log V)$.
    869 
    870 Pour la partie «déterminer si la formule est invalide», il faut parcourir le graphe pour voir si une composante fortement connexe contient
    871 un littéral et sa négation. On fera encore un parcours en profondeur $O(V + E)$ et pour chaque noeud (littéral) rencontré lors du parcours,
    872 il faudra voir si on a déjà rencontré la négation de ce littéral dans la même composante, ce qui coûte $O(\text{taille composante})$. Dans
    873 le pire des cas, la composante fortement connexe fait tout le graphe et le coût de la recherche sera alors $O(V)$. Comme cette recherche
    874 est effectuée pour chaque noeud, le coût total sera $O(V+E)$ pour le parcours en profondeur et $O(V^2)$ pour l'ensemble des recherches,
    875 soit $O(V+E+V^2) = O(V^2+E)$ au total.
    876 
    877 On peut améliorer le coût de la recherche en maintenant une structure de données permettant un accès rapide aux littéraux déjà rencontrés, par exemple, un arbre binaire de recherche balancé (AVL). Le coût de la recherche descend alors à $O(\log V)$ dans le pire des cas, pour un coût total de $O(E + V \log V)$.
    878 
    879 L'algorithme d'exploration du graphe (y compris la partie qui trouve un modèle) coûte donc $O(E + V^2)$ sans les tris supplémentaires et $O(E + V \log V)$ avec.
    880 
    881 \begin{sousenonce}
    882 Enfin, vous justifierez l'équivalence de la réponse au problème 2-SAT et au problème qui est posé dans le graphe.
    883 \end{sousenonce}
    884 
    885 Un problème 2-SAT est une conjonction de disjonctions de deux littéraux (ou de leur négation). Pour que la formule soit satisfiable, il faut
    886 qu'il existe une affectation des littéraux telle que chaque clause soit vraie (car les clauses sont reliées par des $\wedge$ et il suffit
    887 donc qu'une seule d'entre elles soit fausse pour que toute la formule devienne fausse).
    888 
    889 Pour qu'une clause soit valide, il faut qu'au moins un de ses deux membres soit vrai. Cela signifie que si le premier membre est forcément
    890 faux, alors le deuxième doit être vrai pour que la formule entière soit vraie.
    891 
    892 On peut donc ré-écrire la formule
    893 $$(a_1 \vee a_2) \wedge (a_3 \vee a_4) \wedge \dots \wedge (a_{n-1} \vee a_n)$$
    894 (les $a_i$ étant des littéraux ou leur négation) de la manière suivante :
    895 $$(\lnot a_1 \rightarrow a_2) \wedge (\lnot a_3 \rightarrow a_4) \wedge \dots \wedge (\lnot a_{n-1} \rightarrow a_n)$$
    896 
    897 Le graphe que l'on constuit explicite ces implications en faisant un arc entre le littéral à gauche et le littéral à droite.
    898 
    899 Pour chercher une contradiction dans la formule, qui la rend insatisfiable, il faut trouver un ensemble d'implications présentes dans la
    900 formules telles que~:
    901 $$
    902 \begin{array}{rrcl}
    903        & (a_{i1} & \Rightarrow & a_{i2}) \\
    904   \wedge & (a_{i3} & \Rightarrow & a_{i4}) \\
    905   \wedge & & \dots & \\
    906   \wedge & (a_{i5} & \Rightarrow & \lnot a_{i1}) \\
    907   \wedge & (\lnot a_{i1} & \Rightarrow & a_{i6}) \\
    908   \wedge & (a_{i7} & \Rightarrow & a_{i8}) \\
    909   \wedge & & \dots & \\
    910   \wedge & (a_{i9} & \Rightarrow & a_{i1}) \\
    911 \end{array}
    912 $$
    913 Ce qui peut se réduire à $a_{i1} \Rightarrow \lnot a_{i1} \Rightarrow a_{i1}$ autrement dit $a_{i1} \Leftrightarrow \lnot a_{i1}$, ce qui
    914 est bien évidemment insatisfiable.
    915 
    916 Cet ensemble d'implication se traduit dans le graphe par un chemin de $a_{i1}$ jusqu'à $\lnot a_{i1}$, et un chemin de $\lnot a_{i1}$
    917 jusqu'à $\lnot a_{i1}$, autrement dit, $a_{i1}$ et $\lnot a_{i1}$ sont dans la même composante connexe.
    918 
    919 L'algorithme utilise cette même transformation en implications pour déterminer un modèle~: le graphe étant trié topologiquement, on part du
    920 terme «le plus à droite» d'une chaîne d'implications et on lui affecte vrai si c'est un littéral sans négation en affectant faux à sa
    921 négation et vice versa si c'est un littéral avec négation. Lorsque l'on remonte ainsi de droite à gauche, on s'assure qu'il n'y aura jamais un
    922 $\text{VRAI} \Rightarrow \text{FAUX}$ (puisqu'on vient de la droite et qu'on n'affecte que des valeurs qui rendent le membre vrai), à moins
    923 qu'il y ait une boucle (qui aurait été détectée à l'étape précédente). Cette combinaison de valeurs nous donne donc un modèle.
    924 
    925 \subsection{Partie Calculabilité}
    926 
    927 \subsubsection*{Exercice \stepcounter{exocount}\bf\small \arabic{exocount} -- Sur le problème de codage}
    928 \addcontentsline{toc}{subsubsection}{Exercice \arabic{exocount} -- Sur le problème de codage}
    929 \setcounter{enoncecount}{0}
    930 
    931 \begin{enonce}
    932 Comment énumérer les couples d'entiers ?
    933 \end{enonce}
    934 
    935 
    936 L'énumération des couples de manière relativement homogène nous donnerait un codage qui nous permettrait d'identifier chaque couple par un nombre unique. 
    937 
    938 Il ne serait pas du tout utile de commencer par tous les couples $(0,y_{i})$  tel que $i \in \mathbb{Z}$ car il s'agirait, là, d'un ensemble infini de couples et on ne passerait jamais aux couples $(1, y_{i})$. 
    939 
    940 Une solution, pour tous les nombres naturels, serait de parcourir un graphe comme suit:
    941 
    942 \begin{figure}[ht!]
    943   %% «Paramètres»
    944   \xdef\maxdots{23}
    945   \xdef\maxdotsX{5}
    946   \xdef\maxdotsY{5}
    947   \xdef\maxnums{20}
    948   \xdef\maxcoordsX{3}
    949   \xdef\maxcoordsY{3}
    950   
    951   %% ===== Code is below =====
    952   
    953   %% Macros crades
    954   \makeatletter
    955   \def\myadv#1#2{%
    956     \xdef\incr@backup{\the\@tempcnta}%
    957     \@tempcnta=#1{}%
    958     \advance\@tempcnta by #2{}%
    959     \xdef#1{\the\@tempcnta}%
    960     \@tempcnta=\incr@backup{}%
    961   }
    962   \def\incr#1{%
    963     \myadv#1{1}%
    964   }
    965   \def\decr#1{%
    966     \myadv#1{-1}%
    967   }
    968   \makeatother
    969   \centering
    970   \begin{tikzpicture}[
    971     scale=1.4,
    972     dot/.style={
    973       circle,
    974       inner sep=0.7pt,
    975       fill=black
    976     },
    977     dotphantom/.style={
    978       circle,
    979       inner sep=3pt,
    980       fill=none,
    981       draw=none
    982     },
    983     numero/.style={rectangle, fill=white, inner sep=2pt, text=red!50!black},
    984     coord/.style={darkgray, scale=.8},
    985     %
    986     bigarrow/.style={
    987       ->,
    988       thick,
    989       draw=green!50!black
    990     },
    991     constatation1/.style={
    992       circle,
    993       inner sep=1.5pt,
    994       outer sep=0.8pt,
    995       fill=white,
    996       text=red,
    997       anchor=south,
    998       rotate around={45:(0,0)}
    999     },
   1000     constatation2/.style={
   1001       text=green!50!black,
   1002       node distance=0.6cm
   1003     }
   1004     ]
   1005     
   1006     % %% Digonale
   1007     % \draw[bigarrow,red] (0,0) -- (.5*7.5,-.5*7.5);
   1008     
   1009     % Définitions pour le code ci-dessous.
   1010     \xdef\i{0}
   1011     \xdef\x{0}
   1012     \xdef\y{0}
   1013     \xdef\corner{3}
   1014     \xdef\sidelen{0}
   1015     \xdef\nextsidelen{1}
   1016     \xdef\direction{3}
   1017     \incr\maxnums
   1018     \incr\maxcoordsX
   1019     \incr\maxcoordsY
   1020     
   1021     \foreach \x in {0,...,\maxcoordsX} {
   1022       \foreach \y in {1,...,\maxcoordsY} {
   1023         \expandafter\xdef\csname dotxypresent-\x-\y\endcsname{0}
   1024       }
   1025     }
   1026     
   1027     \def\reallysmallcheat#1{%
   1028       \ensuremath{\hphantom{\vphantom{X}}_{\hphantom{\vphantom{X}}_{#1}}}
   1029     }
   1030     \def\drawnode{%
   1031       \node[dot] (dot-\x-\y) at (\x,-\y) {};
   1032       \node[dotphantom] (phantom-\x-\y) at (\x,-\y) {};
   1033       \ifnum\maxnums>\i
   1034         % \ifnum\corner=0    \node[numero,anchor=south]      at (dot-\x-\y.north)      {\i}; \else
   1035         % \ifnum\corner=1    \node[numero,anchor=east]       at (dot-\x-\y.west)       {\i}; \else
   1036         % \ifnum\corner=2    \node[numero,anchor=east]       at (dot-\x-\y.west)       {\i}; \else
   1037         % \ifnum\corner=3    \node[numero,anchor=south]      at (dot-\x-\y.north)      {\i}; \else
   1038         % \ifnum\direction=0 \node[numero,anchor=north west] at (dot-\x-\y.south east) {\i}; \else
   1039         % \ifnum\direction=2 \node[numero,anchor=north west] at (dot-\x-\y.south east) {\i}; \fi\fi\fi\fi\fi\fi
   1040         \node[numero,anchor=north west] at (dot-\x-\y.south east) {\i};
   1041       \fi
   1042       \ifnum\maxcoordsX>\x
   1043       \ifnum\maxcoordsY>\y
   1044         % \ifnum\corner=0    \node[coord,anchor=south east] at (dot-\x-\y.north west) {\reallysmallcheat{(\x, \y)}}; \else
   1045         % \ifnum\corner=1    \node[coord,anchor=north east] at (dot-\x-\y.south west) {\reallysmallcheat{(\x, \y)}}; \else
   1046         % \ifnum\corner=2    \node[coord,anchor=north west] at (dot-\x-\y.south east) {\reallysmallcheat{(\x, \y)}}; \else
   1047         % \ifnum\corner=3    \node[coord,anchor=south west] at (dot-\x-\y.north east) {\reallysmallcheat{(\x, \y)}}; \else
   1048         % \ifnum\direction=0 \node[coord,anchor=east]       at (dot-\x-\y.west)       {\reallysmallcheat{(\x, \y)}}; \else
   1049         % \ifnum\direction=1 \node[coord,anchor=north]      at (dot-\x-\y.south)      {\reallysmallcheat{(\x, \y)}}; \else
   1050         % \ifnum\direction=2 \node[coord,anchor=west]       at (dot-\x-\y.east)       {\reallysmallcheat{(\x, \y)}}; \else
   1051         % \ifnum\direction=3 \node[coord,anchor=south]      at (dot-\x-\y.north)      {\reallysmallcheat{(\x, \y)}}; \fi\fi\fi\fi\fi\fi\fi\fi
   1052         \expandafter\xdef\csname dotxypresent-\x-\y\endcsname{1}
   1053         \ifnum\y=0
   1054           \node[coord,anchor=south west] at (dot-\x-\y.north east) {\reallysmallcheat{(\x, \y)}};
   1055         \else
   1056           \node[coord,anchor=west,xshift=0.2] at (dot-\x-\y.east) {\reallysmallcheat{(\x, \y)}};
   1057         \fi
   1058       \fi
   1059       \fi
   1060     }
   1061     \def\drawlinknode{%
   1062       \drawnode%
   1063       \draw[->] (phantom-\oldx-\oldy) -- (phantom-\x-\y);%
   1064     }
   1065     \def\mystep{%
   1066       \incr\i%
   1067       \xdef\oldx{\x}%
   1068       \xdef\oldy{\y}%
   1069     }
   1070     \def\changedir#1{%
   1071       \xdef\direction{#1}%
   1072       \xdef\corner{#1}%
   1073     }
   1074     
   1075     \drawnode
   1076     \mystep \incr\x
   1077     \xdef\cornerc{0}
   1078 
   1079     \foreach \pos in {1,...,\maxdots} {
   1080       % Detect when we are at the end of this edge.
   1081       \ifnum\sidelen=0
   1082         \ifnum\direction=0 \changedir{1} \incr\nextsidelen \xdef\sidelen{1}            \else
   1083         \ifnum\direction=1 \changedir{2}                   \xdef\sidelen{\nextsidelen} \else
   1084         \ifnum\direction=2 \changedir{3} \incr\nextsidelen \xdef\sidelen{1}            \else
   1085         \ifnum\direction=3 \changedir{0}                   \xdef\sidelen{\nextsidelen} \fi\fi\fi\fi% Brin d'acier
   1086         
   1087       \fi
   1088       % Draw node and link to previous, step counters
   1089       \drawlinknode \mystep
   1090       %% Se déplacer vers ↙↓↗→
   1091       \ifnum\direction=0 \incr\y \decr\x \fi
   1092       \ifnum\direction=1 \incr\y         \fi
   1093       \ifnum\direction=2 \decr\y \incr\x \fi
   1094       \ifnum\direction=3         \incr\x \fi
   1095       \decr\sidelen
   1096       \xdef\corner{4}%% 4 == pas de coin-coin.
   1097     }
   1098     
   1099     \foreach \x in {0,...,\maxdotsX} {
   1100       \foreach \y in {1,...,\maxdotsY} {
   1101         \node[dot] (dot-\x-\y) at (\x,-\y) {};
   1102       }
   1103     }
   1104     \decr\maxcoordsX
   1105     \decr\maxcoordsY
   1106     \foreach \x in {0,...,\maxcoordsX} {
   1107       \foreach \y in {0,...,\maxcoordsY} {
   1108         \node[dot,fill=none] (fakedot-\x-\y) at (\x,-\y) {};
   1109         \expandafter\ifnum\csname dotxypresent-\x-\y\endcsname=0
   1110           \ifnum\y=0
   1111             \node[coord,anchor=south west] at (fakedot-\x-\y.north east) {\reallysmallcheat{(\x, \y)}};
   1112           \else
   1113             \node[coord,anchor=west,xshift=0.2] at (fakedot-\x-\y.east) {\reallysmallcheat{(\x, \y)}};
   1114           \fi
   1115         \fi
   1116       }
   1117     }
   1118     
   1119     % \foreach \i in {1, ...,6}{
   1120     %   \node[constatation1] at (.5*\i,-.5*\i) {\i};
   1121     % }
   1122     % \node[constatation1] at (.5*7,-.5*7) {\vdots};
   1123     
   1124     % \node[coordinate] (fake0-0) at (0,0) {};
   1125     % \node[coordinate] (fake1-0) at (1,0) {};
   1126     % \node[coordinate] (fake3-0) at (3,0) {};
   1127     % \node[coordinate] (fake5-0) at (5,0) {};
   1128     % \node[coordinate] (fake0-2) at (0,-2) {};
   1129     % \node[coordinate] (fake0-4) at (0,-4) {};
   1130     % \node[coordinate] (fake0-6) at (0,-6) {};
   1131     % \node[constatation2, above left of=fake0-0] {0};
   1132     % \node[constatation2, above of=fake1-0]  {1};
   1133     % \node[constatation2, above of=fake3-0]  {6};
   1134     % \node[constatation2, above of=fake5-0] {15};
   1135     % \node[constatation2, left of=fake0-2] {3};
   1136     % \node[constatation2, left of=fake0-4] {10};
   1137     % \node[constatation2, left of=fake0-6] {21};
   1138   \end{tikzpicture}
   1139   \caption{Codage d'un couple d'entiers relatifs}%% TODO : caption
   1140   \label{fig:codage-zigzag}
   1141 \end{figure}
   1142 
   1143 %% TODO: Il faudrait ajouter les coordonnées (0,0), (1,0), (0,1), et les codes correspondants au graphe ci-dessus, etc. VOIR LES DIAGRAMMES QUE J'AI DONNE A BERTRAND
   1144 %% TODO : Réponse georges : c'est fait.
   1145 
   1146 Dans la figure \ref{fig:codage-zigzag}, on commence par le couple $(0,0)$, puis on procède aux couples $(1,0)$, $(0,1)$, $(0,2)$, $(1,1)$, $(2,0)$, $(3,0)$, $(2,1)$, $(1,2)$, $(0,3)$, $(0,4)$\ldots L'algorithme pour simplement parcourir les couples de cette façon consisterait tout d'abord de déclarer et d'intialiser trois variables globales~: le point de départ, \lstinline!*current*!, et les valeurs maximales courantes de $x$ et de $y$, c'est-à-dire \lstinline!*max-x*! et \lstinline!*max-y*!. En LISP, ceci pourrait être codé comme suit~:
   1147 
   1148 \begin{lstlisting}[language=Lisp]
   1149 (defvar *current* (list 0 0 0)) ;; liste courante (code x y)
   1150 (setf *current* (list 0 0 0)) 
   1151 (defvar *max-x* 0) ;; valeur maximal courante de x
   1152 (setf *max-x* 0)
   1153 (defvar *max-y* 0) ;; valeur maximal courante de y
   1154 (setf *max-y* 0)
   1155 \end{lstlisting}
   1156 
   1157 On pourrait stocker toutes les valeurs de \lstinline!*current*! dans un tableau \lstinline!*db*! (base de données) comme suit~:
   1158 
   1159 \begin{lstlisting}[language=Lisp]
   1160 (defvar *db* nil) 
   1161 (setf *db* nil)
   1162 (push *current* *db*)
   1163 \end{lstlisting}
   1164 
   1165 Puis, les conditions pour déterminer la direction à prendre afin de parcourir le graphe pourrait être implémentées comme suit (toujours en LISP)~:
   1166 
   1167 \begin{lstlisting}[language=Lisp]
   1168 (defun move (L)
   1169   (cond
   1170     ((and (zerop (third L)) (= *max-x* *max-y*)) 
   1171 		;; RIGHT takes precedence over LEFT becuase it occurs first
   1172       (print "in RIGHT") ;; 
   1173          (right L))
   1174     ((and (zerop (second L)) (= *max-x* *max-y*)) ;; DOWN
   1175       (print "in DOWN") 
   1176          (down L))
   1177     ((> *max-x* *max-y*) ;; DOWN-LEFT
   1178       (print "in DOWN-LEFT")  
   1179          (down-left L))
   1180     ((< *max-x* *max-y*) ;; UP-RIGHT
   1181       (print "in UP-RIGHT") 
   1182          (up-right L))))
   1183 \end{lstlisting}
   1184  
   1185 La liste \lstinline!*current*! est passée en paramètre lorsque l'on appelle ces fonctions~: L correspond toujours à *current*. Les fonctions 'right', 'down', 'down-left' et 'up-right', qui correspondent au parcours dans la figure \ref{fig:codage-zigzag}, incrémente la première valeur de L (le codage), qui est une liste de la forme \lstinline!(code x y)!. Par ailleurs, la fonction 'right' incrémente la valeur courante de $x$ (le deuxième élément de la liste), la fonction 'down' incrémente la valeur courante de $y$ (la troisième élément de la liste), la fonction 'down-left' décrémente la valeur de $x$ et incrémente la valeur $y$ et la fonction 'up-right', elle, fait le contraire, elle incrémente la valeur de $x$ et décrémente la valeur de $y$. 
   1186 
   1187 On peut parcourir le graphe à l'aide de la fonction 'zig-zag' qui, elle, se sert de la fonction move-and-update afin de mettre à jour les variables globales *max-x* et *max-y*. 'move-and-update' se sert de 'move' qui choisit la bonne direction à prendre pour parcourir le graphe, c'est-à-dire 'right', 'down', 'down-left' ou 'up-right'~:
   1188 
   1189 \begin{lstlisting}[language=Lisp]
   1190 (defun move-and-update (L)
   1191   (progn
   1192     (setf L (move L))
   1193     (update-max-x-y L)
   1194     *db*))
   1195  
   1196 (defun zig-zag (L n)
   1197     (if (zerop n) 
   1198       (move-and-update *current*)
   1199       (progn
   1200         (move-and-update *current*)
   1201         (zig-zag L (- n 1)))))
   1202 \end{lstlisting}
   1203 
   1204 
   1205 %% TODO : JOHN :
   1206 %% Pour définir un label pour une section / sous-section / …, il faut mettre ceci juste après le \section{…}
   1207 %% \label{foobar}
   1208 %%
   1209 %% Pour avoir le numéro de page correspondant :
   1210 %% \pageref{foobar}
   1211 %%
   1212 %% Pour le numéro de section / sous-section / … :
   1213 %% \ref{foobar}
   1214 %%
   1215 %% Tu changes foobar par un nom de ton choix.
   1216 
   1217 %% TODO TODO TODO !!!!!!!!
   1218 L'intégralité du programme est en annexe à la page \pageref{coupleslisp}.
   1219 
   1220 Voici une trace de cette fonction en passant \lstinline!*current*! égal à \lstinline!(0 0 0)! et $n = 100$ en paramètres~:
   1221 
   1222 \begin{lstlisting}[language=Lisp]
   1223 > (zig-zag *current* 100)
   1224 "in RIGHT" 
   1225 "in DOWN-LEFT" 
   1226 "in DOWN" 
   1227 "in UP-RIGHT" 
   1228 "in UP-RIGHT" 
   1229 "in RIGHT" 
   1230 (etc.)
   1231 "in DOWN-LEFT" 
   1232 "in DOWN-LEFT" 
   1233 ((101 3 10) (100 4 9) (99 5 8) (98 6 7) (97 7 6) (96 8 5) 
   1234 (95 9 4) (94 10 3) (93 11 2) (92 12 1) (91 13 0) (90 12 0) 
   1235 (89 11 1) (88 10 2) (87 9 3) (86 8 4) (85 7 5) (84 6 6) 
   1236 (83 5 7) (82 4 8) (81 3 9) (80 2 10) (79 1 11) (78 0 12) 
   1237 (77 0 11) (76 1 10) (75 2 9) (74 3 8) (73 4 7) (72 5 6) 
   1238 (71 6 5) (70 7 4) (69 8 3) (68 9 2) (67 10 1) (66 11 0) 
   1239 (65 10 0) (64 9 1) (63 8 2) (62 7 3) (61 6 4) (60 5 5) 
   1240 (59 4 6) (58 3 7) (57 2 8) (56 1 9) (55 0 10) (54 0 9) 
   1241 (53 1 8) (52 2 7) (51 3 6) (50 4 5) (49 5 4) (48 6 3) 
   1242 (47 7 2) (46 8 1) (45 9 0) (44 8 0) (43 7 1) (42 6 2) 
   1243 (41 5 3) (40 4 4) (39 3 5) (38 2 6) (37 1 7) (36 0 8) 
   1244 (35 0 7) (34 1 6) (33 2 5) (32 3 4) (31 4 3) (30 5 2) 
   1245 (29 6 1) (28 7 0) (27 6 0) (26 5 1) (25 4 2) (24 3 3) 
   1246 (23 2 4) (22 1 5) (21 0 6) (20 0 5) (19 1 4) (18 2 3) 
   1247 (17 3 2) (16 4 1) (15 5 0) (14 4 0) (13 3 1) (12 2 2) 
   1248 (11 1 3) (10 0 4) (9 0 3) (8 1 2) (7 2 1) (6 3 0) (5 2 0) 
   1249 (4 1 1) (3 0 2) (2 0 1) (1 1 0) (0 0 0))
   1250 \end{lstlisting}
   1251 
   1252 
   1253 \begin{enonce}
   1254 Donner les fonctions de codage et de décodage $f_1(z)\rightarrow x$ et $f_2(z)\rightarrow y$.
   1255 \end{enonce}
   1256 
   1257 \begin{figure}[ht!]
   1258   %% «Paramètres»
   1259   \xdef\maxdots{23}
   1260   \xdef\maxdotsX{5}
   1261   \xdef\maxdotsY{5}
   1262   \xdef\maxnums{20}
   1263   \xdef\maxcoordsX{3}
   1264   \xdef\maxcoordsY{3}
   1265   
   1266   %% ===== Code is below =====
   1267   
   1268   %% Macros crades
   1269   \makeatletter
   1270   \def\myadv#1#2{%
   1271     \xdef\incr@backup{\the\@tempcnta}%
   1272     \@tempcnta=#1{}%
   1273     \advance\@tempcnta by #2{}%
   1274     \xdef#1{\the\@tempcnta}%
   1275     \@tempcnta=\incr@backup{}%
   1276   }
   1277   \def\incr#1{%
   1278     \myadv#1{1}%
   1279   }
   1280   \def\decr#1{%
   1281     \myadv#1{-1}%
   1282   }
   1283   \makeatother
   1284   \centering
   1285   \begin{tikzpicture}[
   1286     scale=1.4,
   1287     dot/.style={
   1288       circle,
   1289       inner sep=0.7pt,
   1290       fill=black
   1291     },
   1292     dotphantom/.style={
   1293       circle,
   1294       inner sep=3pt,
   1295       fill=none,
   1296       draw=none
   1297     },
   1298     numero/.style={rectangle, fill=white, inner sep=2pt, text=red!50!black},
   1299     coord/.style={darkgray, scale=.8},
   1300     %
   1301     bigarrow/.style={
   1302       ->,
   1303       thick,
   1304       draw=green!50!black
   1305     },
   1306     constatation1/.style={
   1307       circle,
   1308       inner sep=1.5pt,
   1309       outer sep=0.8pt,
   1310       fill=white,
   1311       text=red,
   1312       anchor=south,
   1313       rotate around={45:(0,0)}
   1314     },
   1315     constatation2/.style={
   1316       text=green!50!black,
   1317       node distance=0.6cm
   1318     }
   1319     ]
   1320     
   1321     %% Digonale
   1322     \draw[bigarrow,red] (0,0) -- (.5*7.5,-.5*7.5);
   1323     
   1324     % Définitions pour le code ci-dessous.
   1325     \xdef\i{0}
   1326     \xdef\x{0}
   1327     \xdef\y{0}
   1328     \xdef\corner{3}
   1329     \xdef\sidelen{0}
   1330     \xdef\nextsidelen{1}
   1331     \xdef\direction{3}
   1332     \incr\maxnums
   1333     \incr\maxcoordsX
   1334     \incr\maxcoordsY
   1335     
   1336     \foreach \x in {0,...,\maxcoordsX} {
   1337       \foreach \y in {1,...,\maxcoordsY} {
   1338         \expandafter\xdef\csname dotxypresent-\x-\y\endcsname{0}
   1339       }
   1340     }
   1341     
   1342     \def\reallysmallcheat#1{%
   1343       \ensuremath{\hphantom{\vphantom{X}}_{\hphantom{\vphantom{X}}_{#1}}}
   1344     }
   1345     \def\drawnode{%
   1346       \node[dot] (dot-\x-\y) at (\x,-\y) {};
   1347       \node[dotphantom] (phantom-\x-\y) at (\x,-\y) {};
   1348       \ifnum\maxnums>\i
   1349         % \ifnum\corner=0    \node[numero,anchor=south]      at (dot-\x-\y.north)      {\i}; \else
   1350         % \ifnum\corner=1    \node[numero,anchor=east]       at (dot-\x-\y.west)       {\i}; \else
   1351         % \ifnum\corner=2    \node[numero,anchor=east]       at (dot-\x-\y.west)       {\i}; \else
   1352         % \ifnum\corner=3    \node[numero,anchor=south]      at (dot-\x-\y.north)      {\i}; \else
   1353         % \ifnum\direction=0 \node[numero,anchor=north west] at (dot-\x-\y.south east) {\i}; \else
   1354         % \ifnum\direction=2 \node[numero,anchor=north west] at (dot-\x-\y.south east) {\i}; \fi\fi\fi\fi\fi\fi
   1355         \node[numero,anchor=north west] at (dot-\x-\y.south east) {\i};
   1356       \fi
   1357       \ifnum\maxcoordsX>\x
   1358       \ifnum\maxcoordsY>\y
   1359         % \ifnum\corner=0    \node[coord,anchor=south east] at (dot-\x-\y.north west) {\reallysmallcheat{(\x, \y)}}; \else
   1360         % \ifnum\corner=1    \node[coord,anchor=north east] at (dot-\x-\y.south west) {\reallysmallcheat{(\x, \y)}}; \else
   1361         % \ifnum\corner=2    \node[coord,anchor=north west] at (dot-\x-\y.south east) {\reallysmallcheat{(\x, \y)}}; \else
   1362         % \ifnum\corner=3    \node[coord,anchor=south west] at (dot-\x-\y.north east) {\reallysmallcheat{(\x, \y)}}; \else
   1363         % \ifnum\direction=0 \node[coord,anchor=east]       at (dot-\x-\y.west)       {\reallysmallcheat{(\x, \y)}}; \else
   1364         % \ifnum\direction=1 \node[coord,anchor=north]      at (dot-\x-\y.south)      {\reallysmallcheat{(\x, \y)}}; \else
   1365         % \ifnum\direction=2 \node[coord,anchor=west]       at (dot-\x-\y.east)       {\reallysmallcheat{(\x, \y)}}; \else
   1366         % \ifnum\direction=3 \node[coord,anchor=south]      at (dot-\x-\y.north)      {\reallysmallcheat{(\x, \y)}}; \fi\fi\fi\fi\fi\fi\fi\fi
   1367         \expandafter\xdef\csname dotxypresent-\x-\y\endcsname{1}
   1368         \ifnum\y=0
   1369           \node[coord,anchor=south west] at (dot-\x-\y.north east) {\reallysmallcheat{(\x, \y)}};
   1370         \else
   1371           \node[coord,anchor=west,xshift=0.2] at (dot-\x-\y.east) {\reallysmallcheat{(\x, \y)}};
   1372         \fi
   1373       \fi
   1374       \fi
   1375     }
   1376     \def\drawlinknode{%
   1377       \drawnode%
   1378       \draw[->] (phantom-\oldx-\oldy) -- (phantom-\x-\y);%
   1379     }
   1380     \def\mystep{%
   1381       \incr\i%
   1382       \xdef\oldx{\x}%
   1383       \xdef\oldy{\y}%
   1384     }
   1385     \def\changedir#1{%
   1386       \xdef\direction{#1}%
   1387       \xdef\corner{#1}%
   1388     }
   1389     
   1390     \drawnode
   1391     \mystep \incr\x
   1392     \xdef\cornerc{0}
   1393 
   1394     \foreach \pos in {1,...,\maxdots} {
   1395       % Detect when we are at the end of this edge.
   1396       \ifnum\sidelen=0
   1397         \ifnum\direction=0 \changedir{1} \incr\nextsidelen \xdef\sidelen{1}            \else
   1398         \ifnum\direction=1 \changedir{2}                   \xdef\sidelen{\nextsidelen} \else
   1399         \ifnum\direction=2 \changedir{3} \incr\nextsidelen \xdef\sidelen{1}            \else
   1400         \ifnum\direction=3 \changedir{0}                   \xdef\sidelen{\nextsidelen} \fi\fi\fi\fi% Brin d'acier
   1401         
   1402       \fi
   1403       % Draw node and link to previous, step counters
   1404       \drawlinknode \mystep
   1405       %% Se déplacer vers ↙↓↗→
   1406       \ifnum\direction=0 \incr\y \decr\x \fi
   1407       \ifnum\direction=1 \incr\y         \fi
   1408       \ifnum\direction=2 \decr\y \incr\x \fi
   1409       \ifnum\direction=3         \incr\x \fi
   1410       \decr\sidelen
   1411       \xdef\corner{4}%% 4 == pas de coin-coin.
   1412     }
   1413     
   1414     \foreach \x in {0,...,\maxdotsX} {
   1415       \foreach \y in {1,...,\maxdotsY} {
   1416         \node[dot] (dot-\x-\y) at (\x,-\y) {};
   1417       }
   1418     }
   1419     \decr\maxcoordsX
   1420     \decr\maxcoordsY
   1421     \foreach \x in {0,...,\maxcoordsX} {
   1422       \foreach \y in {0,...,\maxcoordsY} {
   1423         \node[dot,fill=none] (fakedot-\x-\y) at (\x,-\y) {};
   1424         \expandafter\ifnum\csname dotxypresent-\x-\y\endcsname=0
   1425           \ifnum\y=0
   1426             \node[coord,anchor=south west] at (fakedot-\x-\y.north east) {\reallysmallcheat{(\x, \y)}};
   1427           \else
   1428             \node[coord,anchor=west,xshift=0.2] at (fakedot-\x-\y.east) {\reallysmallcheat{(\x, \y)}};
   1429           \fi
   1430         \fi
   1431       }
   1432     }
   1433     
   1434     \foreach \i in {1, ...,6}{
   1435       \node[constatation1] at (.5*\i,-.5*\i) {\i};
   1436     }
   1437     \node[constatation1] at (.5*7,-.5*7) {\vdots};
   1438     
   1439     \node[coordinate] (fake0-0) at (0,0) {};
   1440     \node[constatation2, coordinate, above of=fake0-0] (fake0-0-bis) {};
   1441     \node[coordinate] (fake1-0) at (1,0) {};
   1442     \node[coordinate] (fake3-0) at (3,0) {};
   1443     \node[coordinate] (fake5-0) at (5,0) {};
   1444     \node[coordinate] (fake0-2) at (0,-2) {};
   1445     \node[coordinate] (fake0-4) at (0,-4) {};
   1446     \node[coordinate] (fake0-6) at (0,-6) {};
   1447     \node[constatation2, left of=fake0-0-bis] {0};
   1448     \node[constatation2, above of=fake1-0]  {1};
   1449     \node[constatation2, above of=fake3-0]  {6};
   1450     \node[constatation2, above of=fake5-0] {15};
   1451     \node[constatation2, left of=fake0-2] {3};
   1452     \node[constatation2, left of=fake0-4] {10};
   1453     \node[constatation2, left of=fake0-6] {21};
   1454   \end{tikzpicture}
   1455   \caption{Codage d'un couple d'entiers relatifs}%% TODO : caption
   1456   \label{fig:codage-nat-avec-constatation}
   1457 \end{figure}
   1458 
   1459 
   1460 En reprenant la figure \ref{fig:codage-nat-avec-constatation} ci-dessus, on peut faire plusieurs constatations~:
   1461 
   1462 \begin{itemize}
   1463 \item La somme de $x$ et $y$ de chaque sommet du graphe d'une diagonale dans le sens du parcours est toujours la même.
   1464 \item La longueur de chaque diagonale successive s'incrémente à chaque fois et nous donne par conséquent toujours une longueur impaire suivie d'une longueur paire.
   1465 \item Le point à partir duquel on commence à incrémenter le code au long d'une diagonale correspond aux codes $1$, $3$, $6$, $10$, $15$, $21$\ldots (voir la figure \ref{fig:codage-nat-avec-constatation}), ce qui correspond à la formule de Gauss, à savoir~:
   1466 
   1467 $$\dfrac{(n \times (n + 1))}{2}$$
   1468 \end{itemize}
   1469 
   1470 Ces trois informations nous permettront de coder un couple de nombres naturels sans parcourir le graphe. En voici l'algorithme en C~:
   1471 
   1472 \begin{lstlisting}[language=C]
   1473 long int orderedPairToCodeNat(int x, int y){
   1474 	long code;
   1475 	int sumxy; 
   1476 	sumxy = x + y;
   1477 	code = ((sumxy)*(sumxy + 1))/2;
   1478 
   1479 	if(even(sumxy)){
   1480 		code = code + x;
   1481 	}
   1482 	else{
   1483 		code = code + y; 
   1484 	}
   1485 	return code;
   1486 }
   1487 \end{lstlisting}
   1488 
   1489 
   1490 En reprenant les trois informations constatées à partir du figure \ref{fig:codage-nat-avec-constatation} et les algorithmes décrits ci-dessus, il est également relativement facile de calculer n'importe quel couple d'entiers naturels à partir d'un code. En voici l'algorithme en C~:
   1491 
   1492 \begin{lstlisting}[language=C]
   1493 int* codeToOrderedPairNat(long int code){
   1494 	int *couple = malloc(2*sizeof(int));
   1495 	int n = sqrt(code * 2);
   1496 	long int axis = (n * (n + 1))/2;
   1497 	int diff = 0;
   1498 	if(axis > code){
   1499 			n = n - 1;
   1500 			axis = (n * (n + 1))/2;
   1501 	}
   1502 	diff = code - axis;
   1503 	if(even(n)){
   1504 		couple[0] = diff;
   1505 		couple[1] = n - diff;
   1506 	}
   1507 	else{
   1508 		couple[0] = n - diff;
   1509 		couple[1] = diff;
   1510 	}
   1511 	return couple;
   1512 }
   1513 \end{lstlisting}
   1514 
   1515 On trouve d'abord une valeur approximative du code correspondant aux valeurs de la formule de Gauss (la variable \lstinline!axis! dans la fonction ci-dessus), puis on modifie cette valeur afin qu'elle soit une valeur plus petite que le vrai code passé en paramètre. La valeur \lstinline!n! est égale soit à la valeur de \lstinline!x! soit à la valeur de \lstinline!y! d'un point extrêmal de la ligne diagonale en question (selon le point en question). On modifie les valeurs de \lstinline!x! et de \lstinline!y! en calculant la différence entre le code et le code approximatif (la variable $axis$), ce qui nous donne les valeurs de \lstinline!x! et de \lstinline!y! correspondant au code passé en paramètre.
   1516 
   1517 Prenons un simple example. Mettons qu'on voulait connaitre le couple correspondant au code $19$. La valeur entière  correspondant au point extrêmal de la diagonale est $15$ ($axis = 15$, $n = 5$). La différence entre ces deux points est $19 - 15 = 4$ ($diff = code - axis$). On soustrait $4$ à $5$ ($couple[0] = n - diff$) pour avoir la valeur de $x$ (ce qui nous donne $1$) et $4$ ($diff$) est la valeur de $y$. On retourne $x$ et $y$ (à savoir ($(1,4)$).
   1518 
   1519 On peut étendre ce codage pour comprendre tous les nombres entiers en réutilisant la fonction ci-dessus. Voici l'algorithme implémenté en C de la fonction du codage des entiers~:
   1520 
   1521 \begin{lstlisting}[language=C]
   1522 long int orderedPairToCodeInt(int x, int y){
   1523 	long int code = 0;	
   1524 
   1525 	if (x < 0){
   1526 		x = (2 * (abs (x))) - 1;
   1527 	}
   1528 	else{
   1529 		x = 2 * x;
   1530 	}
   1531 
   1532 	if (y < 0){
   1533 		y = (2 * (abs(y))) - 1;
   1534 	}
   1535 	else{
   1536 		y = 2 * y;
   1537 	}
   1538 
   1539 	code = orderedPairToCodeNat(x, y);
   1540 	return code;
   1541 }
   1542 \end{lstlisting}
   1543 
   1544 
   1545 On n'utilise que des valeurs positive pour ce codage. Si x est négative, on l'attribut une valeur impaire. Si \lstinline!x! est positif, on
   1546 l'attribut une valeur paire, et il en va de même des valeurs de y. Ensuite, on passe le nouveau couple ainsi créé en paramètre en se servant
   1547 de la fonction initialement créée pour coder les nombres naturels.
   1548 
   1549 
   1550 Pour trouver un couple à partir d'un code, on fait l'inverse~:
   1551 
   1552 \begin{lstlisting}[language=C]
   1553 int* codeToOrderedPairInt(long int code){
   1554 	int *pair = codeToOrderedPairNat(code);
   1555 
   1556 	if (even(pair[0])){
   1557 		pair[0] = pair[0] / 2;
   1558 	}
   1559 	else{
   1560 		pair[0] = (pair[0] / 2)*(-1) - 1;
   1561 	} 
   1562 	
   1563 	if (even (pair[1])){
   1564 		pair[1] = pair[1] / 2;
   1565 	}
   1566 	else{
   1567 		pair[1] = (pair[1] / 2)*(-1) - 1;
   1568 	}
   1569 
   1570 	return pair;
   1571 }
   1572 \end{lstlisting}  
   1573 
   1574 
   1575 Un autre système de codage pourrait être utilisé en parcourant un graphe comme montré dans la figure \ref{fig:codage-rel}.
   1576 
   1577 \begin{figure}[ht!]
   1578   %% «Paramètres»
   1579   \xdef\maxdots{81}
   1580   \xdef\maxnums{56}
   1581   \xdef\maxcoords{20}
   1582   
   1583   %% ===== Code is below =====
   1584   
   1585   %% Macros crades
   1586   \makeatletter
   1587   \def\myadv#1#2{%
   1588     \xdef\incr@backup{\the\@tempcnta}%
   1589     \@tempcnta=#1{}%
   1590     \advance\@tempcnta by #2{}%
   1591     \xdef#1{\the\@tempcnta}%
   1592     \@tempcnta=\incr@backup{}%
   1593   }
   1594   \def\incr#1{%
   1595     \myadv#1{1}%
   1596   }
   1597   \def\decr#1{%
   1598     \myadv#1{-1}%
   1599   }
   1600   \makeatother
   1601   % \centering
   1602   \hskip -21mm%% Hack-o-matic to get the picture more or less centered…
   1603   \begin{tikzpicture}[
   1604     dot/.style={
   1605       circle,
   1606       inner sep=0.7pt,
   1607       fill=black
   1608     },
   1609     dotphantom/.style={
   1610       circle,
   1611       inner sep=3pt,
   1612       fill=none,
   1613       draw=none
   1614     },
   1615     numero/.style={circle, fill=white, inner sep=0.2pt, text=red, scale=.75},
   1616     coord/.style={darkgray, scale=.6},
   1617     %
   1618     bigarrow/.style={
   1619       ->,
   1620       thick,
   1621       draw=green!50!black
   1622     }
   1623     ]
   1624     
   1625     % Diagonales
   1626     \node[dotphantom] (pre-phantom-0-0) at (0,0) {};
   1627     \node[dotphantom] (pre-phantom-1-0) at (1,0) {};
   1628     
   1629     % Top right
   1630     \node[inner sep=0.1pt] (tr-start) at (4,4) {};
   1631     \xdef\previous{tr-start}
   1632     \foreach \pos/\content in {0/$1\times 2=2$,1/$3\times 4=12$,2/$5\times 6=30$,3/$7\times 8=56$,4/$\vphantom{X}\dots$}{
   1633       \node[anchor=south] (tr-temp-\pos) at (intersection cs: first line={(\previous.north west)--(\previous.north east)}, second line={(0,0)--(6,6)}) {\phantom{\content}};
   1634       \node[anchor=north west] (tr-\pos) at (intersection cs: first line={(tr-temp-\pos.north west)--(tr-temp-\pos.north east)}, second line={(0,0)--(6,6)}) {\content};
   1635       \xdef\previous{tr-\pos}
   1636     }
   1637     \draw[bigarrow] (pre-phantom-0-0) -- (intersection cs: first line={(\previous.north west)--(\previous.south west)}, second line={(0,0)--(6,6)});
   1638     
   1639     % Top left
   1640     \node[inner sep=0.1pt] (tl-start) at (-4,4) {};
   1641     \xdef\previous{tl-start}
   1642     \foreach \pos/\content in {0/$0^2=0$,1/$2^2=4$,2/$6^2=36$,3/$8^2=64$,4/$\vphantom{X}\dots$}{
   1643       \node[anchor=south] (tl-temp-\pos) at (intersection cs: first line={(\previous.north west)--(\previous.north east)}, second line={(0,0)--(-6,6)}) {\phantom{\content}};
   1644       \node[anchor=north east] (tl-\pos) at (intersection cs: first line={(tl-temp-\pos.north west)--(tl-temp-\pos.north east)}, second line={(0,0)--(-6,6)}) {\content};
   1645       \xdef\previous{tl-\pos}
   1646     }
   1647     \draw[bigarrow] (pre-phantom-0-0) -- (intersection cs: first line={(\previous.north east)--(\previous.south east)}, second line={(0,0)--(-6,6)});
   1648     
   1649     % Bottom left
   1650     \node[inner sep=0.1pt] (bl-start) at (-4,-4) {};
   1651     \xdef\previous{bl-start}
   1652     \foreach \pos/\content in {0/$0\times 1=0$,1/$2\times 3=6$,2/$4\times 5=20$,3/$6\times 7=42$,4/$\vphantom{X}\dots$}{
   1653       \node[anchor=north] (bl-temp-\pos) at (intersection cs: first line={(\previous.south west)--(\previous.south east)}, second line={(0,0)--(-6,-6)}) {\phantom{\content}};
   1654       \node[anchor=south east] (bl-\pos) at (intersection cs: first line={(bl-temp-\pos.south west)--(bl-temp-\pos.south east)}, second line={(0,0)--(-6,-6)}) {\content};
   1655       \xdef\previous{bl-\pos}
   1656     }
   1657     \draw[bigarrow] (pre-phantom-0-0) -- (intersection cs: first line={(\previous.north east)--(\previous.south east)}, second line={(0,0)--(-6,-6)});
   1658     
   1659     % Bottom right
   1660     \node[inner sep=0.1pt] (br-start) at (5,-4) {};
   1661     \xdef\previous{br-start}
   1662     \foreach \pos/\content in {0/$1^2=1$,1/$3^2=9$,2/$5^2=25$,3/$7^2=49$,4/$\vphantom{X}\dots$}{
   1663       \node[anchor=north] (br-temp-\pos) at (intersection cs: first line={(\previous.south west)--(\previous.south east)}, second line={(1,0)--(6,-5)}) {\phantom{\content}};
   1664       \node[anchor=south west] (br-\pos) at (intersection cs: first line={(br-temp-\pos.south west)--(br-temp-\pos.south east)}, second line={(1,0)--(6,-5)}) {\content};
   1665       \xdef\previous{br-\pos}
   1666     }
   1667     \draw[bigarrow] (pre-phantom-1-0) -- (intersection cs: first line={(\previous.north west)--(\previous.south west)}, second line={(1,0)--(6,-5)});
   1668     % Fin diagonales
   1669 
   1670     % Définitions pour le code ci-dessous.
   1671     \xdef\i{0}
   1672     \xdef\x{0}
   1673     \xdef\y{0}
   1674     \xdef\corner{4}
   1675     \xdef\sidelen{0}
   1676     \xdef\nextsidelen{1}
   1677     \xdef\direction{3}
   1678     \incr\maxnums
   1679     \incr\maxcoords
   1680     
   1681     \def\reallysmallcheat#1{%
   1682       \ensuremath{\hphantom{\vphantom{X}}_{\hphantom{\vphantom{X}}_{#1}}}
   1683     }
   1684     \def\drawnode{%
   1685       \node[dot] (dot-\x-\y) at (\x,\y) {};
   1686       \node[dotphantom] (phantom-\x-\y) at (\x,\y) {};
   1687       \ifnum\maxnums>\i
   1688         \ifnum\corner=0    \node[numero,anchor=north west] at (dot-\x-\y.south east) {\i}; \else
   1689         \ifnum\corner=1    \node[numero,anchor=south west] at (dot-\x-\y.north east) {\i}; \else
   1690         \ifnum\corner=2    \node[numero,anchor=south east] at (dot-\x-\y.north west) {\i}; \else
   1691         \ifnum\corner=3    \node[numero,anchor=north east] at (dot-\x-\y.south west) {\i}; \else
   1692         \ifnum\direction=0 \node[numero,anchor=west]       at (dot-\x-\y.east)       {\i}; \else
   1693         \ifnum\direction=1 \node[numero,anchor=south]      at (dot-\x-\y.north)      {\i}; \else
   1694         \ifnum\direction=2 \node[numero,anchor=east]       at (dot-\x-\y.west)       {\i}; \else
   1695         \ifnum\direction=3 \node[numero,anchor=north]      at (dot-\x-\y.south)      {\i}; \fi\fi\fi\fi\fi\fi\fi\fi
   1696       \fi
   1697       \ifnum\maxcoords>\i
   1698         \ifnum\corner=0    \node[coord,anchor=south east] at (dot-\x-\y.north west) {\reallysmallcheat{(\x, \y)}}; \else
   1699         \ifnum\corner=1    \node[coord,anchor=north east] at (dot-\x-\y.south west) {\reallysmallcheat{(\x, \y)}}; \else
   1700         \ifnum\corner=2    \node[coord,anchor=north west] at (dot-\x-\y.south east) {\reallysmallcheat{(\x, \y)}}; \else
   1701         \ifnum\corner=3    \node[coord,anchor=south west] at (dot-\x-\y.north east) {\reallysmallcheat{(\x, \y)}}; \else
   1702         \ifnum\direction=0 \node[coord,anchor=east]       at (dot-\x-\y.west)       {\reallysmallcheat{(\x, \y)}}; \else
   1703         \ifnum\direction=1 \node[coord,anchor=north]      at (dot-\x-\y.south)      {\reallysmallcheat{(\x, \y)}}; \else
   1704         \ifnum\direction=2 \node[coord,anchor=west]       at (dot-\x-\y.east)       {\reallysmallcheat{(\x, \y)}}; \else
   1705         \ifnum\direction=3 \node[coord,anchor=south]      at (dot-\x-\y.north)      {\reallysmallcheat{(\x, \y)}}; \fi\fi\fi\fi\fi\fi\fi\fi
   1706       \fi
   1707     }
   1708     \def\drawlinknode{%
   1709       \drawnode%
   1710       \draw[->] (phantom-\oldx-\oldy) -- (phantom-\x-\y);%
   1711     }
   1712     \def\mystep{%
   1713       \incr\i%
   1714       \xdef\oldx{\x}%
   1715       \xdef\oldy{\y}%
   1716     }
   1717     \def\changedir#1{%
   1718       \xdef\direction{#1}%
   1719       \xdef\corner{#1}%
   1720     }
   1721     
   1722     \drawnode
   1723     \mystep \incr\x
   1724     \xdef\cornerc{0}
   1725 
   1726     \foreach \pos in {1,...,\maxdots} {
   1727       % Detect when we are at the end of this edge.
   1728       \ifnum\sidelen=0
   1729         \ifnum\direction=0 \changedir{1} \incr\nextsidelen \else
   1730         \ifnum\direction=1 \changedir{2}                   \else
   1731         \ifnum\direction=2 \changedir{3} \incr\nextsidelen \else
   1732         \ifnum\direction=3 \changedir{0}                   \fi\fi\fi\fi% Brin d'acier
   1733         \xdef\sidelen{\nextsidelen}
   1734       \fi
   1735       % Draw node and link to previous, step counters
   1736       \drawlinknode \mystep
   1737       %% Se déplacer vers ↑←↓→
   1738       \ifnum\direction=0 \incr\y \fi
   1739       \ifnum\direction=1 \decr\x \fi
   1740       \ifnum\direction=2 \decr\y \fi
   1741       \ifnum\direction=3 \incr\x \fi
   1742       \decr\sidelen
   1743       \xdef\corner{4}%% 4 == pas de coin-coin.
   1744     }
   1745   \end{tikzpicture}
   1746   \caption{Codage d'un couple d'entiers relatifs}
   1747   \label{fig:codage-rel}
   1748 \end{figure}
   1749 
   1750 Bien que les algorithmes d'encodage et de décodage ne soient pas les mêmes, le principe reste identique. 
   1751 
   1752 On peut faire plusieurs constations~:
   1753 
   1754 \begin{itemize}
   1755 \item Le code correspondant aux couples (1,1), (2,2), (3,3), (4,4)\ldots sont respectivement 1, 2, 12, 30\ldots, ce qui correspond à $(1 \times 2)$, $(3 \times 4)$, $(5 \times 6)$, $(7 \times 8)$\ldots
   1756 \item Le code correspondant aux couples (0,0), (-1,-1), (-2,-2), (-3,-3)\ldots sont respectivement 0, 6, 20, 42\ldots, ce qui correspond à $(0 \times 1)$, $(2 \times 3)$, $(4 \times 5)$, $(6 \times 7)$\ldots
   1757 \item Le code des couples $(1,0)$, $(2,-1)$, $(3,-2)$, $(4,-3)$ sont respectivement $1$, $9$, $25$, $49$\ldots ce qui correspond à la valeur de $(x + |y|))^{2}$, ce sont les carrés des entiers impairs.
   1758 \item Le code des couples $(-1,-1)$, $(-2,-2)$, $(-3,-3)$, $(-4,-4)$ sont respectivement $4$, $16$, $36$, $64$\ldots,  ce qui correspond à la valeur de $(|x| + |y|))^{2}$, ce sont les carrés des entiers pairs.
   1759 \end{itemize}
   1760 
   1761 
   1762 A l'aide de ces constations, on peut coder n'importe quel couple d'entiers. En voici un exemple en C~:
   1763 
   1764 
   1765 \begin{lstlisting}[language=C]
   1766 long int orderedPairToCodeIntAlgo2(int x, int y){
   1767 	long int code = 0;
   1768 	int _x, _y, diff;
   1769 	_x = _y = diff = 0;
   1770 	int temp;
   1771 	int absmax;	
   1772 	absmax = max(abs(x), abs(y));	
   1773 	
   1774 	if(absmax == abs(x)){ // _x == x 
   1775 		_x = _y = x;
   1776 		temp = abs(x) * 2;
   1777 		if(x < 0){ // x negative
   1778 			code = temp * (temp + 1);
   1779 			if(y < 0){ // x negative, y negative
   1780 				diff = abs(_y) - abs(y);
   1781 			}
   1782 			else{ // x negative, y positive
   1783 				diff = abs(_y) + abs(y);
   1784 			}
   1785 		}
   1786 		else{ // x positive
   1787 			code = (temp - 1) * temp; 
   1788 			if(y > 0){ // x positive, y positive
   1789 				diff = abs(_y) - abs(y);
   1790 			}
   1791 			else{ // x positive, y negative
   1792 				diff = abs(_y) + abs(y);
   1793 			}
   1794 		}
   1795 		code = code - diff;
   1796 	}
   1797 	else{ // _y = y
   1798 		_x = _y = y;
   1799 		temp = abs(y) * 2;
   1800 		if(y < 0){ // y negative
   1801 			code = temp * (temp + 1);		
   1802 			if(x < 0){ // y negative, x negative
   1803 				diff = abs(_x) - abs(x);
   1804 			}
   1805 			else{ // y negative, x positive
   1806 				diff = abs(_x) + abs (x);
   1807 			}
   1808 		}
   1809 		else{ // y positive
   1810 			code = (temp - 1) * temp;
   1811 			if(x > 0){ // y positive, x positive
   1812 				diff = abs(_x) - abs(x);
   1813 			}
   1814 			else{ // y positive, x negative
   1815 				diff = abs(_x) + abs(x);
   1816 			}	
   1817 		}	
   1818 		code = code + diff;	
   1819 	}
   1820 	return code;
   1821 }
   1822 \end{lstlisting}
   1823 
   1824 
   1825 On commence par trouver le max de $|x|$ et $|y|$~: $(-3,1)$ nous donnerait comme $absmax$ la valeur $3$. Ensuite on détermine si cette valeur correspond à la valeur de $x$ ou la valeur de $y$. Si cette valeur correspond à la valeur de $x$ (resp. $y$), on affecte la valeur de $x$ (resp. $y$) aux variables temporaires $\_x$ et $\_y$. Ensuite, on se sert de la propriété des multiplications décrite précédemment selon les quatre cas de figures possibles, à savoir, le cas où $x$ et $y$ sont positives, le cas où $x$ et $y$ sont négatives, celui où $x$ est positive et $y$ est négative, et inversement. On affecte une valeur provisoire à la variable $code$, qui est soit $temp$ (la valeur absolue de la max des deux coordonnées) multiplié par $temp + 1$ ou bien $temp$ multiplié par $temp - 1$ selon que la valeur de la coordonnée $absmax$ est négative ou positive respectivement. Nous avons à ce point un code approximatif. On peut facilement trouver la coordonnée correspondant à $absmax$, et pour trouver l'autre coordonnée on calcule la différence entre la valeur absolue de la coordonnée qu'on connaît et l'autre coordonnée afin d'ajuster le code. Puis, enfin, on retourne le code exact.
   1826 
   1827 Le décodage utilise le même principe mais dans le sens inverse~:
   1828 
   1829 \begin{lstlisting}[language=C]
   1830 int* codeToOrderedPairIntAlgo2(long int code){
   1831 	int* pair = malloc(2*sizeof(int));
   1832 	int isqrtcode = (int) sqrt(code);
   1833 	long int pivotcode = isqrtcode * (isqrtcode + 1);
   1834 	int x, y;
   1835 	x = y = 0;	
   1836 
   1837 	if(even(isqrtcode)){
   1838 		x = y = -(isqrtcode / 2);
   1839 		if(code > pivotcode){
   1840 			x = x + (code - pivotcode);
   1841 		}
   1842 		else{
   1843 			y = y + (pivotcode - code);
   1844 		}
   1845 	}
   1846 	else{
   1847 		x = y = (isqrtcode / 2) + 1;
   1848 		if(code > pivotcode){
   1849 			x = x - (code - pivotcode);
   1850 		}
   1851 		else{
   1852 			y = y - (pivotcode - code); 
   1853 		}
   1854 	}
   1855 	pair[0] = x;
   1856 	pair[1] = y; 
   1857 	return pair;
   1858 }
   1859 \end{lstlisting}
   1860 
   1861 Plusieurs programmes complets pour le codage des entiers naturels et le codage des entiers se trouve annexe~: couples-2.lisp (page \pageref{couples2lisp}), couples-3.lisp (page \pageref{couples3lisp}), couples.c (page \pageref{couplesc}) et couple\_entiers.c (page \pageref{coupleentiersc}).
   1862 
   1863 
   1864 
   1865 \begin{enonce}
   1866 Montrer que l'on peut coder les triplets. Généraliser aux k-uplets, puis aux listes de longueurs quelconques.
   1867 \end{enonce}
   1868 
   1869 Pour coder un triplet $(x_1, x_2, x_3)$, on code d'abord le couple $(x_1, x_2)$, puis, soit $x^*$ le résultat intermédiaire, on code le couple $(x^*, x_3)$.
   1870 
   1871 \begin{figure}[ht!]
   1872   \centering
   1873   \begin{tikzpicture}
   1874     \node (x11) {$x_1$};
   1875     \node[right of=x11] (x21) {$x_2$};
   1876     \node[right of=x21] (x31) {$x_3$};
   1877     \node[coordinate] (xmark) at ($ .5*(x11) + .5*(x21) $) {};
   1878     \node[below of=xmark] (x*2) {$x^*$};
   1879     \node[coordinate] (xmark2) at ($ .5*(xmark) + .5*(x*2) $) {};
   1880     
   1881     \node[anchor=base] (x32) at (x*2.base -| x31) {$x_3$};
   1882     
   1883     \node[coordinate] (xmark4) at ($ .5*(x*2) + .5*(x32) $) {};
   1884     \node[below of=xmark4] (x*3) {résultat};
   1885     \node[coordinate] (xmark5) at ($ .5*(xmark4) + .5*(x*3) $) {};
   1886     
   1887     \draw (x11) -- (xmark2);
   1888     \draw[->] (x21) -- (xmark2) -- (x*2);
   1889     \draw[->] (x31) -- (x32 |- x*2.north);
   1890     \draw (x*2) -- (xmark5);
   1891     \draw[->] (x32) -- (xmark5) -- (x*3);
   1892   \end{tikzpicture}
   1893   \caption{Codage d'un triplet d'entiers naturels}
   1894   \label{fig:codage-couple}
   1895 \end{figure}
   1896 
   1897 Le décodage suit tout simplement le chemin inverse (on décode ne nombre en $(x^*, x_3)$, puis on décode $x^*$ en $(x_1, x_2)$ et on recompose en $(x_1, x_2, x_3)$.
   1898 
   1899 La généralisation aux k-uplets suit le même principe : On code les deux premiers nombres de la paire en nommant le résultat $x^*$, puis, on
   1900 code successivement chaque paire $(x^*, x_i)$, avec $x_i$ qui vaut successivement chaque élément du k-uplet, et $x^*$ qui vaut à chaque fois
   1901 le résultat précédent.
   1902 
   1903 Le décodage d'un k-uplet de longueur k décodera le nombre en une paire $(x^*, x_i)$ $k-1$ fois, et la dernière paire ainsi générée sera
   1904 $(x_1, x_2)$. Il suffira alors de recomposer le k-uplet à partir de $x_1$, $x_2$ et tous les $x_i$.
   1905 
   1906 Le codage et le décodage d'un singleton sont triviaux : $(x_1) \leftrightarrow x_1$.
   1907 
   1908 Pour les listes de longueur quelconque, le problème est de savoir combien de fois faudra-t-il décoder le résultat. En effet, $(0)$, $(0,0)$
   1909 et $(0,0,0)$ ont le même code, $0$, donc il n'y a plus de bijection entre la liste et les entiers naturels, donc ambiguïté lors du décodage.
   1910 
   1911 Étant donné que pour un k donné, il y a une bijection entre les k-uplets et les entiers naturels, il nous suffit d'ajouter une information
   1912 permettant de déterminer de manière unique la valeur de k. On code donc d'abbord le k-uplet correspondant à la liste, en nommant le résultat
   1913 $x^*$, puis on code le couple $(x^*, k)$. Au décodage, on décodera le nombre pour obtenir $x^*$ et $k$, et on décodera $x^*$ avec la méthode
   1914 de décodage des k-uplets donnés ci-dessus.
   1915 
   1916 Reste un dernier problème, celui de pouvoir encoder des listes d'entiers relatifs (et non pas juste des entiers naturels). Pour cela, on
   1917 fera une transformation préalable sur chaque élément des k-uplets :
   1918 
   1919 Soit $n$ le $i$-ième élément du k-uplet, si $n$ est positif, on le transforme en le $n$-ième nombre pair, sinon, il est strictement négatif et on le transforme en le $|n|-1$ ième nombre impair. Ainsi, $0 \mapsto 0$, $1 \mapsto 2$, $2 \mapsto 4$, $-1 \mapsto 1$, $-2 \mapsto 3$, \dots
   1920 
   1921 \begin{equation}
   1922   \begin{array}{r l}
   1923     \mathrm{transformation} : Z & \longrightarrow N \\
   1924     n & \mapsto
   1925     \left \{
   1926       \begin{array}{r l}
   1927         2n       & \text{si $n$ est pair} \\
   1928         2(|n|-1) & \text{si $n$ est impair}
   1929       \end{array}
   1930     \right .
   1931   \end{array}
   1932 \end{equation}
   1933 
   1934 Le codage d'une liste d'entiers relatifs peut donc être résumé par la figure \ref{fig:codage-all}
   1935 
   1936 \begin{figure}[ht!]
   1937   \centering
   1938   \begin{tikzpicture}[
   1939     level distance=0.7cm,
   1940     circle,
   1941     inner sep=0.1pt,
   1942     ]
   1943     \node[rectangle, inner sep=1pt] (res) {$\text{résultat}$} [grow=up]
   1944     child[draw=red] {
   1945       node[coordinate] (catch-k) {} edge from parent[<-]
   1946     }
   1947     child {
   1948       node {x*}
   1949       child {
   1950         child {
   1951           child {
   1952             child {
   1953               child {
   1954                 child {
   1955                   node (xk) {$x_{\phantom{k}}$}
   1956                   % node[anchor=base] at (xk.base) {$\vphantom{x}_{k}$}
   1957                   % node[anchor=east] at (xk.east) {$\hphantom{x}_{k}$}
   1958                   node[anchor=base] (get-k-v) at (xk.base) {$\vphantom{x}_{\phantom{k}}$}
   1959                   node[anchor=east] (get-k-h) at (xk.east) {$\hphantom{x}_{\phantom{k}}$}
   1960                   node[coordinate] (get-k-se) at (get-k-v.south -| get-k-h.east) {}
   1961                   node[coordinate] (get-k-nw) at (get-k-v.north -| get-k-h.west) {}
   1962                   node[anchor=base east, draw=red, inner sep=0.15pt] (the-k)
   1963                   at (get-k-v.base -| get-k-h.east) {$\vphantom{.}_{k}$}
   1964                 }
   1965               }
   1966             }
   1967           }
   1968         } edge from parent[<-]
   1969       }
   1970       child {
   1971         node {x*}
   1972         child {
   1973           child {
   1974             child {
   1975               child {
   1976                 child {node {...} edge from parent[dashed]}
   1977                 edge from parent[dashed]
   1978               }
   1979               edge from parent[dashed]
   1980             }
   1981             edge from parent[dashed]
   1982           }
   1983           edge from parent[dashed,<-]
   1984         }
   1985         child {
   1986           node{x*}
   1987           child {
   1988             child {
   1989               child {
   1990                 child {node {$x_5$}}
   1991               }
   1992             } edge from parent[<-]
   1993           }
   1994           child {
   1995             node{x*}
   1996             child {
   1997               child {
   1998                 child {node {$x_4$}}
   1999               } edge from parent[<-]
   2000             }
   2001             child {
   2002               node{x*}
   2003               child {
   2004                 child {node {$x_3$}} edge from parent[<-]
   2005               }
   2006               child {
   2007                 node{x*} [sibling distance=7.5mm] edge from parent[<-]
   2008                 child {node {$x_2$} edge from parent[<-]}
   2009                 child {node {$x_1$} edge from parent[<-]}
   2010                 child[missing] {}
   2011               } edge from parent[<-]
   2012             } edge from parent[<-]
   2013           } edge from parent[<-]
   2014         } edge from parent[<-]
   2015       } edge from parent[<-]
   2016     };
   2017     
   2018     \draw[red] (the-k) -| (catch-k);
   2019     
   2020     \node[xshift=0cm, anchor=base west] at (res.base east) {$\vphantom{\text{résultat}} = \operatorname{code}(x^*,k)$};
   2021     
   2022     % \node (e11) {$x_1$}; 
   2023     % \node[right of=e11] (e21) {$x_2$};
   2024     % \node[right of=e21] (e31) {$x_3$};
   2025     % \node[right of=e31] (e41) {$x_4$};
   2026     % \node[right of=e41] (e51) {$x_5$};
   2027     % \node[right of=e51] (ed1) {\dots};
   2028     % \node[right of=ed1] (ek1) {$x_k$};
   2029 
   2030 
   2031     % \matrix[column sep=2mm, row sep=7mm]{
   2032     %   \node (e11) {$x_1$}; & \node[coordinate] (o11) {}; &
   2033     %   \node (e21) {$x_2$}; & \node[coordinate] (o21) {}; &
   2034     %   \node (e31) {$x_3$}; & \node[coordinate] (o31) {}; &
   2035     %   \node (e41) {$x_4$}; & \node[coordinate] (o41) {}; &
   2036     %   \node (e51) {$x_5$}; & \node[coordinate] (o51) {}; &
   2037     %   \node (ed1) {\dots}; & \node[coordinate] (o61) {}; &
   2038     %   \node (ek1) {$x_k$}; & \node[coordinate] (o71) {}; \\
   2039       
   2040     %   \node[coordinate] (e12) {}; & \node (o11) {$x^*$}; &
   2041     %   \node (e22) {$x_2$}; & \node[coordinate] (o22) {}; &
   2042     %   \node (e32) {$x_3$}; & \node[coordinate] (o32) {}; &
   2043     %   \node (e42) {$x_4$}; & \node[coordinate] (o42) {}; &
   2044     %   \node (e52) {$x_5$}; & \node[coordinate] (o52) {}; &
   2045     %   \node (ed2) {\dots}; & \node[coordinate] (o62) {}; &
   2046     %   \node (ek2) {$x_k$}; & \node[coordinate] (o72) {}; \\
   2047       
   2048     %   \node[coordinate] (e12) {}; & \node[coordinate] (o12) {}; &
   2049     %   \node[coordinate] (e22) {}; & \node (o22) {$x^*$}; & 
   2050     %   \node (e32) {$x_3$}; & \node[coordinate] (o32) {}; &
   2051     %   \node (e42) {$x_4$}; & \node[coordinate] (o42) {}; &
   2052     %   \node (e52) {$x_5$}; & \node[coordinate] (o52) {}; &
   2053     %   \node (ed2) {\dots}; & \node[coordinate] (o62) {}; &
   2054     %   \node (ek2) {$x_k$}; & \node[coordinate] (o72) {}; \\
   2055       
   2056     %   \node[coordinate] (e12) {}; & \node[coordinate] (o12) {}; &
   2057     %   \node[coordinate] (e22) {}; & \node[coordinate] (o22) {}; & 
   2058     %   \node[coordinate] (e32) {}; & \node (o32) {$x^*$}; &
   2059     %   \node (e42) {$x_4$}; & \node[coordinate] (o42) {}; &
   2060     %   \node (e52) {$x_5$}; & \node[coordinate] (o52) {}; &
   2061     %   \node (ed2) {\dots}; & \node[coordinate] (o62) {}; &
   2062     %   \node (ek2) {$x_k$}; & \node[coordinate] (o72) {}; \\
   2063       
   2064     %   \node[coordinate] (e12) {}; & \node[coordinate] (o12) {}; &
   2065     %   \node[coordinate] (e22) {}; & \node[coordinate] (o22) {}; & 
   2066     %   \node[coordinate] (e32) {}; & \node[coordinate] (o32) {}; &
   2067     %   \node[coordinate] (e42) {}; & \node (o42) {$x^*$}; &
   2068     %   \node (e52) {$x_5$}; & \node[coordinate] (o52) {}; &
   2069     %   \node (ed2) {\dots}; & \node[coordinate] (o62) {}; &
   2070     %   \node (ek2) {$x_k$}; & \node[coordinate] (o72) {}; \\
   2071     % };
   2072     
   2073     % \node[coordinate] (x11-21) at ($ .5*(x11) + .5*(x21) $) {};
   2074     % \node[coordinate] (x21-31) at ($ .5*(x11) + .5*(x21) $) {};
   2075     % \node[coordinate] (x31-41) at ($ .5*(x11) + .5*(x21) $) {};
   2076     % \node[coordinate] (x41-51) at ($ .5*(x11) + .5*(x21) $) {};
   2077     % \node[coordinate] (x51-d1) at ($ .5*(x11) + .5*(x21) $) {};
   2078     % \node[coordinate] (xd1-k1) at ($ .5*(x11) + .5*(x21) $) {};
   2079     
   2080     % \node[below of=xmark] (x*2) {$x^*$};
   2081     % \node[coordinate] (xmark2) at ($ .5*(xmark) + .5*(x*2) $) {};
   2082     
   2083     % \node[anchor=base] (x32) at (x*2.base -| x31) {$x_3$};
   2084     
   2085     % \node[coordinate] (xmark4) at ($ .5*(x*2) + .5*(x32) $) {};
   2086     % \node[below of=xmark4] (x*3) {résultat};
   2087     % \node[coordinate] (xmark5) at ($ .5*(xmark4) + .5*(x*3) $) {};
   2088     
   2089     % \draw (x11) -- (xmark2);
   2090     % \draw[->] (x21) -- (xmark2) -- (x*2);
   2091     % \draw[->] (x31) -- (x32 |- x*2.north);
   2092     % \draw (x*2) -- (xmark5);
   2093     % \draw[->] (x32) -- (xmark5) -- (x*3);
   2094   \end{tikzpicture}
   2095   \caption{Codage d'un $n$-uplet d'entiers}
   2096   \label{fig:codage-all}
   2097 \end{figure}
   2098 
   2099 %% TODO : ce qui suit est un doublon du début de l'exercice !?!
   2100 
   2101 Pour coder les triplets, on considère un triplet, (3,1,2) par exemple, comme un couple (3,(1,2)). On calcule le code du couple imbriqué,
   2102 c'est-à-dire du couple (1,2), ce qui nous donne 8. On refait le même codage en substituant 8 à (1,2), ce qui nous donne (3,8). On code
   2103 ensuite (3,8) et notre résultat est 74. L'algorithme est récursif, tant qu'on n'a pas un couple à deux éléments atomiques, on continue à
   2104 coder les \og{}sous-couples\fg{}, ce qui nous permet non seulement de coder les triplets, mais de coder n'importe quel k-uplet. Donc, pour
   2105 ce faire, il nous faut deux informations, le code et la taille du k-uplet, qui est implicite lorsque l'on code, mais qui doit être
   2106 explicitée lorsque l'on doit trouver le k-uplet à partir d'un code.
   2107 
   2108 Voici le code en C pour coder et décoder respectivement n'importe quel k-uplet de nombres entiers en reprenant les fonctions déjà décrites
   2109 dans la réponse de la question précédente~:
   2110 
   2111 \begin{lstlisting}[language=C]
   2112 
   2113 long int orderedMultipleToCodeInt(int *arr, int size){
   2114 	long int code;	
   2115 	if(size > 1){
   2116 		code = orderedPairToCodeInt(arr[size - 2], arr[size - 1]);
   2117 		arr[size - 2] = code;
   2118 		arr = realloc(arr, (size - 1));
   2119 		if(size > 2){		
   2120 			code = orderedMultipleToCodeInt(&arr[0], (size - 1));
   2121 		}
   2122 	}
   2123 	return code;
   2124 }
   2125 
   2126 int* codeToOrderedMultipleInt(long int code, int size){
   2127 	int *multiple = malloc(size*sizeof(int));
   2128 	int *pair;
   2129 	int i = 0;
   2130 	for(i = 0; i < (size - 1); i++){
   2131 		pair = codeToOrderedPairInt(code);
   2132 		code = pair[1];
   2133 		multiple[i] = pair[0];
   2134 		multiple[i + 1] = pair[1];
   2135 	}
   2136 	return multiple;
   2137 }
   2138 
   2139 \end{lstlisting}
   2140 
   2141 
   2142 Plusieurs programmes permettant de coder et de décoder des couples et des k-uplets en LISP et en C sont fournis en annexe de ce document, y
   2143 compris les fonctions 'int* codeToOrderedMultipleIntAlgo2(long int code, int size)' et 'long int orderedMultipleToCodeIntAlgo2(int *arr, int
   2144 size)' qui se servent du deuxième algorithme pour coder et pour décoder les k-uplets de nombres entiers.
   2145 
   2146 
   2147 \begin{enonce}
   2148   Peut-on énumérer les fonctions C syntaxiquements correctes ? Et les fonctions C qui ne bouclent jamais ? Justifier vos réponses le plus
   2149   clairement et le plus synthétiquement possible.
   2150 \end{enonce}
   2151 
   2152 On sait énumérer récursivement toutes les séquences d'octets~:
   2153 
   2154 Pour passer d'une séquence à la suivante, on commence par le dernier octet. S'il est inférieur à 255, on incrémente sa valeur de 1, sinon on passe à l'octet d'avant, et continue la même démarche. Si on arrive au premier octet de la séquence sans avoir pu en incrémenter de 1, on crée une séquence d'octets de longueur $n + 1$ (où $n$ est la longueur de la séquence courante) dans laquelle chaque octet vaut zéro.
   2155 
   2156 Pour énumérer les fonctions C syntaxiquement correctes, on passe successivement chaque séquence d'octets et on vérifie si elle correspond à une fonction C syntaxiquement correcte (La reconaissance de la syntaxe C peut être faite grâce à un automate, qui se termine toujours dans un temps fini). S'il s'agit d'une fonction C syntaxiquement correcte, on l'affiche, et dans tous les cas on passe à la suivante et on recommence.
   2157 
   2158 Énumérer les fonctions consiste à fournir un algorithme (donc un programme) permettant de donner l'élément suivant à partir de l'élément courant (ou de les donner un à un, ce qui revient à la même chose).
   2159 
   2160 Dans ce cas-ci, il faudrait donc faire un programme (algorithme) qui énumère toutes les fonctions C (ce qu'on sait faire), et soit capable de ne pas lister celles qui bouclent indéfiniment.
   2161 
   2162 Or, cela signifierait que ce programme (algorithme) serait capable de résoudre le problème de l'arrêt, ce qui n'est pas possible.
   2163 
   2164 % TODO : faire un titre de la ligne suivante
   2165 \textbf{Démonstration de l'impossibilité de résoudre algorithmiquement le problème de l'arrêt.}
   2166 
   2167 Supposons qu'il existe un programme $h(p, x)$ prennant en paramètre un programme et une donnée tel que :
   2168 \[
   2169 h(p, x) = \left\{
   2170 \begin{array}{ll}
   2171   1 & \qquad \text{si $p(x)$ se termine} \\
   2172   0 & \qquad \text{sinon $p(x)$ boucle indéfiniment} \\
   2173 \end{array}
   2174 \right.
   2175 \]
   2176 
   2177 \ldots on pourrait alors construire le programme $gamma(n)$ suivant~:
   2178 \begin{lstlisting}[language=C]
   2179   int gamma(int n) {
   2180     if (h(gamma, n))
   2181      while (1);
   2182     else
   2183      return (0);
   2184   }
   2185 \end{lstlisting}
   2186 Si $gamma(n)$ se termine, alors $gamma(n)$ boucle et donc ne se termine pas. Si $gamma(n)$ ne se termine pas, alors $gamma(n)$ retourne 0,
   2187 donc $gamma(n)$ se termine.
   2188 
   2189 Dans les deux cas, il y a contradiction. Par conséquent, il n'est pas possible de déterminer algorithmiquement si un programme s'arrête ou
   2190 boucle indéfiniment, et donc il est impossible d'énumerer toutes les fonctions C qui ne bouclent jamais (puisqu'on ne peut pas savoir si la
   2191 fonction en question boucle ou non, on ne peut pas savoir si elle fait partie de l'énumération ou non).
   2192 
   2193 \section{Partie pratique sur les algorithmes de flots}
   2194 
   2195 
   2196 \subsubsection*{Exercice \stepcounter{exocount}\bf\small \arabic{exocount} -- La méthode de Edmonds-Karp et celle de Dinic}
   2197 \addcontentsline{toc}{subsubsection}{Exercice \arabic{exocount} -- La méthode de Edmonds-Karp et celle de Dinic}
   2198 \setcounter{enoncecount}{0}
   2199 
   2200 \begin{enonce}
   2201 Programmer une procédure qui construit à partir d'un graphe orienté valué (les valuations représentent les capacités) et deux sommets $s$ et $p$ du graphe, le graphe d'écart associé (correspondant à un flot nul sur chaque arc).
   2202 \end{enonce}
   2203 
   2204 (Voir Annexe B, page \pageref{annexeexo5})
   2205 
   2206 \begin{enonce}
   2207 Programmer un procédure qui à partir d'un graphe orienté et deux sommets $s$ et $p$ donne un plus court chemin en nombre d'arcs de $s$ à $p$ ou qui signale s'il n'y en a pas.
   2208 \end{enonce}
   2209 
   2210 (Voir Annexe B, page \pageref{annexeexo5})
   2211 
   2212 \begin{enonce}
   2213 Etant donnés un graphe G orienté et valué et un chemin de G, écrire une fonction uqi calcule l'arc de plus petite valuation sur le chemin.
   2214 \end{enonce}
   2215 
   2216 (Voir Annexe B, page \pageref{annexeexo5})
   2217 
   2218 \begin{enonce}
   2219 Etant donnés un graphe d'écard, un chemin et un entier $k$, donner une procédure qui met à jour le graphe d'écard si on augmente le flot de $k$ le long de la chaîne augmentante correspondant au chemin. 
   2220 \end{enonce}
   2221 
   2222 (Voir Annexe B, page \pageref{annexeexo5})
   2223 
   2224 \begin{enonce}
   2225 Ecrire une procédure qui à partir du graphe initial et du graphe d'écard final (plus de chemins entre $s$ et $p$ donne la valeur du flot maximum ainsi que la valeur deu flot sur chaque arc lorsque le flot maximum est atteint. 
   2226 \end{enonce}
   2227 
   2228 (Voir Annexe B, page \pageref{annexeexo5})
   2229 
   2230 \begin{enonce}
   2231 En utilisant les procédures et les fonctions précédentes, programmer l'algorithme de Edmond-Karp. 
   2232 \end{enonce}
   2233 
   2234 (Voir Annexe B, page \pageref{annexeexo5})
   2235 
   2236 \begin{enonce}
   2237 Ecrire une procédure qui prend en compte l'ensemble des plus cours chemins en nombres d'arcs.
   2238 \end{enonce}
   2239 
   2240 (Voir Annexe B, page \pageref{annexeexo5})
   2241 
   2242 \begin{enonce}
   2243 Ecrire une procédure qui calcule la plus petite valeur du flot dans le graphe de couche.
   2244 \end{enonce}
   2245 
   2246 (Voir Annexe B, page \pageref{annexeexo5})
   2247 
   2248 \begin{enonce}
   2249 Ecrire une procédure qui met à jour le flot dans le graphe G. 
   2250 \end{enonce}
   2251 
   2252 (Voir Annexe B, page \pageref{annexeexo5})
   2253 
   2254 \begin{enonce}
   2255 En déduire l'algorithme de Dinic.
   2256 \end{enonce}
   2257 
   2258 (Voir Annexe B, page \pageref{annexeexo5})
   2259 
   2260 \begin{enonce}
   2261 Comparer les résultats (temps d'exécution, taux d'occupation mémoire) entre les deux méthodes. Vous apporterez un soin tout particulier à la génération de vos résultats et à leur présentation.
   2262 \end{enonce}
   2263 
   2264 Les graphiques ci-dessous représentent le temps d'exécution et l'espace mémoire utilisé par nos implémentations de l'algorithme de Dinic et d'Elmonds-Karp. Notre implémentation de l'algorithme de Dinic fonctionne, mais les résultats montrés dans les graphiques ne reflète pas la réalité car nous avons mal implémenté la gestion de la structure de couche dans cet algorithme, ce qui rend notre implémentation très gourmand en mémoire. 
   2265 
   2266 \newpage
   2267 \input{temps}
   2268 \newpage
   2269 \input{espace}
   2270 \newpage
   2271 \input{espace2}
   2272 \newpage
   2273 
   2274 \appendix
   2275 \section{Annexe~: Exercice 4}
   2276 \label{annexe-deb}
   2277 \newpage
   2278 \subsection{couples.lisp}
   2279 \label{coupleslisp}
   2280 \begin{lstlisting}[language=Lisp, basicstyle=\footnotesize]
   2281 
   2282 ;;COUPLES.LISP
   2283 
   2284 ;; definition des variables globales (toujours entre asterisques)
   2285 (defvar *current* (list 0 0 0)) ;; liste courante "(code x y)"
   2286 (setf *current* (list 0 0 0)) 
   2287 (defvar *db* nil) ;; base de donnees qui stocke tous les "(code x y)"
   2288 (setf *db* nil)
   2289 (push *current* *db*)
   2290 
   2291 (defvar *max-x* 0) ;; valeur maximal courante de x
   2292 (setf *max-x* 0)
   2293 (defvar *max-y* 0) ;; valeur maximal courante de y
   2294 (setf *max-y* 0)
   2295 
   2296 #| pour remettre toutes les variables globales a leur valeurs par defaut 
   2297 afin de tester, de refaire un 'zig-zag', etc.
   2298 |#
   2299 (defun reset ()
   2300   (progn
   2301     (defvar *current* (list 0 0 0)) ;; liste courante (cle x y)
   2302     (setf *current* (list 0 0 0))  
   2303     (defvar *db* nil) ;; base de donnees qui stocke tous les "(cle x y)"
   2304     (setf *db* nil)
   2305     (push *current* *db*)
   2306     (defvar *max-x* 0) ;; valeur maximal de x jusque "la"
   2307     (setf *max-x* 0)
   2308     (defvar *max-y* 0) ;; valeur maximal de y jusque "la"
   2309     (setf *max-y* 0)
   2310     *current*))
   2311   
   2312 #| Les fonctions "right" "down-left", "down", "up-right" imitent le movement des 
   2313 coordonnees sur un graphe mais au les coordonnees "y" positifs sont en DESSOUS du graphe
   2314 |#
   2315 (defun right (L)
   2316   (progn
   2317     (push
   2318       (setf *current*
   2319         (cons (+ 1 (first L)) (cons (+ 1 (second L)) (last L)))) *db*)
   2320     *current*))
   2321   
   2322 (defun down (L)
   2323   (progn
   2324     (push
   2325       (setf *current*
   2326         (cons (+ 1 (first L)) (cons (second L) (cons (+ 1 (third L)) ())))) *db*)
   2327      *current*))
   2328 
   2329 (defun up-right (L)
   2330   (progn
   2331     (push
   2332       (setf *current*
   2333         (cons (+ 1 (first L)) (cons (+ 1 (second L)) (cons (- (third L) 1) ())))) *db*)
   2334     *current*))
   2335     
   2336 (defun down-left (L)
   2337   (progn
   2338 	(push
   2339 	  (setf *current*
   2340 	    (cons (+ 1 (first L)) (cons (- (second L) 1) (cons (+ 1 (third L)) ())))) *db*)
   2341     *current*))
   2342 
   2343 (defun update-max-x (L)
   2344   (if (> (second L) *max-x*)
   2345     (setf *max-x* (second L))
   2346     nil))
   2347 
   2348 (defun update-max-y (L)
   2349   (if (> (third L) *max-y*)
   2350     (setf *max-y* (third L))
   2351     nil))
   2352 
   2353 (defun update-max-x-y (L)
   2354   (cond
   2355     ((> (second L) *max-x*)
   2356       (setf *max-x* (second L)))
   2357     ((> (third L) *max-y*)
   2358       (setf *max-y* (third L)))
   2359     (t ())))
   2360 
   2361 ;; "move" s'occupe de choisir "right", "down-left" etc. selon les valeurs dans *current*
   2362 (defun move (L)
   2363   (cond
   2364     ((and (zerop (third L)) (= *max-x* *max-y*)) ;; RIGHT takes precedence over LEFT becuase it occurs first
   2365       (print "in RIGHT") ;; 
   2366          (right L))
   2367     ((and (zerop (second L)) (= *max-x* *max-y*)) ;; DOWN
   2368       (print "in DOWN") 
   2369          (down L))
   2370     ((> *max-x* *max-y*) ;; DOWN-LEFT
   2371       (print "in DOWN-LEFT")  
   2372          (down-left L))
   2373     ((< *max-x* *max-y*) ;; UP-RIGHT
   2374       (print "in UP-RIGHT") 
   2375          (up-right L))))
   2376 
   2377 #|
   2378 On fait un "move" et puis un "update-max-x-y"
   2379 Attention : il faut bien faire un setf L, sinon, le parametre L de "update-max-x-y utilise la valeur
   2380 de L inchange !
   2381 |#
   2382 (defun move-and-update (L)
   2383   (progn
   2384     (setf L (move L))
   2385     (update-max-x-y L)
   2386     *db*))
   2387 
   2388 ;; "zig-zag" fait n "move-and-update" en un seul coup et affiche le contenu de *db* (toutes les couples) 
   2389 (defun zig-zag (L n)
   2390     (if (zerop n) 
   2391       (move-and-update *current*)
   2392       (progn
   2393         (move-and-update *current*)
   2394         (zig-zag L (- n 1)))))
   2395 
   2396 ;;END COUPLES.LISP
   2397 
   2398 \end{lstlisting}
   2399 
   2400 \subsection{couples-2.lisp}
   2401 \label{couples2lisp}
   2402 \begin{lstlisting}[language=Lisp, basicstyle=\footnotesize]
   2403 
   2404 ;;COUPLES-2.LISP
   2405 
   2406 (defun gauss-formula (n)
   2407   (/ (* n (+ n 1)) 2))
   2408 
   2409 (defun get-n (code)
   2410   (isqrt (* code 2)))
   2411 
   2412 (defun get-axis (code)
   2413   (gauss-formula (isqrt (* code 2))))
   2414 
   2415 (defun get-axis-from-n (n)
   2416   (gauss-formula n))
   2417 
   2418 (defun axis-code-compare (code)
   2419   (format t "~d    ~d~%" code (get-axis code))) 
   2420 
   2421 (defun axis-code-compare-n (startcode n)
   2422   (let ((i 0))
   2423     (loop
   2424       (when (> i n) (return))
   2425       (axis-code-compare (+ startcode i))
   2426       (incf i))))
   2427   
   2428 (defun ord-pr-to-code (x y)
   2429   (let ((sumxy (+ x y)))
   2430     (if (evenp sumxy)
   2431       (+ (gauss-formula sumxy) x)
   2432       (+ (gauss-formula sumxy) y))))
   2433 
   2434 (defun code-to-ord-pr (code)
   2435   (let ((n (get-n code))
   2436         (axis (get-axis code))
   2437         (diff 0))
   2438   (progn
   2439     (when (> (get-axis code) code)
   2440       (progn
   2441         (setf n (- n 1))
   2442         (setf axis (get-axis-from-n n))))
   2443     (setf diff (- code axis))
   2444     (if (evenp n)
   2445       (cons diff (cons (- n diff) ()))
   2446       (cons (- n diff) (cons diff ()))))))
   2447 
   2448 (defun ord-mult-to-code (L)
   2449   (if (= (list-length L) 1)
   2450     (car L)
   2451     (ord-mult-to-code (append (butlast (butlast L)) 
   2452                         (cons (ord-pr-to-code (car (last (butlast L))) (car (last L))) ())))))
   2453 
   2454 (defun code-to-ord-mult (L-or-code size)
   2455   (if (atom L-or-code)
   2456        (code-to-ord-mult (code-to-ord-pr L-or-code) (- size 1))
   2457     (if (not (= size 1))
   2458         (code-to-ord-mult (append (butlast L-or-code) (code-to-ord-pr (car (last L-or-code))))
   2459           (- size 1))
   2460       L-or-code)))
   2461 
   2462 #| Les codes generes par cette fonction ne correspondent pas au code genere par le
   2463 diagramme du rapport ni des fonctions ord-mult-to-code et code-to-ord-mult. 
   2464 Toutefois, la fonction ci-dessous a ete creees ici car son ecriture et beaucoup plus idiomatique
   2465 en LISP (d'ou le nom 'ord-mult-to-code-lisp'). En effet, si on avait a coder les nombres naturels en LISP, on ajouterait 
   2466 (resp. supprimerait) des elements de la liste en partant du debut de la liste afin de creer
   2467 une paire ou un n-uplet (resp. pour trouver le code correspondant a une paire ou un n-uplet
   2468 |#
   2469 (defun ord-mult-to-code-lisp (L)
   2470   (if (= (list-length L) 1)
   2471     (car L)
   2472     (ord-mult-to-code-lisp (cons (ord-pr-to-code (first L) (second L)) (cddr L)))))
   2473 
   2474 #| voir le commentaire precedent concernant la fonction ord-mult-to-code-lisp |#
   2475 (defun code-to-ord-mult-lisp (L-or-code size)
   2476   (if (atom L-or-code)
   2477     (code-to-ord-mult-lisp (code-to-ord-pr L-or-code) (- size 1))
   2478     (if (not (= size 1))
   2479       (code-to-ord-mult-lisp (append (code-to-ord-pr (car L-or-code)) (cdr L-or-code)) (- size 1))
   2480       L-or-code)))
   2481 
   2482 #|
   2483 (defun code-to-ord-pr (code)
   2484   (;let* ((code*2 (* code 2))
   2485          (n (isqrt code*2))
   2486          (axis (gauss-formula n))
   2487          (diff 0))
   2488     (cond 
   2489       ((> axis code)
   2490          (loop while (> axis code)
   2491            ((setf n (- n 1)) 
   2492            (setf axis (gauss-formula n))))
   2493        (< axis code)
   2494           ((loop while (< axis code)
   2495              ((setf n (- n 1)) 
   2496              (setf axis (gauss-formula n))))
   2497            (when (> axis code)
   2498              ((setf n (- n 1))
   2499              (setf axis (gauss-formula n))))))
   2500         (t 5))))
   2501   |#           
   2502   
   2503 
   2504 (defun loop-test (n)
   2505   (let ((n 0))
   2506     (loop
   2507       (when (> n 10) (return))
   2508       (format t "~d ~d ~d~%" n (isqrt n) (gauss-formula n))
   2509       ;(print n) (write (* n n)) (write n)
   2510       (incf n))))
   2511 
   2512 ;;END COUPLES-2.LISP
   2513 
   2514 \end{lstlisting}
   2515 
   2516 \subsection{couples-3.lisp}
   2517 \label{couples3lisp}
   2518 \begin{lstlisting}[language=Lisp, basicstyle=\footnotesize]
   2519 
   2520 ;;COUPLES-3.LISP
   2521 
   2522 (defun gauss-formula (n)
   2523   (/ (* n (+ n 1)) 2))
   2524 
   2525 (defun get-n (code)
   2526   (isqrt (* code 2)))
   2527 
   2528 (defun get-axis (code)
   2529   (gauss-formula (isqrt (* code 2))))
   2530 
   2531 (defun get-axis-from-n (n)
   2532   (gauss-formula n))
   2533 
   2534 (defun axis-code-compare (code)
   2535   (format t "~d    ~d~%" code (get-axis code))) 
   2536 
   2537 (defun axis-code-compare-n (startcode n)
   2538   (let ((i 0))
   2539     (loop
   2540       (when (> i n) (return))
   2541       (axis-code-compare (+ startcode i))
   2542       (incf i))))
   2543   
   2544 (defun ord-pr-to-code-nat (x y)
   2545   (let ((sumxy (+ x y)))
   2546     (if (evenp sumxy)
   2547       (+ (gauss-formula sumxy) x)
   2548       (+ (gauss-formula sumxy) y))))
   2549 
   2550 (defun code-to-ord-pr-nat (code)
   2551   (let ((n (get-n code))
   2552         (axis (get-axis code))
   2553         (diff 0))
   2554   (progn
   2555     (when (> (get-axis code) code)
   2556       (progn
   2557         (setf n (- n 1))
   2558         (setf axis (get-axis-from-n n))))
   2559     (setf diff (- code axis))
   2560     (if (evenp n)
   2561       (cons diff (cons (- n diff) ()))
   2562       (cons (- n diff) (cons diff ()))))))
   2563 
   2564 (defun nat-to-int (nat)
   2565   (if (< nat 0)
   2566     (- (* 2 (abs nat)) 1)
   2567     (* 2 (abs nat))))
   2568 
   2569 (defun int-to-nat (int)
   2570   (if (evenp int)
   2571     (/ int 2) 
   2572     (ceiling (- (- (/ int 2)) 1))))
   2573     
   2574 
   2575 (defun ord-pr-to-code-int (x y)
   2576   (setf x (nat-to-int x))
   2577   (setf y (nat-to-int y))
   2578   (ord-pr-to-code-nat x y))
   2579 
   2580 (defun code-to-ord-pr-int (code)
   2581   (let ((L (code-to-ord-pr-nat code)))
   2582     (progn
   2583         (setf L (cons (int-to-nat (first L)) (cdr L)))
   2584         (setf L (cons (car L) (cons (int-to-nat (second L)) ())))
   2585       L)))  
   2586 
   2587 (defun ord-mult-to-code-nat (L)
   2588   (if (= (list-length L) 1)
   2589     (car L)
   2590     (ord-mult-to-code-nat (append (butlast (butlast L)) 
   2591                         (cons (ord-pr-to-code-nat (car (last (butlast L))) (car (last L))) ())))))
   2592 
   2593 (defun code-to-ord-mult-nat (L-or-code size)
   2594   (if (atom L-or-code)
   2595        (code-to-ord-mult-nat (code-to-ord-pr L-or-code) (- size 1))
   2596     (if (not (= size 1))
   2597         (code-to-ord-mult-nat (append (butlast L-or-code) (code-to-ord-pr (car (last L-or-code))))
   2598           (- size 1))
   2599       L-or-code)))
   2600 
   2601 #| Les codes generes par cette fonction ne correspondent pas au code genere par le
   2602 diagramme du rapport ni des fonctions ord-mult-to-code et code-to-ord-mult. 
   2603 Toutefois, la fonction ci-dessous a ete creees ici car son ecriture et beaucoup plus idiomatique
   2604 en LISP (d'ou le nom 'ord-mult-to-code-lisp'). En effet, si on avait a coder les nombres naturels en LISP, on ajouterait 
   2605 (resp. supprimerait) des elements de la liste en partant du debut de la liste afin de creer
   2606 une paire ou un n-uplet (resp. pour trouver le code correspondant a une paire ou un n-uplet.
   2607 On aurait pu faire pareil pour les fonctions concernant tous les entiers
   2608 |#
   2609 (defun ord-mult-to-code-nat-lisp (L)
   2610   (if (= (list-length L) 1)
   2611     (car L)
   2612     (ord-mult-to-code-lisp (cons (ord-pr-to-code (first L) (second L)) (cddr L)))))
   2613 
   2614 #| voir le commentaire precedent concernant la fonction ord-mult-to-code-lisp |#
   2615 (defun code-to-ord-mult-nat-lisp (L-or-code size)
   2616   (if (atom L-or-code)
   2617     (code-to-ord-mult-lisp (code-to-ord-pr L-or-code) (- size 1))
   2618     (if (not (= size 1))
   2619       (code-to-ord-mult-lisp (append (code-to-ord-pr (car L-or-code)) (cdr L-or-code)) (- size 1))
   2620       L-or-code)))
   2621 
   2622 (defun loop-test (n)
   2623   (let ((n 0))
   2624     (loop
   2625       (when (> n 10) (return))
   2626       (format t "~d ~d ~d~%" n (isqrt n) (gauss-formula n))
   2627       ;(print n) (write (* n n)) (write n)
   2628       (incf n))))
   2629 
   2630 ;;END COUPLES-3.LISP
   2631 
   2632 \end{lstlisting}
   2633 
   2634 \subsection{couples.c}
   2635 \label{couplesc}
   2636 \begin{lstlisting}[language=C, basicstyle=\footnotesize]
   2637 
   2638 //COUPLES.C
   2639 
   2640 #include <stdio.h>
   2641 #include <stdlib.h>
   2642 #include <math.h>
   2643 
   2644 int even(int x){
   2645 	return (!(x % 2));
   2646 }
   2647 
   2648 int max(int a, int b){
   2649 	if(a > b) 
   2650 		return a;
   2651 	return b;
   2652 }
   2653 
   2654 long int orderedPairToCodeNat(int x, int y){
   2655 	long code;
   2656 	int sumxy; 
   2657 	sumxy = x + y;
   2658 	code = ((sumxy)*(sumxy + 1))/2;
   2659 
   2660 	if(even(sumxy)){
   2661 		code = code + x;
   2662 	}
   2663 	else{
   2664 		code = code + y; 
   2665 	}
   2666 	return code;
   2667 }
   2668 
   2669 int* codeToOrderedPairNat(long int code){
   2670 	int *couple = malloc(2*sizeof(int));
   2671 	int n = sqrt(code * 2);
   2672 	long int axis = (n * (n + 1))/2;
   2673 	int diff = 0;
   2674 	if(axis > code){
   2675 			n = n - 1;
   2676 			axis = (n * (n + 1))/2;
   2677 	}
   2678 	diff = code - axis;
   2679 	if(even(n)){
   2680 		couple[0] = diff;
   2681 		couple[1] = n - diff;
   2682 	}
   2683 	else{
   2684 		couple[0] = n - diff;
   2685 		couple[1] = diff;
   2686 	}
   2687 	return couple;
   2688 }
   2689 
   2690 long int orderedPairToCodeInt(int x, int y){
   2691 	long int code = 0;	
   2692 
   2693 	if (x < 0){
   2694 		x = (2 * (abs (x))) - 1;
   2695 	}
   2696 	else{
   2697 		x = 2 * x;
   2698 	}
   2699 
   2700 	if (y < 0){
   2701 		y = (2 * (abs(y))) - 1;
   2702 	}
   2703 	else{
   2704 		y = 2 * y;
   2705 	}
   2706 
   2707 	code = orderedPairToCodeNat(x, y);
   2708 	return code;
   2709 }
   2710 
   2711 int* codeToOrderedPairInt(long int code){
   2712 	int *pair = codeToOrderedPairNat(code);
   2713 
   2714 	if (even(pair[0])){
   2715 		pair[0] = pair[0] / 2;
   2716 	}
   2717 	else{
   2718 		pair[0] = (pair[0] / 2)*(-1) - 1;
   2719 	} 
   2720 	
   2721 	if (even (pair[1])){
   2722 		pair[1] = pair[1] / 2;
   2723 	}
   2724 	else{
   2725 		pair[1] = (pair[1] / 2)*(-1) - 1;
   2726 	}
   2727 
   2728 	return pair;
   2729 }
   2730 
   2731 long int orderedPairToCodeIntAlgo2(int x, int y){
   2732 	long int code = 0;
   2733 	int _x, _y, diff;
   2734 	_x = _y = diff = 0;
   2735 	int temp;
   2736 	int absmax;	
   2737 	absmax = max(abs(x), abs(y));	
   2738 	
   2739 	if(absmax == abs(x)){ // _x == x 
   2740 		_x = _y = x;
   2741 		temp = abs(x) * 2;
   2742 		if(x < 0){ // x negative
   2743 			code = temp * (temp + 1);
   2744 			if(y < 0){ // x negative, y negative
   2745 				diff = abs(_y) - abs(y);
   2746 			}
   2747 			else{ // x negative, y positive
   2748 				diff = abs(_y) + abs(y);
   2749 			}
   2750 		}
   2751 		else{ // x positive
   2752 			code = (temp - 1) * temp; 
   2753 			if(y > 0){ // x positive, y positive
   2754 				diff = abs(_y) - abs(y);
   2755 			}
   2756 			else{ // x positive, y negative
   2757 				diff = abs(_y) + abs(y);
   2758 			}
   2759 		}
   2760 		code = code - diff;
   2761 	}
   2762 	else{ // _y = y
   2763 		_x = _y = y;
   2764 		temp = abs(y) * 2;
   2765 		if(y < 0){ // y negative
   2766 			code = temp * (temp + 1);		
   2767 			if(x < 0){ // y negative, x negative
   2768 				diff = abs(_x) - abs(x);
   2769 			}
   2770 			else{ // y negative, x positive
   2771 				diff = abs(_x) + abs (x);
   2772 			}
   2773 		}
   2774 		else{ // y positive
   2775 			code = (temp - 1) * temp;
   2776 			if(x > 0){ // y positive, x positive
   2777 				diff = abs(_x) - abs(x);
   2778 			}
   2779 			else{ // y positive, x negative
   2780 				diff = abs(_x) + abs(x);
   2781 			}	
   2782 		}	
   2783 		code = code + diff;	
   2784 	}
   2785 	return code;
   2786 }
   2787 
   2788 int* codeToOrderedPairIntAlgo2(long int code){
   2789 	int* pair = malloc(2*sizeof(int));
   2790 	int isqrtcode = (int) sqrt(code);
   2791 	long int pivotcode = isqrtcode * (isqrtcode + 1);
   2792 	int x, y;
   2793 	x = y = 0;	
   2794 
   2795 	if(even(isqrtcode)){
   2796 		x = y = -(isqrtcode / 2);
   2797 		if(code > pivotcode){
   2798 			x = x + (code - pivotcode);
   2799 		}
   2800 		else{
   2801 			y = y + (pivotcode - code);
   2802 		}
   2803 	}
   2804 	else{
   2805 		x = y = (isqrtcode / 2) + 1;
   2806 		if(code > pivotcode){
   2807 			x = x - (code - pivotcode);
   2808 		}
   2809 		else{
   2810 			y = y - (pivotcode - code); 
   2811 		}
   2812 	}
   2813 	pair[0] = x;
   2814 	pair[1] = y; 
   2815 	return pair;
   2816 }
   2817 
   2818 long int orderedMultipleToCodeNat(int *arr, int size){
   2819 	long int code;	
   2820 	if(size > 1){
   2821 		code = orderedPairToCodeNat(arr[size - 2], arr[size - 1]);
   2822 		arr[size - 2] = code;
   2823 		arr = realloc(arr, (size - 1));
   2824 		if(size > 2){		
   2825 			code = orderedMultipleToCodeNat(&arr[0], (size - 1));
   2826 		}
   2827 	}
   2828 	return code;
   2829 }
   2830 
   2831 int* codeToOrderedMultipleNat(long int code, int size){
   2832 	int *multiple = malloc(size*sizeof(int));
   2833 	int *pair;
   2834 	int i = 0;
   2835 	for(i = 0; i < (size - 1); i++){
   2836 		pair = codeToOrderedPairNat(code);
   2837 		code = pair[1];
   2838 		multiple[i] = pair[0];
   2839 		multiple[i + 1] = pair[1];
   2840 	}
   2841 	return multiple;
   2842 }
   2843 
   2844 
   2845 long int orderedMultipleToCodeInt(int *arr, int size){
   2846 	long int code;	
   2847 	if(size > 1){
   2848 		code = orderedPairToCodeInt(arr[size - 2], arr[size - 1]);
   2849 		arr[size - 2] = code;
   2850 		arr = realloc(arr, (size - 1));
   2851 		if(size > 2){		
   2852 			code = orderedMultipleToCodeInt(&arr[0], (size - 1));
   2853 		}
   2854 	}
   2855 	return code;
   2856 }
   2857 
   2858 int* codeToOrderedMultipleInt(long int code, int size){
   2859 	int *multiple = malloc(size*sizeof(int));
   2860 	int *pair;
   2861 	int i = 0;
   2862 	for(i = 0; i < (size - 1); i++){
   2863 		pair = codeToOrderedPairInt(code);
   2864 		code = pair[1];
   2865 		multiple[i] = pair[0];
   2866 		multiple[i + 1] = pair[1];
   2867 	}
   2868 	return multiple;
   2869 }
   2870 
   2871 
   2872 long int orderedMultipleToCodeIntAlgo2(int *arr, int size){
   2873 	long int code = 0;	
   2874 	if(size > 1){
   2875 		code = orderedPairToCodeIntAlgo2(arr[size - 2], arr[size - 1]);
   2876 		arr[size - 2] = code;
   2877 		arr = realloc(arr, (size - 1));
   2878 		if(size > 2){		
   2879 			code = orderedMultipleToCodeIntAlgo2(&arr[0], (size - 1));
   2880 		}
   2881 	}
   2882 	return code;
   2883 }
   2884 
   2885 int* codeToOrderedMultipleIntAlgo2(long int code, int size){
   2886 	int *multiple = malloc(size*sizeof(int));
   2887 	int *pair;
   2888 	int i = 0;
   2889 	for(i = 0; i < (size - 1); i++){
   2890 		pair = codeToOrderedPairIntAlgo2(code);
   2891 		code = pair[1];
   2892 		multiple[i] = pair[0];
   2893 		multiple[i + 1] = pair[1];
   2894 	}
   2895 	return multiple;
   2896 }
   2897 
   2898 
   2899 void testMultiNat(){
   2900 	
   2901 	int x = 0;
   2902 	int y = 0;
   2903 	long int code = 0;
   2904 	int *p;
   2905 	int size = 0;
   2906 
   2907 	do{		
   2908 		printf("\n(NATURAL NUMBERS) testPairInt();Enter a size of a multidimensional array representing a 'ordered multiple': ");
   2909 		scanf("%d",&size);
   2910 		p = malloc(size * sizeof(int));
   2911 		int i;
   2912 		for(i = 0; i < size; i++){
   2913 			printf("Enter value number %d: ", i);
   2914 			scanf("%d", &p[i]);
   2915 		}
   2916 
   2917 		code = orderedMultipleToCodeNat(p, size);
   2918 		printf("\n... The code is %ld", code);
   2919 		printf ("\ncode = ");
   2920 		scanf("%ld",&code);
   2921 		printf ("\nnumber of ordered elements = ");
   2922 		scanf("%d",&size);
   2923 		p = codeToOrderedMultipleNat(code, size);
   2924 		printf("The ordered multiple identified by code %ld contains the following elements: ", code);
   2925 		printf("(");
   2926 	
   2927 		for(i = 0; i < (size - 1); i++){
   2928 			printf("%d, ", p[i]);
   2929 		}
   2930 		printf("%d)", p[size-1]);
   2931 	}
   2932 	while(1);
   2933 }
   2934 
   2935 void testPairInt(){
   2936 	
   2937 	int x = 0;
   2938 	int y = 0;
   2939 	long int code = 0;
   2940 	int *p;
   2941 
   2942 	do{		
   2943 		p = malloc(2 * sizeof(int));
   2944 		int i;
   2945 		for(i = 0; i < 2; i++){
   2946 			printf("(ORDERED PAIRS INT) Enter value number %d: ", i);
   2947 			scanf("%d", &p[i]);
   2948 		}
   2949 
   2950 		code = orderedPairToCodeInt(p[0], p[1]);
   2951 		printf("\n... The code is %ld", code);
   2952 		printf ("\ncode = ");
   2953 		scanf("%ld",&code);
   2954 		p = codeToOrderedPairInt(code);
   2955 		printf("The ordered pair identified by code %ld contains the following elements: ", code);
   2956 		printf("(");
   2957 	
   2958 		for(i = 0; i < 1; i++){
   2959 			printf("%d, ", p[i]);
   2960 		}
   2961 		printf("%d)\n", p[1]);
   2962 	}
   2963 	while(1);
   2964 }
   2965 
   2966 void testMultiInt(){
   2967 	
   2968 	int x = 0;
   2969 	int y = 0;
   2970 	long int code = 0;
   2971 	int *p;
   2972 	int size = 0;
   2973 
   2974 	do{		
   2975 		printf("\n(INTEGERS) Enter a size of a multidimensional array representing a 'ordered multiple': ");
   2976 		scanf("%d",&size);
   2977 		p = malloc(size * sizeof(int));
   2978 		int i;
   2979 		for(i = 0; i < size; i++){
   2980 			printf("Enter value number %d: ", i);
   2981 			scanf("%d", &p[i]);
   2982 		}
   2983 
   2984 		code = orderedMultipleToCodeInt(p, size);
   2985 		printf("\n... The code is %ld", code);
   2986 		printf ("\ncode = ");
   2987 		scanf("%ld",&code);
   2988 		printf ("\nnumber of ordered elements = ");
   2989 		scanf("%d",&size);
   2990 		p = codeToOrderedMultipleInt(code, size);
   2991 		printf("The ordered multiple identified by code %ld contains the following elements: ", code);
   2992 		printf("(");
   2993 	
   2994 		for(i = 0; i < (size - 1); i++){
   2995 			printf("%d, ", p[i]);
   2996 		}
   2997 		printf("%d)", p[size-1]);
   2998 	}
   2999 	while(1);
   3000 }
   3001 
   3002 void testPairIntAlgo2(){
   3003 	
   3004 	int x = 0;
   3005 	int y = 0;
   3006 	long int code = 0;
   3007 	int *p;
   3008 
   3009 	do{		
   3010 		p = malloc(2 * sizeof(int));
   3011 		int i;
   3012 		
   3013 		for(i = 0; i < 2; i++){
   3014 			printf("(ORDERED PAIRS INT) Enter value number %d: ", i);
   3015 			scanf("%d", &p[i]);
   3016 		}
   3017 
   3018 		code = orderedPairToCodeIntAlgo2(p[0], p[1]);
   3019 		printf("\n... The code is %ld", code);	
   3020 
   3021 		printf ("\ncode = ");
   3022 		scanf("%ld",&code);
   3023 		p = codeToOrderedPairIntAlgo2(code);
   3024 		printf("The ordered pair identified by code %ld contains the following elements: ", code);
   3025 		printf("(");
   3026 	
   3027 		for(i = 0; i < 1; i++){
   3028 			printf("%d, ", p[i]);
   3029 		}
   3030 		printf("%d)\n", p[1]);
   3031 	}
   3032 	while(1);
   3033 }
   3034 
   3035 
   3036 void testMultiIntAlgo2(){
   3037 	
   3038 	int x = 0;
   3039 	int y = 0;
   3040 	long int code = 0;
   3041 	int *p;
   3042 	int size = 0;
   3043 
   3044 	do{		
   3045 		printf("\n(INTEGERS) Enter a size of a multidimensional array representing a 'ordered multiple': ");
   3046 		scanf("%d",&size);
   3047 		p = malloc(size * sizeof(int));
   3048 		int i;
   3049 		for(i = 0; i < size; i++){
   3050 			printf("Enter value number %d: ", i);
   3051 			scanf("%d", &p[i]);
   3052 		}
   3053 
   3054 		code = orderedMultipleToCodeIntAlgo2(p, size);
   3055 		printf("\n... The code is %ld", code);
   3056 		printf ("\ncode = ");
   3057 		scanf("%ld",&code);
   3058 		printf ("\nnumber of ordered elements = ");
   3059 		scanf("%d",&size);
   3060 		p = codeToOrderedMultipleIntAlgo2(code, size);
   3061 		printf("The ordered multiple identified by code %ld contains the following elements: ", code);
   3062 		printf("(");
   3063 	
   3064 		for(i = 0; i < (size - 1); i++){
   3065 			printf("%d, ", p[i]);
   3066 		}
   3067 		printf("%d)", p[size-1]);
   3068 	}
   3069 	while(1);
   3070 }
   3071 
   3072 
   3073 
   3074 
   3075 int main(int argc, char **argv, char **envp){
   3076 	// testMultiNat();
   3077 	// testPairInt();
   3078 	// testMultiInt();
   3079 	// testPairIntAlgo2();
   3080 	 testMultiIntAlgo2();
   3081 }
   3082 
   3083 
   3084 //END COUPLES.C
   3085 
   3086 \end{lstlisting}
   3087 
   3088 \subsection{couple\_entiers.c}
   3089 \label{coupleentiersc}
   3090 \begin{lstlisting}[language=C, basicstyle=\footnotesize]
   3091 
   3092 
   3093 //COUPLES_ENTIERS.C
   3094 
   3095 #include <stdio.h>
   3096 #include <stdlib.h>
   3097 #include <math.h>
   3098 
   3099 int pair(int x){
   3100 	return (!(x % 2));
   3101 }
   3102 
   3103 int orderedPairToCode(int x, int y){
   3104 	int sumxy, code;
   3105 	sumxy = x + y;
   3106 	code = ((sumxy)*(sumxy + 1))/2;
   3107 
   3108 	if(pair(sumxy)){
   3109 		code = code + x;
   3110 	}
   3111 	else{
   3112 		code = code + y; 
   3113 	}
   3114 	return code;
   3115 }
   3116 
   3117 
   3118 int* codeToOrderedPair(int code){
   3119 	int *couple = malloc(2*sizeof(int));
   3120 	int n = sqrt(code * 2);
   3121 	int axis = (n * (n + 1))/2;
   3122 	int diff = 0;
   3123 	if(axis > code){
   3124 		while(axis > code){
   3125 			n = n - 1;
   3126 			axis = (n * (n + 1))/2;
   3127 		}
   3128 	}
   3129 	else if(axis < code){
   3130 		while(axis < code){
   3131 			n = n + 1;
   3132 			axis = (n * (n + 1))/2;
   3133 		}
   3134 		if(axis > code){
   3135 			n = n - 1;
   3136 			axis = (n * (n + 1))/2;
   3137 		}
   3138 	}
   3139 
   3140 	if(axis == code){ // je pense que je peux me dispenser de cet "if", ca revient au meme car diff serait = 0
   3141 		if(pair(n)){
   3142 			couple[0] = 0;
   3143 			couple[1] = n;
   3144 		}
   3145 		else{
   3146 			couple[0] = n;
   3147 			couple[1] = 0;
   3148 		}
   3149 	}
   3150 	if(axis != code){ // idem
   3151 		diff = code - axis;
   3152 		if(pair(n)){
   3153 			couple[0] = diff;
   3154 			couple[1] = n - diff;
   3155 		}
   3156 		else{
   3157 			couple[0] = n - diff;
   3158 			couple[1] = diff;
   3159 		}
   3160 	}
   3161 	return couple;
   3162 }
   3163 
   3164 int	orderedMultipleToCode(int *arr, int size){
   3165 	int code;	
   3166 	if(size > 1){
   3167 		code = orderedPairToCode(arr[size - 2], arr[size - 1]);
   3168 		arr[size - 2] = code;
   3169 		arr = realloc(arr, (size - 1));
   3170 		if(size > 2){		
   3171 			code = orderedMultipleToCode(&arr[0], (size - 1));
   3172 		}
   3173 	}
   3174 	return code;
   3175 }
   3176 
   3177 int* codeToOrderedMultiple(int code, int size){
   3178 	int *multiple = malloc(size*sizeof(int));
   3179 	int *pair;
   3180 	int i = 0;
   3181 	for(i = 0; i < (size - 1); i++){
   3182 		pair = codeToOrderedPair(code);
   3183 		code = pair[1];
   3184 		multiple[i] = pair[0];
   3185 		multiple[i + 1] = pair[1];
   3186 	}
   3187 	return multiple;
   3188 }
   3189 
   3190 
   3191 int main(int argc, char **argv, char **envp){
   3192 
   3193 	int x = 0;
   3194 	int y = 0;
   3195 	int code = 0;
   3196 	int *p;
   3197 	int size = 0;
   3198 
   3199 	do{
   3200 	/*
   3201 		printf ("\nx = ");
   3202 		scanf("%d",&x);
   3203 		printf ("y = ");
   3204 		scanf("%d",&y);
   3205 		code = orderedPairToCode(x, y);
   3206 		printf("Le code du couple (%d, %d) est %d\n", x, y, code);
   3207 
   3208 		printf ("\ncode = ");
   3209 		scanf("%d",&code);
   3210 		p = codeToOrderedPair(code);
   3211 		printf("The ordered pair identified by code %d is (%d, %d)", code, p[0], p[1]);
   3212 	
   3213 */			
   3214 		printf("\nEnter a size of a multidimensional array representing a 'ordered multiple': ");
   3215 		scanf("%d",&size);
   3216 		p = malloc(size * sizeof(int));
   3217 		int i;
   3218 		for(i = 0; i < size; i++){
   3219 			printf("Enter value number %d: ", i);
   3220 			scanf("%d", &p[i]);
   3221 		}
   3222 
   3223 		code = orderedMultipleToCode(p, size);
   3224 		printf("\n... The code is %d", code);
   3225 	
   3226 
   3227 
   3228 		printf ("\ncode = ");
   3229 		scanf("%d",&code);
   3230 		printf ("\nnumber of ordered elements = ");
   3231 		scanf("%d",&size);
   3232 		p = codeToOrderedMultiple(code, size);
   3233 		printf("The ordered multiple identified by code %d contains the following elements: ", code);
   3234 		printf("(");
   3235 		for(i = 0; i < (size - 1); i++){
   3236 			printf("%d, ", p[i]);
   3237 		}
   3238 		printf("%d)", p[size-1]);
   3239 
   3240 
   3241 	}
   3242 	while(code != -1);
   3243 }
   3244 
   3245 //END COUPLES_ENTIERS.C
   3246 \end{lstlisting}
   3247 \newpage
   3248 \section{Annexe~: Exercice 5}
   3249 \label{annexeexo5}
   3250 \includepdf[pages=-]{exo5}
   3251 
   3252 \end{document}