Complexité de l'espace pour calculer l'alignement optimal des chaînes pour la distance d'édition de Levenshtein

12

Si on nous donne deux chaînes de taille et , le calcul standard de la distance d'édition de Levenshtein se fait par un algorithme dynamique avec la complexité temporelle et la complexité spatiale . (Certaines améliorations peuvent être apportées en fonction de la distance de montage , mais nous ne supposons pas que soit particulièrement petit.) Si vous êtes uniquement intéressé par la valeur de la distance de montage (c'est-à-dire le nombre minimal de modifications), Une amélioration bien connue de l'algorithme habituel (où vous ne conservez que la ligne précédente et actuelle de la table d'alignement) réduit la complexité de l'espace à .n1n2O(n1n2)O(n1n2)ddO(max(n1,n2))

Cependant, si vous souhaitez obtenir les modifications réelles d'un script d'édition optimal, est-il possible de faire mieux que l' utilisation de la mémoire O(n1n2) , probablement au détriment du temps d'exécution?

a3nm
la source

Réponses:

15

Il n'est pas nécessaire de faire le compromis suggéré par Yuval. L'ensemble de la séquence d'édition optimale peut être calculé dans le temps et l' espace , en utilisant un mélange de programmation dynamique et de division et de conquête décrit pour la première fois par Dan Hirschberg. ( Un algorithme d'espace linéaire pour calculer des sous-séquences communes maximales. Commun. ACM 18 (6): 341–343, 1975.)O(nm)O(n+m)

Intuitivement, l'idée de Hirschberg est de calculer une seule opération d'édition à mi-chemin de la séquence d'édition optimale, puis de calculer récursivement les deux moitiés de la séquence. Si nous considérons la séquence d'édition optimale comme un chemin d'un coin de la table de mémorisation à l'autre, nous avons besoin d'une récurrence modifiée pour enregistrer où ce chemin traverse la ligne du milieu de la table. Une récurrence qui fonctionne est la suivante:

Half(i,j)={if i<m/2jif i=m/2Half(i1,j)if i>m/2 and Edit(i,j)=Edit(i1,j)+1Half(i,j1)if i>m/2 and Edit(i,j)=Edit(i,j1)+1Half(i1,j1)otherwise

Les valeurs de peuvent être calculées en même temps que le tableau de distance d'édition , en utilisant le temps . Étant donné que chaque ligne de la table de mémorisation dépend uniquement de la ligne au-dessus, le calcul à la fois de et de ne nécessite qu'un espace .Half(i,j)Edit(i,j)O(mn)Edit(m,n)Half(m,n)O(m+n)

entrez la description de l'image ici

Enfin, la séquence d'édition optimale transformant les chaînes d'entrée en est constituée des séquences optimales transformant en suivi de la séquence optimale transformant en . Si nous calculons ces deux sous-séquences de manière récursive, le temps d'exécution global obéit à la récurrence suivante: Il n'est pas difficile de prouver queA[1..m]B[1..n]A[1..m/2]B[1..Half(m,n)]A[m/2+1..m]B[Half(m,n)+1..n]

T(m,n)={O(n)if m1O(m)if n1O(mn)+maxh(T(m/2,h)+T(m/2,nh))otherwise
T(m,n)=O(mn). De même, comme nous n'avons besoin d'espace que pour une seule passe de programmation dynamique à la fois, l'espace total lié est toujours . (L'espace pour la pile de récursivité est négligeable.)O(m+n)
Jeffε
la source
5
Parce que j'ai raté ça quand Dan m'a demandé à mon examen de qualification, c'est pourquoi.
Jeffε
Je me souviens avoir eu cela comme un exercice (guidé) et avoir pensé que c'était plutôt cool
Sasho Nikolov
3

L'algorithme que vous décrivez, qui s'exécute dans l'espace récupère en fait le montage final et l'état juste avant le montage final. Donc, si vous exécutez cet algorithme fois, vous pouvez récupérer l'intégralité de la séquence d'édition, au détriment de l'augmentation de l'exécution. En général, il existe un compromis espace-temps qui est contrôlé par le nombre de lignes que vous conservez à ce moment-là. Les deux points extrêmes de ce compromis sont l'espace et l'espace , et entre ceux-ci, le produit du temps et de l'espace est constant (jusqu'à un grand O).O(n1+n2)O(n1+n2)O(n1n2)O(n1+n2)

Yuval Filmus
la source