2.3 Problème de chaînes ternaires
Combien y a-t-il de chaînes ternaire de longueur pour lesquels aucun n’est adjacent (avant ou après) à un ? Ici, la méthode que nous avons utilisé pour l’exemple précédent n’est pas d’une grande utilité. L’astuce est d’utiliser des variables intermédiaires. On commence par dénoter par le nombre de chaînes ternaires de longueurs qui n’ont pas de et adjacents (i.e. les chaînes valides). On divise ensuite les solutions en différents cas:
| Les chaînes valides de longueur qui se termine par un | ||
| Les chaînes valides de longueur qui se termine par un | ||
| Les chaînes valides de longueur qui se termine par un |
Maintenant, remarquons que pour toutes les chaînes valides qui se termine par un , on peut toujours ajouter soit un ou un . De plus, pour les chaînes valides qui se termine par un , on peut ajouter un ou un . Finalement, pour les chaînes valides se terminant par un , on peut ajouter soit un , ou . Ceci peut être représenter par l’automate ci-dessous:
À partir de ceci, on peut obtenir les systèmes de récurrences suivants:
Auquel nous devons ajouter les valeurs initiales . Il est relativement facile à partir de ces équations de calculer et , puis les additionner pour obtenir la solution de notre problème. À nouveau, ceci peut être facilement accompli à l’aide de Python.
1 from sympy import *2 from pandas import *3 init_printing()45 def a(n):6 if n == 1:7 return 18 else:9 return a(n-1) + c(n-1)1011 def b(n):12 if n == 1:13 return 114 else:15 return b(n-1) + c(n-1)1617 def c(n):18 if n == 1:19 return 120 else:21 return a(n-1) + b(n-1) + c(n-1)2223 tableau = DataFrame({24 "a_n": [a(n) for n in range(1,11)],25 "b_n": [b(n) for n in range(1,11)],26 "c_n": [c(n) for n in range(1,11)],27 "Somme": [a(n) + b(n) + c(n) for n in range(1,11)]28 })29 tableau.index = [n for n in range(1,11)]30 tableau
Ce qui nous permet d’obtenir le tableau suivant:
| Somme | ||||
| 1 | 1 | 1 | 1 | 3 |
| 2 | 2 | 2 | 3 | 7 |
| 3 | 5 | 5 | 7 | 17 |
| 4 | 12 | 12 | 17 | 41 |
| 5 | 29 | 29 | 41 | 99 |
| 6 | 70 | 70 | 99 | 239 |
| 7 | 169 | 169 | 239 | 577 |
| 8 | 408 | 408 | 577 | 1393 |
| 9 | 985 | 985 | 1393 | 3363 |
| 10 | 2378 | 2378 | 3363 | 8119 |
Il y a donc un total de chaînes ternaires de longueur pour lesquels aucun n’est adjacent à un . Comme pour l’exemple des chaînes binaires, il nous est aussi possible de ramener notre système de récurrence en une seule récurrence.
Cette dernière récurrence étant valide pour tout . Il nous faut cependant deux valeurs initiales. On a donc et . La récurrence décrivant notre problème est donc:
À partir de cette dernière, il devient relativement simple d’utiliser Python pour construire un tableau avec les différentes valeurs de .
1 from sympy import *2 from pandas import *3 init_printing()45 def x(n):6 if n == 1:7 return 38 if n == 2:9 return 710 else:11 return 2*x(n-1) + x(n-2)1213 tableau = DataFrame([[x(n) for n in range(1,11)]])14 tableau.columns = [n for n in range(1,11)]15 tableau.index = ["valeurs"]16 tableau
Ce qui nous donne le tableau suivant:
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
| 3 | 7 | 17 | 41 | 99 | 239 | 577 | 1393 | 3363 | 8119 |
Nous obtenons donc à nouveau qu’il y a chaînes ternaires de longueur qui n’ont pas de et adjacents.
L’algèbre linéaire nous donne une autre approche pour résoudre le problème. En effet, le système d’équations de récurrence peut être réécrit sous la forme matricielle suivante:
Pour trouver la solution de notre problème, on a donc:
La solution du problème est donc chaînes ternaires. Remarquez qu’ici pour calculer facilement l’exposant de la matrice, il est à nouveau nécessaire d’utiliser un logiciel tel que Python.
1 from sympy import *2 init_printing()34 A = Matrix([[1,0,1],[0,1,1],[1,1,1]])5 b = Matrix([1,1,1])6 Reponse = A**9 * b7 Reponse.norm(1)
À la place d’utiliser Python, il aurait aussi été possible d’effectuer la diagonalisation de la matrice à l’aide des valeurs propres et des vecteurs propres pour évaluer la puissance de la matrice.