web-dev-qa-db-ja.com

ノードの数を最小化する有向非循環グラフのマージ

[〜#〜] dag [〜#〜] s(有向非循環グラフ)がいくつかあり、ノードの数を最小限に抑えるためにそれらをマージしたい(すべてのノードにコスト、エッジはフリーです)。

これらの4つの異なるDAG(左から右に向けられています)...

a-b-c
a-d-c
a-c
c-a

...になるはずです:

 /---\
a--b--c-a
 \-d-/

これは本当ではありません [〜#〜] dawg [〜#〜] (有向非循環ワードグラフ):「 'adc'は含まれていますか?」のような情報を保存したくありません。私の構造はこの質問に答えることしかできませんでした:「 'adc'が単語の1つであった可能性はありますか?」。

この目的のためのアルゴリズムはありますか?

更新(12/15/14)-レーベンシュタイン距離

別の方法を試しました: Levenshtein distance を使用して、文字列を別の文字列に変換するために必要な編集の最小数を見つけました(node = characterandchain =シーケンス/ノード/文字= Word)。私のアルゴリズムは削除を無視し、文字を置き換えるのではなく挿入します。ここに興味深い部分があります(Pythonコード):

current = words[0]
for Word in words[1:]:
    edit = editops(current, Word)
    customEdit = [('insert', s, d) for op, s, d in edit if op != 'delete']
    current = apply_edit(customEdit, current, Word)

不要な文字がある場合があるので、プロセスの最後に削除します。単語の順序を変更すると、異なる結果が得られるため、短い文字列を見つけるためにコードを何度もシャッフルwordsします(シャッフルは反復回数が少ないより良い結果を提供するようです)順列(単語が長さでソートされている場合でも)。

すべての文字がノードであり、すべての単語がDAGである場合、探しているDAGの適切な近似を簡単に取得できます。

このアプローチの主な問題は、最良の結果がどのように表示されるかわからないため、いつ停止するかわからないことです(順列のすべての結果を確認することはできません。時間がかかりすぎます!)。

これが私の コード です(Python 2; python-Levenshtein でテストされています)。出力は次のようになります:

ldoarmilpesouimtr(17)
 iapmdsoeluiortem(16)
 diolposarmieutm(15)
 ^ C 
元のサイズ:22 
圧縮:15 
 
 diolposarmieutm(lorem)
 diolposarmieutm(ipsum)
diolposarmieutm(dolor)
 diolposarmi eutm(sit)
 diolposar mieut m(amet)

この問題を解決する良い方法ですか?何を改善できるでしょうか?最適化されたときにアルゴリズムを停止するために必要なノード/文字の最小数を知ることが可能かどうか知っていますか?

あなたの構造は最小限のDAWGの折れ線グラフだと思います。 3年前に、これらの線グラフから最小のDAWGを作成し、線グラフを最小化することで、これらを生成しました。私は文献とGoogleを広範囲に検索しましたが、この最後のステップは見つかりませんでした。 DAWGの方が一般的に有用であると結論付けましたが、DAWGに慣れていない人にはDAWGの方が表示に適していました。自然言語処理で使用されているDAWGの別の名前、Word Somethingがあります。これは、今私を思い起こさせるものです。

あなたのadcの例は、すべてのノードがシンクへの#エッジを持つDAWGを提案しています。

1
Jon