Distanța Levenshtein ( distanța de editare , distanța de editare ) este o măsurătoare care măsoară diferența absolută dintre două secvențe de caractere. Este definită ca numărul minim de operații cu un singur caracter (și anume inserții, ștergeri, înlocuiri) necesare pentru a transforma o secvență de caractere în alta. În general, operațiunilor utilizate în această transformare li se pot atribui prețuri diferite. Utilizat pe scară largă în teoria informației și lingvistica computațională .
Problema a fost pusă pentru prima dată în 1965 de matematicianul sovietic Vladimir Levenshtein când studia secvențele [1] , mai târziu o problemă mai generală pentru un alfabet arbitrar a fost asociată cu numele său. O mare contribuție la studiul problemei a adus-o Dan Gasfield [2] .
Distanța Levenshtein și generalizările sale sunt utilizate în mod activ:
Din punct de vedere al aplicațiilor, definirea distanței dintre cuvinte sau câmpuri de text conform Levenshtein are următoarele dezavantaje:
O instrucțiune editorială este o succesiune de acțiuni necesare pentru a obține a doua din prima linie în cel mai scurt mod posibil. De obicei, acțiunile sunt notate astfel: D ( eng. delete ) - delete, I (eng. insert) - insert, R ( replace ) - replace, M ( potrivire ) - potrivire.
De exemplu, pentru 2 șiruri „CONNECT” și „CONEHEAD” puteți construi următorul tabel de conversie:
M | M | M | R | eu | M | R | R |
---|---|---|---|---|---|---|---|
C | O | N | N | E | C | T | |
C | O | N | E | H | E | A | D |
Găsirea doar a distanței Levenshtein este o sarcină mai ușoară decât găsirea rețetei editoriale (vezi mai jos pentru mai multe detalii).
Prețurile operațiunii pot depinde de tipul operațiunii (inserați, ștergeți, înlocuiți) și/sau de caracterele implicate în aceasta, reflectând probabilitatea diferită a mutațiilor în biologie [3] , probabilitatea diferită a diferitelor erori la introducerea textului etc. cazul general:
Este necesar să se găsească o succesiune de substituții care să minimizeze costul total. Distanța Levenshtein este un caz special al acestei probleme pentru
Atât un caz special, cât și o problemă pentru w arbitrar sunt rezolvate de algoritmul Wagner-Fisher prezentat mai jos. Aici și mai jos, presupunem că toți w sunt nenegativi, iar inegalitatea triunghiului se aplică : înlocuirea a două operații consecutive cu una nu crește costul total (de exemplu, înlocuirea simbolului x cu y și apoi y cu z este nu) mai bine decât imediat x cu z).
Dacă adăugăm o transpunere la lista de operațiuni permise (două caractere adiacente sunt schimbate), obținem distanța Damerau-Levenshtein . Are, de asemenea, un algoritm care necesită operații O(MN). Damerau a arătat că 80% dintre erorile de tastare umane sunt transpoziții. În plus, distanța Damerau-Levenshtein este folosită și în bioinformatică.
Aici și mai jos, se presupune că elementele șirurilor sunt numerotate de la primul, așa cum este obișnuit în matematică, și nu de la zero, așa cum este obișnuit în multe limbaje de programare.
Fie și două șiruri (de lungime și respectiv) peste un alfabet , apoi distanța de editare (distanța Levenshtein) poate fi calculată folosind următoarea formulă recursivă
, Unde
,
unde este zero dacă și unul în caz contrar; returnează cel mai mic dintre argumente.
Aici pasul pe simbolizează ștergerea (D) din prima linie, pe - inserarea (I) în prima linie, iar pasul pe ambii indici simbolizează înlocuirea caracterului (R) sau absența modificărilor (M) .
Evident, următoarele afirmații sunt adevărate:
P | O | L | Y | N | O | M | eu | A | L | ||
---|---|---|---|---|---|---|---|---|---|---|---|
0 | unu | 2 | 3 | patru | 5 | 6 | 7 | opt | 9 | zece | |
E | unu | unu | 2 | 3 | patru | 5 | 6 | 7 | opt | 9 | zece |
X | 2 | 2 | 2 | 3 | patru | 5 | 6 | 7 | opt | 9 | zece |
P | 3 | 2 | 3 | 3 | patru | 5 | 6 | 7 | opt | 9 | zece |
O | patru | 3 | 2 | 3 | patru | 5 | 5 | 6 | 7 | opt | 9 |
N | 5 | patru | 3 | 3 | patru | patru | 5 | 6 | 7 | opt | 9 |
E | 6 | 5 | patru | patru | patru | 5 | 5 | 6 | 7 | opt | 9 |
N | 7 | 6 | 5 | 5 | 5 | patru | 5 | 6 | 7 | opt | 9 |
T | opt | 7 | 6 | 6 | 6 | 5 | 5 | 6 | 7 | opt | 9 |
eu | 9 | opt | 7 | 7 | 7 | 6 | 6 | 6 | 6 | 7 | opt |
A | zece | 9 | opt | opt | opt | 7 | 7 | 7 | 7 | 6 | 7 |
L | unsprezece | zece | 9 | opt | 9 | opt | opt | opt | opt | 7 | 6 |
Să luăm în considerare formula mai detaliat. Evident, distanța de editare dintre două linii goale este zero. De asemenea, este evident că pentru a obține un șir gol dintr-un șir de lungime , trebuie să efectuați operații de ștergere, iar pentru a obține un șir de lungime dintr-un șir gol, trebuie să efectuați operații de inserare.
Rămâne de luat în considerare cazul non-trivial când ambele șiruri sunt nevide.
Pentru început, observăm că în secvența optimă de operații ele pot fi interschimbate în mod arbitrar. Într-adevăr, luați în considerare două operații secvențiale:
Lasă-l să se termine cu caracterul „a”, se termină cu caracterul „b”. Există trei opțiuni:
Pentru a găsi cea mai scurtă distanță, trebuie să calculați matricea D folosind formula de mai sus . Poate fi calculat atât pe rânduri, cât și pe coloane. Pseudocod algoritm:
pentru toate i de la 0 la M pentru toate j de la 0 la N calculați D(i, j) întoarce D(M, N)Sau într-o formă mai detaliată și cu prețuri arbitrare pentru înlocuiri, inserări și ștergeri:
D(0, 0) = 0 pentru toate j de la 1 la N D(0, j) = D(0, j - 1) + costul de inserare simbol S2[j] pentru toate i de la 1 la M D(i, 0) = D(i - 1, 0) + costul ștergerii simbolului S1[i] pentru toate j de la 1 la N D(i, j) = min{ D(i - 1, j) + costul ștergerii simbolului S1[i], D(i, j - 1) + costul inserării simbolului S2[j], D(i - 1, j - 1) + costul înlocuirii simbolului S1[i] cu simbolul S2[j] } întoarce D(M, N)(Vă reamintim că elementele rândurilor sunt numerotate de la primul , nu de la zero.)
Pentru a restabili prescripția editorială, este necesar să se calculeze matricea D, apoi să se treacă din colțul din dreapta jos (M, N) în stânga sus, la fiecare pas căutând minim trei valori:
Aici (i, j) este celula matricei în care ne aflăm la acest pas. Dacă două dintre cele trei valori sunt minime (sau toate trei sunt egale), înseamnă că există 2 sau 3 prescripții editoriale echivalente.
Acest algoritm se numește algoritmul Wagner-Fisher. A fost propus de R. Wagner (RA Wagner) și M. Fischer (MJ Fischer) în 1974. [patru]
Algoritmul în forma descrisă mai sus necesită operații și aceeași memorie. Acesta din urmă poate fi enervant: de exemplu, compararea fișierelor cu o lungime de 10 5 linii va necesita aproximativ 40 de gigaocteți de memorie.
Dacă este necesară doar distanța, este ușor să reduceți memoria necesară la . Pentru a face acest lucru, trebuie să ținem cont de faptul că după calcularea oricărei linii, linia anterioară nu mai este necesară. Mai mult, după calcularea D(i, j), D(i-1,0) ... D(i-1,j-1) nu este de asemenea necesar. Prin urmare, algoritmul poate fi rescris ca
pentru toate i de la 0 la M pentru toate j de la 0 la N calculați D(i, j) dacă i > 0 ștergeți linia D(i - 1) întoarce D(M, N)sau chiar
pentru toate i de la 0 la M pentru toate j de la 0 la N calculați D(i, j) dacă i > 0 și j > 0 ștergeți D(i - 1, j - 1) întoarce D(M, N)Dacă este necesar un mandat editorial, salvarea memoriei devine mai dificilă.
Pentru a asigura timpul de memorie , definim o matrice E de distante minime intre sufixele sirurilor , adica E(i, j) este distanta dintre ultimele i caractere si ultimele j caractere . Evident, matricea E poate fi calculată în mod similar cu matricea D și la fel de rapid.
Acum descriem algoritmul, presupunând că acesta este cel mai scurt dintre cele două șiruri.
Timpul de execuție satisface (până la înmulțirea cu o constantă) condiția
,de unde rezultă (demonstrat prin inducție pe M)
prin urmare
Memoria necesară este proporțională
În plus, există algoritmi care economisesc memorie din cauza unei încetiniri semnificative, de exemplu, timpul devine cubic, nu pătratic, în lungimea liniilor.
Siruri de caractere | |
---|---|
Măsuri de similitudine a șirurilor | |
Căutare subșir | |
palindromuri | |
Alinierea secvenței | |
Structuri de sufix | |
Alte |