Jarak edit Levenshtein-Distance antara daftar adalah masalah yang dipelajari dengan baik. Tetapi saya tidak dapat menemukan banyak perbaikan yang mungkin jika diketahui bahwa tidak ada elemen yang muncul lebih dari satu kali di setiap daftar .
Mari kita asumsikan juga bahwa elemen-elemennya sebanding / disortir (tetapi daftar untuk dibandingkan tidak diurutkan sejak awal).
Lebih formal,
seberapa efisien kita dapat menghitung jarak edit antara dua string yang diberikan dengan janji bahwa mereka tidak memiliki huruf yang diulang?
adalah alfabet yang sangat besar.
algorithms
strings
string-metrics
edit-distance
pengguna362178
sumber
sumber
Jawaban:
TL; DR: Jenis pengeditan yang sedikit lebih membatasi, di mana kita hanya dapat menyisipkan dan menghapus karakter individual, dapat dihitung dalam waktu linearithmic ketika kedua (atau bahkan hanya satu) string memiliki karakter unik. Ini memberi batas atas dan bawah yang berguna pada jarak edit Levenshtein.
Masukkan / hapus jarak edit, dan urutan umum terpanjang
Jarak edit Levenshtein memungkinkan penyisipan, penghapusan, dan pergantian karakter tunggal, yang masing-masing menetapkan biaya 1. Jika kita membatasi hanya penyisipan dan penghapusan, kita mendapatkan ukuran jarak yang sama yang sekarang menyebabkan pergantian memiliki biaya 2 (karena setiap substitusi dapat ditiru menggunakan penyisipan dan penghapusan). Saya tidak tahu nama standar untuk jenis edit jarak yang lebih ketat ini, jadi saya akan menyebutnya "masukkan / hapus jarak edit". Hal ini berkaitan erat dengan masalah Common Commoncenceence (LCS) terpanjang , di mana kita diberi dua string, panjang dan , masing-masing, dan ingin mengetahui panjang dari urutan terpanjang yang muncul pada keduanya. Jika dua string memiliki LCSn L n + m - 2 Lm n L , kemudian mereka menyisipkan / menghapus jarak editn+m−2L : cara termudah untuk melihat ini adalah dengan menyelaraskan string sehingga karakter dalam LCS tampak ditumpuk di atas satu sama lain, sementara karakter yang tidak ada dalam LCS muncul di seberang
-
celah karakter. Maka akan jelas bahwa kita dapat mengedit string pertama menjadi string kedua dengan membuat penyisipan di mana pun ada-
di baris atas, dan penghapusan di mana pun ada-
di baris bawah. Sebagai contoh:Di sini LCS dari6+7−2∗4=5
CIRCLE
danTRICKLE
,ICLE
memiliki panjang 4, dan jarak sunting memang .Selanjutnya meningkat terpanjang
Alasan untuk jalan memutar ini adalah bahwa ada cara yang sangat efisien untuk menghitung LCS (dan dengan demikian menyisipkan / menghapus jarak edit) ketika setidaknya satu dari sekuens hanya berisi karakter yang berbeda: Dalam hal ini, masalah LCS dapat diubah menjadi masalah menemukan urutan meningkat terpanjang , yang dapat diselesaikan dalam waktu . Misalkan kita diberi dua string dan , dan string memiliki karakter yang berbeda. Kita bisa mengganti nama karakter pertama di ke 1, yang kedua ke 2 dan seterusnya, melacak nomor apa yang kita tetapkan untuk setiap karakter dalam tabel. Kemudian diA B A A B O ( n + m log m ) A B n mO(nlogn) A B A A B , kami mengganti nama karakternya menggunakan tabel ini (yaitu, setiap kemunculan karakter apa pun yang pertama kali O(n+mlogm) A B n m
A
diubah menjadi 1, dll.). Akhirnya, kami mencari peningkatan berikutnya terpanjang diB
. Ini sesuai dengan LCS antaraA
danB
, dan dari sana kita dapat segera menghitung jarak sisipkan / hapus sunting. Total waktu yang dibutuhkan hanya jika dan masing-masing memiliki panjang dan .Batas edit jarak Levenshtein
Jarak sisipkan / hapus jelas memberikan batas atas pada jarak Levenshtein (karena setiap urutan operasi edit yang sah di bawah jarak sisipkan / hapus juga merupakan urutan yang valid dari operasi edit Levenshtein). Membagi jarak edit sisipan / hapus oleh 2 juga memberikan batas yang lebih rendah, karena dalam kasus terburuk setiap operasi edit Levenshtein dapat diubah menjadi 2 operasi sisipan / hapus edit.
Generalisasi
Sudah pada tahun 1977, Hunt dan Szymanski datang dengan suatu algoritma yang dapat dilihat sebagai generalisasi dari algoritma berikutnya yang paling lama meningkat. Ini efisien setiap kali jumlah pasangan posisi karakter yang cocok antara kedua string kecil. Jika ada pasangan seperti itu, algoritme mereka membutuhkan waktu . (Perhatikan bahwa jika semua karakter dalam satu string berbeda.) Algoritma ini adalah dasar dari program asli , yang memperlakukan seluruh baris teks sebagai karakter individu. kemudian beralih menggunakan algoritma waktu - Myers , di manaO ( ( r + n ) log n ) r ≤ n O ( n d ) dr O((r+n)logn) r≤n O(nd) d adalah jarak sisipkan / hapus edit, karena ini berkinerja lebih baik ketika perbedaan keseluruhan kecil tetapi beberapa "karakter" (baris teks) sering muncul (seperti garis yang hanya berisi kurung pembuka dalam kode program C).
diff
diff
sumber