Như đã được chỉ ra, vấn đề này tương tự như vấn đề khoảng cách chỉnh sửa thường được biết đến (bên dưới khoảng cách Levenshtein ). Nó cũng có những điểm tương đồng với, ví dụ như khoảng cách Warping Dynamic Time (sự trùng lặp, hoặc nói lắp, trong yêu cầu cuối cùng của bạn).
Các bước hướng tới lập trình động
Nỗ lực đầu tiên của tôi về phân rã đệ quy dọc theo các khoảng cách Levenshtein và Khoảng cách cong thời gian động là một cái gì đó như sau (đối với và ), với được đặt thành
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.
Ở đây, tùy chọn cuối cùng về cơ bản nói rằng chuyển đổi FOOX sang BARX tương đương với chuyển đổi FOO sang BAR. Điều này có nghĩa là bạn có thể sử dụng tùy chọn thêm chữ cái ở tùy chọn end end để đạt được hiệu ứng nói lắp (sao chép) và xóa tại một điểm. Vấn đề là nó tự động cho phép bạn thêm một tùy ý nhân vật ở giữa của chuỗi cũng , một cái gì đó có thể bạn không muốn. (Điều này bỏ qua các yếu tố cuối cùng giống hệt nhau. Đây là cách tiêu chuẩn để đạt được việc xóa và nói lắp ở các vị trí tùy ý.
Tôi đã bao gồm sự cố này mặc dù nó không hoàn thành công việc, trong trường hợp người khác có thể cứu được nó, bằng cách nào đó, và vì tôi sử dụng nó trong giải pháp heuristic của mình, bên dưới.
(Tất nhiên, nếu bạn có thể gặp sự cố như thế này thực sự xác định khoảng cách của bạn, bạn chỉ cần thêm ghi nhớ và bạn sẽ có giải pháp. Tuy nhiên, vì bạn không chỉ làm việc với tiền tố, tôi không ' Bạn nghĩ rằng bạn chỉ có thể sử dụng các chỉ mục cho việc ghi nhớ của mình, bạn có thể phải lưu trữ các chuỗi thực tế, đã sửa đổi cho mỗi cuộc gọi, sẽ rất lớn nếu các chuỗi của bạn có kích thước đáng kể.)
Các bước hướng tới một giải pháp heuristic
Một cách tiếp cận khác, có thể dễ hiểu hơn và có thể sử dụng ít không gian hơn một chút, là tìm kiếm đường dẫn chỉnh sửa ngắn nhất, từ chuỗi đầu tiên đến chuỗi thứ hai của bạn, sử dụng thuật toán (về cơ bản, tốt nhất- nhánh đầu tiên và ràng buộc). Không gian tìm kiếm sẽ được xác định trực tiếp bởi các hoạt động chỉnh sửa của bạn. Bây giờ, đối với một chuỗi lớn, bạn sẽA∗có được một vùng lân cận lớn, vì bạn có thể xóa bất kỳ ký tự nào (cung cấp cho bạn một hàng xóm cho mỗi lần xóa tiềm năng) hoặc sao chép bất kỳ ký tự nào (một lần nữa, cung cấp cho bạn một số lượng lân cận tuyến tính), cũng như thêm bất kỳ ký tự nào ở cuối cung cấp cho bạn một số hàng xóm bằng hai lần kích thước bảng chữ cái. (Chỉ hy vọng bạn không sử dụng Unicode đầy đủ ;-) Với lượng fanout lớn như vậy, bạn có thể đạt được tốc độ khá đáng kể bằng cách sử dụng hai chiều hoặc một số người thânA∗ .
Để làm cho hoạt động, bạn cần có giới hạn thấp hơn cho khoảng cách còn lại với mục tiêu của mình. Tôi không chắc có sự lựa chọn rõ ràng nào ở đây không, nhưng những gì bạn có thể làm là triển khai giải pháp lập trình động dựa trên phân rã đệ quy mà tôi đã đưa ra ở trên (một lần nữa với các vấn đề không gian có thể xảy ra nếu chuỗi của bạn rất dài). Mặc dù phân tách đó không tính toán chính xác khoảng cách của bạn, nhưng nó được đảm bảo là giới hạn thấp hơn (vì nó dễ cho phép hơn), điều đó có nghĩa là nó sẽ hoạt động như một heuristic trong . (Tôi sẽ không biết nó chặt đến mức nào, nhưng nó sẽ đúng.) Tất nhiên, việc ghi nhớ chức năng ràng buộc của bạn có thể được chia sẻ trên tất cả các tính toán của ràng buộc trong của bạnA∗A∗A∗chạy. (Một sự đánh đổi thời gian / không gian ở đó.)
Vì thế…
Hiệu quả của giải pháp đề xuất của tôi dường như phụ thuộc khá nhiều vào (1) độ dài của chuỗi và (2) kích thước của bảng chữ cái của bạn. Nếu không phải là rất lớn, nó có thể làm việc. Đó là:
- Thực hiện giới hạn dưới với khoảng cách của bạn bằng cách sử dụng phân tách đệ quy và lập trình động của tôi (ví dụ: sử dụng hàm đệ quy, ghi nhớ).
- Triển khai (hoặc hai chiều ) với các thao tác chỉnh sửa của bạn khi có thể di chuyển trên phạm vi không gian nhà nước và giới hạn dưới dựa trên lập trình động.A∗A∗
Tôi thực sự không thể đưa ra bất kỳ sự đảm bảo nào về hiệu quả của nó, nhưng nó phải chính xác, và nó có lẽ sẽ tốt hơn rất nhiều so với một giải pháp vũ phu.
Nếu không có gì khác, tôi hy vọng điều này cung cấp cho bạn một số ý tưởng để điều tra thêm.