Số lần chỉnh sửa ngắn nhất giữa hai từ


11

Tôi đang tìm kiếm một cấu trúc dữ liệu và một thuật toán để tính toán số lượng thay đổi tối thiểu cần thiết để chuyển đổi một từ này thành một từ khác, với hai từ là đầu vào, trong đó chỉ có các thay đổi được phép

  • thêm một chữ cái tại một trong các điểm cực trị (ví dụ: AB -> ABC),
  • nhân đôi và ghép toàn bộ từ (ví dụ: ABC -> ABCABC),
  • cắt một từ thành hai (kép của di chuyển trùng lặp, ABCABC -> ABC + ABC),
  • xóa một trong các chữ cái (ví dụ: ABC -> AC) và
  • lặp lại một trong các chữ cái (ví dụ: ABC -> ABBC).

Ví dụ: một chuỗi di chuyển tối thiểu từ ABC sang BCBC là ABC -> BC (xóa A) -> BCBC (sao chép).

Tôi không có nền tảng về khoa học máy tính. Có lẽ đây là một vấn đề nổi tiếng, nhưng tìm kiếm Google của tôi không cho tôi được gì.

Bạn có biết một số vấn đề liên quan, được xác định rõ?

Chỉnh sửa : Như được đề xuất trong câu trả lời của Anthony Labarre, tôi đã đọc một số bài viết về vấn đề hoán vị / sắp xếp poset tương tự như vấn đề được mô tả ở trên. Có ai biết thêm về vấn đề này? Điều này có liên quan không?


1
Có lẽ không ai trong danh sách tại en.wikipedia.org/wiki/String_metric áp dụng, cũng không có trong sourceforge.net/projects/simmetrics ?
András Salamon

Tôi không biết tất cả trong số họ, nhưng hầu hết mục tiêu của các phương pháp này là căn chỉnh các chuỗi chỉ thay đổi một chữ cái duy nhất được phép và không cho phép di chuyển phức tạp hơn.
cz3rk

1
Một bản sao được áp dụng trên toàn bộ chuỗi ABC -> ABCABC để hướng không quan trọng. Nhưng hướng của sự lặp lại chỉ có thể theo thứ tự bên trái, giống như một người lắp bắp.
cz3rk

2
Tại sao nó không quan trọng nếu các từ đầu vào không chia sẻ chữ cái? (Cần có một chuỗi trống giữa ABtrong chuỗi của @ reinerpost.)
Jeffε

2
Bạn đã thêm thao tác "cắt một từ làm hai"; bạn có nghĩa là các hoạt động mà bản đồ đến ? wwww
argentpepper

Câu trả lời:


3

Tôi không biết liệu vấn đề chính xác này đã được nghiên cứu hay chưa, nhưng Chaudhuri et al. đã nghiên cứu vấn đề mất ngẫu nhiên song song liên quan : bạn được hoán vị và bạn muốn chuyển đổi nó thành hoán vị danh tính bằng cách (1) sao chép một đoạn có độ dài bất kỳ và nối thêm bản sao ngay sau bản gốc, sau đó (2) xóa các phần tử để bạn có được một hoán vị mới thay vì một chuỗi. Lưu ý rằng áp dụng (1) sau đó (2) cho một thao tác.

Các biến thể khác nhau có thể được xác định theo trọng lượng cho mỗi thao tác, trong bài báo của chúng phụ thuộc vào độ rộng của các đoạn trùng lặp. Họ cũng nghiên cứu một vấn đề tương tự với toàn bộ bộ gen , đây chính xác là loại sao chép mà bạn cho phép. Tôi không nhớ đã đọc về công việc về vấn đề này trong ngữ cảnh của các chuỗi, nhưng tôi hy vọng điều này ít nhất có thể cung cấp cho bạn một điểm khởi đầu cho các tìm kiếm của bạn.


Cảm ơn, tôi sẽ có một cái nhìn vào công việc của họ. Tôi có thể thấy mối quan hệ giữa hai vấn đề.
cz3rk

2

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=x1xny=y1ymd(x,y)

min{d(x,y1ym1)+1▻ Add letter at endd(x,y2ym)+1▻ Add letter at beginningd(x,y1ym/2)+1if y=y1ym/2y1ym/2▻ Doublingd(x1xn/2,y)+1if x=x1xn/2x1xn/2▻ Halvingd(x1xn,y)+1▻ Deletiond(x1xn1,y1ym1)if yn=ym▻ 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ẽAcó đượ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ạnAAAchạ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.AA

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.


0

Một số vấn đề liên quan, được xác định rõ sẽ là vấn đề liên kết trình tự . Nó khác bởi vì nó không sử dụng thao tác sao chép. Các thao tác được xác định là: chèn ký tự, xóa ký tự, chuyển đổi ký tự. Thuật toán phổ biến để giải quyết vấn đề này là Needman-Wunsch .


Tôi biết điều này nhưng tôi thực sự muốn làm việc với một loạt các động thái được xác định. Cách duy nhất mà tôi đã tìm thấy để làm điều đó, là với một thuật toán đệ quy brute-force. Không đẹp lắm và anh ta có thể trở nên chuyên sâu tính toán nếu kích thước của các từ tăng lên.
cz3rk

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.