Odległość Levenshteina

Odległość Levenshteina
Struktura danych

Tablice znaków

Złożoność
Czasowa

Pamięciowa

lub

Odległość Levenshteina (edycyjna) – miara odmienności napisów (skończonych ciągów znaków), zaproponowana w 1965 roku przez Władimira Lewensztejna.

Definicja[edytuj | edytuj kod]

Formalnie jest to metryka w przestrzeni ciągów znaków, zdefiniowana następująco:

  • działaniem prostym na napisie nazwiemy:
    • wstawienie nowego znaku do napisu
    • usunięcie znaku z napisu
    • zamianę znaku w napisie na inny znak
  • odległością pomiędzy dwoma napisami jest najmniejsza liczba działań prostych, przeprowadzających jeden napis na drugi.

Miara ta znajduje zastosowanie w przetwarzaniu informacji, danych w postaci ciągów symboli: w maszynowym rozpoznawaniu mowy, analizie DNA, rozpoznawaniu plagiatów, korekcie pisowni (np. wyszukiwanie w spisie telefonicznym błędnie podanego nazwiska) itp.

Przykłady[edytuj | edytuj kod]

Odległość Levenshteina pomiędzy napisami identycznymi, np.

pies pies 

jest zerowa – skoro są identyczne, to potrzeba zero działań, by jeden z nich przeprowadzić na drugi.

Odległość Levenshteina pomiędzy napisami:

granat granit 

wynosi 1, ponieważ do przeprowadzenia pierwszego na drugi wystarcza jedno działanie: zamiana litery a na i.

Odległość pomiędzy napisami:

orczyk oracz 

równa jest 3, ponieważ do przeprowadzenia pierwszego napisu na drugi potrzeba trzech działań: usunięcia liter y i k oraz wstawienia litery a.

Odległość pomiędzy napisami:

marka ariada 

wynosi 4, ponieważ potrzeba co najmniej czterech działań, np.: usunięcia litery m, zamiany k na i oraz dodania d i a.

Obliczanie odległości Levenshteina[edytuj | edytuj kod]

Odległość Levenshteina można obliczyć używając programowania dynamicznego. Przykładowy algorytm w pseudokodzie:

int LevenshteinDistance(char s[1..m], char t[1..n])        declare int d[0..m, 0..n] // niech d będzie tablicą o m+1 wierszach i n+1 kolumnach      for i from 0 to m        d[i, 0] := i    for j from 1 to n        d[0, j] := j      for i from 1 to m        for j from 1 to n            if s[i] = t[j] then cost := 0                           else cost := 1            d[i, j] := minimum(d[i-1, j] + 1,       // usuwanie                               d[i, j-1] + 1,       // wstawianie                               d[i-1, j-1] + cost)  // zamiana      return d[m, n] 

Uogólnienia i przypadki szczególne[edytuj | edytuj kod]

Odległość Levenshteina jest uogólnieniem odległości Hamminga; sama też ma swoje uogólnienia, oparte na rozszerzaniu zestawu działań uważanych za „proste”.

  • Podstawowym rozszerzeniem jest uznanie za „działanie proste” zamiany miejscami dwu sąsiednich znaków – odległość Damerau-Levenshteina.
  • Innym spotykanym jest dopuszczenie wstawiania, usuwania i zastępowania spójnych ciągów znaków (bloków, nieprzerwanych fragmentów napisu). Jest to szczególnie pożyteczne przy przetwarzaniu ciągów danych o wyróżnionych mniejszych fragmentach, jak wyrazy w zdaniu.

Tak zdefiniowane miary nazywa się odległością transformacyjną, jednak czasem są również nazywane odległościami edycyjnymi. Z tego powodu użycie określenia „odległość edycyjna” należy zawsze uściślić, podając, na jakim zestawie działań opiera się używana miara.

Linki zewnętrzne[edytuj | edytuj kod]