Edit jarak daftar dengan elemen unik

12

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).

O ( min ( s , m , n ) s ) sO(min(m,n)s)O(min(s,m,n)s)s

Lebih formal,

seberapa efisien kita dapat menghitung jarak edit antara dua string yang diberikan s,tΣ dengan janji bahwa mereka tidak memiliki huruf yang diulang?

Σ adalah alfabet yang sangat besar.

pengguna362178
sumber
Apa pertanyaanmu sekarang? bagaimana mempercepat jarak edit berpasangan, atau bagaimana mempercepat menghitung semua jarak berpasangan dari daftar string?
Raphael
2
Saya menduga pertanyaannya adalah: Bagaimana cara menghitung jarak sunting antara , di mana adalah string di atas beberapa alfabet yang sangat besar , dan kami dijamin bahwa tidak ada huruf yang muncul dua kali dalam atau di (OP mewakili setiap string sebagai daftar huruf, yaitu daftar elemen). Tapi ini perlu konfirmasi. s , t Σ Σ s ts,ts,tΣΣst
DW
Ya, dalam hal ini alfabet besar terdiri dari indeks basis data dan "string", s dan t, adalah daftar yang berisi indeks ini.
user362178
Bagi mereka yang bertanya-tanya tentang kerumitan: dan adalah panjang dari string input dan adalah jarak edit yang sebenarnya, sehingga termasuk dalam kompleksitas. Biaya setiap edit dianggap 1 tapi mungkin tidak relevan untuk menghitung jarak ini (jumlah suntingan ). n s smnss
Albert Hendriks

Jawaban:

3

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 LmnL, kemudian mereka menyisipkan / menghapus jarak editn+m2L : 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:

-C-IRC-LE
T-RI-CKLE

Di sini LCS dari CIRCLEdan TRICKLE, ICLEmemiliki panjang 4, dan jarak sunting memang .6+724=5

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)ABAAB, kami mengganti nama karakternya menggunakan tabel ini (yaitu, setiap kemunculan karakter apa pun yang pertama kali Adiubah menjadi 1, dll.). Akhirnya, kami mencari peningkatan berikutnya terpanjang di B. Ini sesuai dengan LCS antara Adan B, dan dari sana kita dapat segera menghitung jarak sisipkan / hapus sunting. Total waktu yang dibutuhkan hanya jika dan masing-masing memiliki panjang dan .O(n+mlogm)ABnm

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 ) drO((r+n)logn)rndiffdiffO(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).

Hunt, J.; Szymanski, T. (1977), "Algoritma cepat untuk menghitung urutan umum terpanjang", Communications of the ACM, 20 (5): 350-353, doi: 10.1145 / 359581.359603

j_random_hacker
sumber