Seperti yang telah ditunjukkan, masalah ini mirip dengan masalah jarak edit yang lebih dikenal (yang mendasari jarak Levenshtein ). Ini juga memiliki kesamaan dengan, misalnya, jarak Dynamic Time Warping (duplikasi, atau "gagap," dalam persyaratan terakhir Anda).
Langkah menuju pemrograman dinamis
x=x1…xny=y1…ymd(x,y)
min⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪d(x,y1…ym−1)+1d(x,y2…ym)+1d(x,y1…ym/2)+1d(x1…xn/2,y)+1d(x1…xn,y)+1d(x1…xn−1,y1…ym−1)if y=y1…ym/2y1…ym/2if x=x1…xn/2x1…xn/2if yn=ym▻ Add letter at end▻ Add letter at beginning▻ Doubling▻ Halving▻ Deletion▻ Ignoring last elt.
Di sini, opsi terakhir pada dasarnya mengatakan bahwa mengubah FOOX ke BARX sama dengan mengubah FOO ke BAR. Ini berarti bahwa Anda dapat menggunakan opsi “add letter at end” untuk mencapai efek kegagapan (duplikasi), dan penghapusan pada suatu titik. Masalahnya adalah bahwa secara otomatis memungkinkan Anda menambahkan sewenang-wenang karakter di tengah-tengah string juga , sesuatu yang Anda mungkin tidak ingin. (Ini "mengabaikan elemen terakhir yang identik" adalah cara standar untuk mencapai penghapusan dan kegagapan dalam posisi sewenang-wenang. Itu memang membuat melarang penyisipan sewenang-wenang, sambil memungkinkan penambahan di kedua ujung, sedikit rumit, meskipun ...)
Saya sudah memasukkan pengelompokan ini walaupun itu tidak melakukan pekerjaan sepenuhnya, kalau-kalau ada orang lain yang bisa "menyelamatkannya", dan karena saya menggunakannya dalam solusi heuristik saya, di bawah.
(Tentu saja, jika Anda bisa mendapatkan rincian seperti ini yang benar-benar menentukan jarak Anda, Anda hanya perlu menambahkan memoisasi, dan Anda akan punya solusinya. Namun, karena Anda tidak hanya bekerja dengan awalan, saya tidak mau ' t berpikir Anda bisa menggunakan hanya indeks untuk memoisasi Anda; Anda mungkin harus menyimpan string yang sebenarnya dimodifikasi untuk setiap panggilan, yang akan menjadi besar jika string Anda berukuran besar.)
Langkah menuju solusi heuristik
Pendekatan lain, yang mungkin lebih mudah dipahami, dan yang bisa menggunakan sedikit ruang lebih sedikit, adalah mencari "jalur edit" terpendek dari string pertama Anda ke yang kedua, menggunakan algoritma (pada dasarnya, terbaik- cabang-dan-terikat pertama). Ruang pencarian akan ditentukan secara langsung oleh operasi edit Anda. Sekarang, untuk string besar, Anda akan melakukannyaA∗A ∗dapatkan lingkungan yang luas, karena Anda dapat menghapus karakter apa pun (memberi Anda tetangga untuk setiap penghapusan potensial), atau menduplikasi karakter apa pun (sekali lagi, memberi Anda jumlah tetangga linear), serta menambahkan karakter apa pun di kedua ujungnya, yang akan memberi Anda sejumlah tetangga sama dengan dua kali ukuran alfabet. (Hanya berharap Anda tidak menggunakan Unicode penuh ;-) Dengan fanout yang begitu besar, Anda dapat mencapai percepatan yang cukup besar menggunakan dua arah , atau relatifA∗ .
Agar berfungsi, Anda memerlukan batas bawah untuk jarak yang tersisa ke target Anda. Saya tidak yakin apakah ada pilihan yang jelas di sini, tetapi yang dapat Anda lakukan adalah mengimplementasikan solusi pemrograman dinamis berdasarkan dekomposisi rekursif yang saya berikan di atas (sekali lagi dengan masalah ruang yang mungkin jika string Anda sangat panjang). Sementara itu dekomposisi tidak tepat menghitung jarak, itu adalah dijamin akan lebih rendah terikat (karena lebih permisif), yang berarti itu akan bekerja sebagai heuristik di . (Seberapa ketat itu, saya tidak tahu, tetapi itu akan benar.) Tentu saja, memoisasi fungsi terikat Anda dapat dibagikan di semua perhitungan batas selamaA ∗ A ∗A∗A∗A∗Lari. (Pengorbanan waktu / ruang di sana.)
Begitu…
Efisiensi dari solusi yang saya usulkan tampaknya sedikit bergantung pada (1) panjang string Anda, dan (2) ukuran alfabet Anda. Jika tidak ada yang besar, itu mungkin berhasil. Itu adalah:
- Terapkan batas bawah pada jarak Anda menggunakan dekomposisi rekursif saya dan pemrograman dinamis (misalnya, menggunakan fungsi memoise, rekursif).
- Terapkan (atau dua arah ) dengan operasi edit Anda sebagai "bergerak" di ruang-negara, dan batas bawah berbasis pemrograman dinamis.A ∗A∗A∗
Saya benar-benar tidak bisa memberikan jaminan seberapa efisiennya, tetapi harus benar, dan mungkin akan jauh lebih baik daripada solusi brute-force.
Jika tidak ada yang lain, saya harap ini memberi Anda beberapa ide untuk penyelidikan lebih lanjut.