2つの単語間で最短の編集移動


11

入力として2つの単語が与えられた場合、1つの単語を別の単語に変換するために必要な最小限の変更を計算するデータ構造とアルゴリズムを探しています。

  • いずれかの端に文字を追加します(たとえば、AB-> ABC)。
  • 単語全体を複製および連結します(たとえば、ABC-> ABCABC)。
  • 単語を2つにカットします(複製移動の二重、ABCABC-> ABC + ABC)。
  • 文字の1つを削除します(たとえば、ABC-> AC)。
  • いずれかの文字を繰り返します(たとえば、ABC-> ABBC)。

たとえば、ABCからBCBCへの移動の最小シーケンスは、ABC-> BC(削除A)-> BCBC(複製)です。

私はコンピューターサイエンスのバックグラウンドを持っていません。おそらくこれはよく知られている問題ですが、私のGoogle検索では何も得られませんでした。

関連する明確に定義された問題を知っていますか?

編集:Anthony Labarreの回答で示唆されたように、私は上記の問題に似たポーズの順列/配置の問題に関するいくつかの論文を読みました。誰もこの問題についてもっと知っていますか?これは関連性がありますか?


1
おそらくen.wikipedia.org/wiki/String_metricのリストからは適用されず、sourceforge.net / projects / simmetricsにも適用されませんか?
アンドラスサラモン

それらのすべてを知っているわけではありませんが、これらのメソッドの目標のほとんどは、単一文字の変更のみを許可し、より複雑な移動を許可しないで文字列を整列させることです。
cz3rk

1
重複は文字列ABC-> ABCABC全体に適用されるため、方向は関係ありません。しかし、繰り返しの方向は、ごちゃごちゃのように、左右の順序でしかできません。
cz3rk

2
入力語が文字を共有しない場合、なぜ重要なのですか?(間に空の文字列があるべきABreinerpostのシーケンス@インチ)
Jeffε

2
「単語を2つに切る」という操作を追加しました。をマッピングする操作を意味しますか?wwww
argentpepper

回答:


3

この正確な問題が研究されたかどうかはわかりませんが、 Chaudhuri et al。関連するタンデム複製-ランダム損失の問題を検討しました:順列が与えられ、(1)任意の長さのセグメントを複製し、元の直後にコピーを追加し、(2)削除することにより、それを恒等置換に変換したい文字列の代わりに新しい順列を取得するための要素。(1)を適用してから(2)1つの操作を説明することに注意してください。

異なるバリアントは、各操作に与えられた重みに従って定義できます。その重みは、紙では複製されたセグメントの幅に依存します。彼らはまた、ゲノム全体の複製に関する同様の問題を研究しています。これはまさにあなたが許可する複製の種類です。文字列のコンテキストでこの問題の作業について読んだことは覚えていませんが、これが少なくとも検索の出発点になることを願っています。


ありがとう、私は彼らの仕事を見ていきます。2つの問題の関係がわかります。
cz3rk

2

指摘されているように、この問題はより一般的に知られている編集距離の問題(レーベンシュタイン距離の根底にある)に似ています。また、たとえば、動的タイムワーピング距離(最後の要件での複製、または「“音」)との共通点もあります。

動的プログラミングへのステップ

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.

ここで、最後のオプションは、基本的に、FOOXをBARXに変換することは、FOOをBARに変換することと同等であることを示しています。これは、「末尾に文字を追加」オプションを使用して、utter音(複製)効果とポイントでの削除を実現できることを意味します。問題は、それが自動的に追加できることです任意の文字列の途中で文字だけでなく、あなたはおそらくしたくない何かを。(この「同一の最後の要素を無視する」ことは、任意の位置で削除とutter音を達成する標準的な方法です。任意の挿入を禁止しますが、両端で追加を許可しますが、少し注意が必要です...)

他の誰かがそれを何らかの方法で「救助」できるように、また以下のヒューリスティックソリューションで使用するために、完全に仕事を果たさなくても、この内訳を含めました。

(もちろん、実際に距離を定義するこのような内訳を取得できる場合、メモを追加するだけで解決策が得られます。ただし、プレフィックスを操作しているだけではないため、メモ化にインデックスだけを使用できるとは思わない。実際の変更された文字列を呼び出しごとに保存する必要があるかもしれませんが、文字列がかなりのサイズである場合は巨大になります)

発見的解決へのステップ

別のアプローチは、理解しやすく、スペースをかなり少なくすることができますが、アルゴリズムを使用して、最初の文字列から2番目の文字列までの最短「編集パス」を検索することです(基本的に、最初の分岐限定)。サーチスペースは、編集操作によって直接定義されます。さて、大きな文字列の場合、次のようになりますAA 任意のキャラクターを削除するか(削除の可能性ごとに隣人を与える)、任意のキャラクターを複製する(再び、隣人の線形数を与える)だけでなく、両端に任意の文字を追加できるため、アルファベットサイズの2倍の数の隣人を指定します。(完全なUnicodeを使用していないことを願っています;-)このような大規模なファンアウトでは、双方向 またはいくつかの相対Aを使用して、大幅な高速化を達成できます。

機能させるには、ターゲットまでの残りの距離の下限が必要です。ここに明確な選択肢があるかどうかはわかりませんが、あなたができることは、上記で示した再帰的分解に基づいて動的プログラミングソリューションを実装することです(文字列が非常に長い場合は、スペースの問題が発生する可能性があります)。この分解は距離を正確に計算するわけではありませんが、下限保証されています(より許容度が高いため)。つまり、ヒューリスティックとして機能します。(どれだけタイトかはわかりませんが、正しいでしょう。)もちろん、バインドされた関数のメモ化は、中のバインドのすべての計算で共有できますA A AAA走る。(時間/スペースのトレードオフがあります。)

そう…

私が提案したソリューションの効率は、(1)文字列の長さと(2)アルファベットのサイズにかなり依存しているように思われます。どちらも巨大ではない場合、動作する可能性があります。あれは:

  • 私の再帰分解と動的プログラミングを使用して(たとえば、メモされた再帰関数を使用して)、距離の下限を実装します。
  • 状態空間での「移動」としての編集操作と、動的プログラミングベースの下限を使用して、(または双方向)を実装します。A AA

私はそれがどれほど効率的であるかについての保証を本当にすることはできませんが、それ正しいはずです、そしてそれはおそらくブルートフォースのソリューションよりもずっと良いでしょう。

他に何もなければ、これがあなたにさらなる調査のためのいくつかのアイデアを与えることを望みます。


0

関連する、明確に定義されたいくつかの問題は、配列アライメントの問題です。複製の操作を使用しないため、異なります。定義されている操作は、文字の挿入、文字の削除、文字の変換です。この問題を解決するための一般的なアルゴリズムは、Needleman-Wunschです。


私はこれを知っていますが、私は本当に一連の定義された動きで働きたいです。私がそれを行うことがわかった唯一の方法は、ブルートフォース再帰アルゴリズムを使用することです。あまりいい人ではなく、単語のサイズが大きくなると計算量が多くなる可能性があります。
cz3rk

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.