2.2 Problème de chaines binaires

Combien y a-t-il de chaines binaires de longueur 10\displaystyle 10 ne contenant pas deux 0\displaystyle 0 consécutifs? Pour ce faire, nous pourrions bien évidement énumérer toutes les possibilités, mais à première vu il semble y en avoir beaucoup. Nous allons donc plutôt prendre l’approche de définir une relation de récurrence. Posons an\displaystyle a_{n} le nombre de chaine binaire de longueur n\displaystyle n ne contenant pas deux 0\displaystyle 0 consécutif. Il est facile de voir que a1=2\displaystyle a_{1}=2 et a2=3\displaystyle a_{2}=3. Maintenant, remarquons qu’une chaine binaire de longueur n\displaystyle n avec n2\displaystyle n\geq 2 doit soit se terminer par un 0\displaystyle 0 ou bien par un 1\displaystyle 1. Pour toutes les chaines de longueur n1\displaystyle n-1, il est toujours possible d’ajouter un 1\displaystyle 1 à la fin pour obtenir une chaine binaire de longueur n\displaystyle n satisfaisant le problème, par contre ceci n’est pas possible avec 0\displaystyle 0 car on risquerait d’obtenir une chaine qui se termine par 00\displaystyle 00. Donc si une chaine binaire de longueur n\displaystyle n ne contient pas pas deux 0\displaystyle 0 consécutif et se termine par 0\displaystyle 0, alors elle doit obligatoirement se terminer par 10\displaystyle 10. On remarque alors qu’il que ceci correspond en fait au nombre de chaine de longueur n2\displaystyle n-2 qui satisfait le problème. Ceci peut-être visualisé sous forme du diagramme suivant:

À partir de ces informations, on obtient donc la récurrence suivante:

{an=an1+an2,n3a1=2a2=3\displaystyle\left\{\begin{array}[]{l}a_{n}=a_{n-1}+a_{n-2},\leavevmode% \nobreak\ \leavevmode\nobreak\ \leavevmode\nobreak\ \forall n\geq 3\\ a_{1}=2\\ a_{2}=3\end{array}\right.

À partir de la récurrence, il devient maintenant beaucoup plus simple de répondre à la question. Il est possible de la résoudre pour obtenir une formule explicite, mais dans le cas présent, comme nous cherchons uniquement la 10e\displaystyle 10e valeur, on peut utiliser le code suivant:

Listing 1: Valeur unique pour le problème des chaînes binaires

              1
              
              
              
            from sympy import *


              2
              
              
              
            from pandas import *


              3
              
              
              
            init_printing()


              4
              
              
              
            


              5
              
              
              
            def a(n):


              6
              
              
              
                if n == 1:


              7
              
              
              
                    return 2


              8
              
              
              
                if n == 2:


              9
              
              
              
                    return 3


              10
              
              
              
                else:


              11
              
              
              
                    return a(n-1) + a(n-2)


              12
              
              
              
            


              13
              
              
              
            a(10)

qui nous permet d’obtenir directement la valeur de a10=144\displaystyle a_{10}=144. Remarquons cependant que dans la plupart des cas, il est plus intéressant de faire un tableau de valeurs complet. Ceci peut bien entendu être obtenu à la main, mais aussi automatiquement à l’aide de Python en utilisant plutôt le code suivant:

Listing 2: Tableau pour le problème des chaînes binaires

              1
              
              
              
            from sympy import *


              2
              
              
              
            from pandas import *


              3
              
              
              
            init_printing()


              4
              
              
              
            


              5
              
              
              
            def a(n):


              6
              
              
              
                if n == 1:


              7
              
              
              
                    return 2


              8
              
              
              
                if n == 2:


              9
              
              
              
                    return 3


              10
              
              
              
                else:


              11
              
              
              
                    return a(n-1) + a(n-2)


              12
              
              
              
            


              13
              
              
              
            tableau = DataFrame([[a(n) for n in range(1,11)]])


              14
              
              
              
            tableau.columns = [n for n in range(1,11)]


              15
              
              
              
            tableau.index = ["Valeurs"]


              16
              
              
              
            tableau

Ce dernier code nous permet alors d’obtenir le tableau suivant:

n\displaystyle n 1 2 3 4 5 6 7 8 9 10
an\displaystyle a_{n} 2 3 5 8 13 21 34 55 89 144

À nouveau, on obtient que le nombre de chaînes binaires de longueur 10\displaystyle 10 qui ne contient pas deux 0\displaystyle 0 consécutifs est 144\displaystyle 144. Alternativement, on peut aussi répondre à cette question à partir d’un système d’équations définie par récurrence. Ceci peut-être accompli à partir de variable intermédiaire et d’un automate. Nous allons donc définir les variables suivantes:

xn\displaystyle x_{n} =\displaystyle= Les chaînes binaires de longueur n\displaystyle n qui ne contiennent pas deux 0\displaystyle 0 consécutif et qui se termine par un 0\displaystyle 0
yn\displaystyle y_{n} =\displaystyle= Les chaînes binaires de longueur n\displaystyle n qui ne contiennent pas deux 0\displaystyle 0 consécutif et qui se termine par un 1\displaystyle 1

D’après la définition, nous savons que si le dernier chiffre est un 1\displaystyle 1, on peut toujours ajouter un 0\displaystyle 0 ou un 1\displaystyle 1. Par contre, si le dernier chiffre est un 0\displaystyle 0, alors on peut uniquement ajouter un 1\displaystyle 1. Ceci nous donne donc l’automate suivant:

0\displaystyle 01\displaystyle 1

Ceci nous donne le système suivant:

{xn=yn1yn=xn1+yn1,n1\displaystyle\left\{\begin{array}[]{l}x_{n}=y_{n-1}\\ y_{n}=x_{n-1}+y_{n-1}\end{array}\right.,\leavevmode\nobreak\ \leavevmode% \nobreak\ \leavevmode\nobreak\ \forall n\geq 1

Avec les valeurs initiales x1=y1=1\displaystyle x_{1}=y_{1}=1. À nouveau, Python peut nous permettre de compléter directement un tableau avec les différentes valeurs.

Listing 3: Problème des chaînes binaires à l’aide d’un système de récurrences

              1
              
              
              
            from sympy import *


              2
              
              
              
            from pandas import *


              3
              
              
              
            init_printing()


              4
              
              
              
            


              5
              
              
              
            def x(n):


              6
              
              
              
                if n == 1:


              7
              
              
              
                    return 1


              8
              
              
              
                else:


              9
              
              
              
                    return y(n-1)


              10
              
              
              
            


              11
              
              
              
            def y(n):


              12
              
              
              
                if n == 1:


              13
              
              
              
                    return 1


              14
              
              
              
                else:


              15
              
              
              
                    return x(n-1) + y(n-1)


              16
              
              
              
            


              17
              
              
              
            tableau = DataFrame({


              18
              
              
              
                "x_n": [x(n) for n in range(1,11)],


              19
              
              
              
                "y_n": [y(n) for n in range(1,11)],


              20
              
              
              
                "Somme": [x(n) + y(n) for n in range(1,11)]


              21
              
              
              
            })


              22
              
              
              
            tableau.index = [n for n in range(1,11)]


              23
              
              
              
            tableau

Ce qui nous permet cette fois d’obtenir le tableau suivant. Notez que ce tableau, en plus de nous donner le nombre de chaînes qui ne contiennent pas deux 0\displaystyle 0 consécutifs, les séparent en nombre de ces chaînes qui se terminent par un 0\displaystyle 0 et en chaînes qui se terminent par un 1\displaystyle 1.

n\displaystyle n xn\displaystyle x_{n} yn\displaystyle y_{n} Somme
1 1 1 2
2 1 2 3
3 2 3 5
4 3 5 8
5 5 8 13
6 8 13 21
7 13 21 34
8 21 34 55
9 34 55 89
10 55 89 144

Bien qu’il soit possible de travailler directement avec ce système, dans le cas présent il est aussi facile de le simplifier pour obtenir la récurrence que nous avions déjà obtenu. Comme nous sommes intéressé par les chaînes qui se termine par 0\displaystyle 0 et celle qui se termine 1\displaystyle 1, la solution du problème est donné par la récurrence suivante:

an=xn+yn=yn1+xn1+yn1=an1+yn1=an1+xn2+yn2=an1+an2\displaystyle a_{n}=x_{n}+y_{n}=y_{n-1}+x_{n-1}+y_{n-1}=a_{n-1}+y_{n-1}=a_{n-1% }+x_{n-2}+y_{n-2}=a_{n-1}+a_{n-2}

On remarque immédiatement qu’il s’agit de la même récurrence que nous avions obtenu précédemment.