Aller au contenu

Le problème de l'alignement de séquences consiste, dans la version qui nous intéresse ici, à rechercher la plus longue sous-chaîne commune.

C'est un problème utile en génétique, aussi notre alphabet sera composé des lettres : {A; C; T; G} qui représentera les bases nucléiques : Adénine, Cytosine, Thymine et Guanine qui composent l'ADN.

Nous avons deux mots :

mot_1 = "𝐴𝑇𝐴𝑇𝐴𝐶𝐴𝐺𝐺𝑇𝐶𝐴"
mot_2 = "𝐺𝐴𝐶𝑇𝐴𝐶𝐴𝐶𝐺𝐴𝐶𝑇"

Dans ce cas, il existe différentes sous_chaînes de longueur maximale, par exempple, nous avons la chaîne de longueur 7 "𝐴𝑇𝐴𝐶𝐴𝐶𝐴" :

image

On notera par la suite plscc(mot_1, mot_2) l'ensemble des plus longues sous-chaînes de mot_1 et mot_2. Et longueur_plscc(mot_1, mot_2) la longueur des plus longues sous-chaînes de mot_1 et mot_2.

Résolution du problème

On s'intéressera dans un premier temps au problème qui consiste à déterminer la longueur de la plus longue sous-chaîne commune.

Avant de résoudre ce problème en utilisant Python, il faut définir un ou plusieurs sous-problèmes qui nous permettront de résoudre le problème global (qui consiste à déterminer la longueur de la sous-chaîne la plus longue). C'est la partie la plus difficile.

On peut distinguer deux cas :

  • Cas 1, Les deux mots ont la même dernière lettre A
    mot_1 = mot1gaucheA et mot_2 = mot2gaucheA. Alors, on va prendre la taille de la sous chaîne commune de mot1gauche et mot2gauche à laquelle on va ajouter 1 : longueur_plscc(mot_1, mot_2) = longueur_plscc(mot1gauche, mot2gauche) + 1
  • Cas 2, Les deux mots n'ont pas la même dernière lettre : mot1 = mot1gaucheA et mot_2 = mot2gaucheB. On ne peut pas aligner la lettre A et la lettre B et on doit alors chercher la plus longue sous-chaîne commune entre plscc(mot_1, mot2gauche) et )plscc(mot_2, mot1gauche)) car on pourrait trouver un A dans mot2gauche ou un B dans mot1gauche.

Dit autrement, cela revient à longueur_plscc(mot_1, mot_2) = max(longueur_plscc(mot_1, mot2gauche), longueur_plscc(mot_2, mot1gauche))

Programmation

Calcul de la longueur d’une plus longue sous-chaîne commune

On va construire une matrice longueur, telle que longueur[i][j] représente la longueur de la plus longue sous chaîne commune entre mot_1[:i] et mot_2[:j] (indices i et j inclus).

Il faut faire attention à l’initialisation de cette matrice, c’est-à-dire aux valeurs à donner à longueur[i][0] (ou bien, de la même façon, à longueur[0][j]). En effet, on ne peut pas, quand 𝑖 (ou 𝑗) vaut 0, utiliser l’indice 𝑖 − 1 (ou 𝑗 − 1) car une des chaînes est de longeur nulle. Dans notre cas les indices i à 0 et les indices j à 0 vont représenter le fait qu'une des sous chaînes est vide.

On aura donc une ligne et une colonne en plus qui ne contiendra que des zéros.

  • Compléter la fonction récursive def rec_longueur_plscc(mot_1, mot_2) qui calcule l’ensemble des valeurs de la matrice longueur.

def rec_longueur_plscc(mot_1, mot_2):
    if len(mot_1) == 0 or len(mot_2) == 0:
        return COMPLETER
    elif mot_1[-1] == mot_2[-1]:
        return COMPLETER
    else:
        return COMPLETER
- Compléter la fonction itérative (non récursive) def longueur_plscc(mot_1, mot_2) qui calcule l’ensemble des valeurs de la matrice longueur.

def longueur_plscc(mot_1, mot_2):
    longeur_max = [ [0 for lettre in range(len(mot_1) + 1)] for lettre in range(len(mot_2) + 1)]
    for i in range(len(mot_1) + 1):
        for j in range(len(mot_2) + 1):
            if i == 0 or j == 0:
                COMPLETER
            elif mot_1[i-1] == mot_2[j-1]:
                COMPLETER
            else:
                COMPLETER
    return COMPLETER
  • Tester vos fonctions sur l’exemple précédent ainsi que sur d’autres exemples pertinents. On gardera trace de ces tests dans le programme.