ツリーのセットのデータ構造。


10

トライにより、要素のリストを効率的に保存できます。接頭辞は共有されるため、スペース効率が高くなります。

木を効率的に保管するための同様の方法を探しています。特定のツリーがいくつかの格納されたツリーのサブツリーであるかどうか、または特定のツリーのサブツリーである格納されたツリーが存在するかどうかを知って、メンバーシップをチェックして要素を追加できるようにしたいと思います。

私は通常、高さが50未満の約500の不平衡バイナリツリーを格納します。

編集

私のアプリケーションは、ある種のメモを使用したある種のモデルチェッカーです。私が持っている状態を想像と以下の式:F = φG = φ ψ φは、複雑な部分式であることを、私が最初かどうかを知りたいと想像fが成り立つ。私はϕが成立するかどうかを確認し、長いプロセスの後、それが事実であることを確認します。ここで、gsに成立するかどうかを知りたい。私は事実を覚えたいfが保持していることに注意してくださいにグラムFsf=ϕg=(ϕψ)ϕfsϕgsfgf私は導き出すことができほぼ瞬時に。 逆に、gtに保持されないことを証明した場合、ftにほぼ瞬時に保持されないことを伝えたいと思います。gs
gtft

私たちは式に部分的秩序を構築し、持つことができます IFF グラムF。状態sごとに、2組の式を保存します。L s は保持する最大の数式を格納し、l s は保持しない最小の数式を格納します。今状態所与Sおよび式Gの場合、私が見ることができるF L S F G、又は場合F L S gfgfsL(s)l(s)sgfL(s),fg私が行っていると私はかどうかを直接知っている場合には gが成り立つfl(s),gfgs

現在、lはリストとして実装されており、保存されているすべての数式を個別に反復処理する必要があるため、これは明らかに最適ではありません。私の数式がシーケンスであり、部分的な順序が「の接頭辞」である場合、トライははるかに速く証明できます。残念ながら、私の式は、に基づいて構造のような木の持つ¬ 、モーダルオペレータ、および原子命題を。Ll¬,

@Raphaelと@Jackが指摘しているように、ツリーを順次化することはできますが、関心のある半順序が「is a prefix of」に対応しないため、問題が解決しないのではないかと心配しています。


簡単なアイデア:ツリーを順次処理して(順序どおりのトラバーサルを実行し、訪問したノードをそれに応じて一覧表示し、上下に移動するための特別な要素を追加して)、トライに格納しましたか?もちろん、これはある意味で、左側のサブツリーのチェックを「のみ」許可します。
ラファエル

2
あなたは、単にシリアル化の使用は何場合は、次のプロパティを持つ樹木のを:TはのサブツリーですT "の場合に限りS TはのストリングであるS T "?そのようなSの作成は簡単です(ツリーの標準形を最初に見つけた場合)。その後、あなたの質問は、文字列学で広く研究されている問題である部分文字列マッチングに相当します。STTS(T)S(T)S
Jukka Suomela、2011

1
用語索引付けを見てください。
starblue

1
別の簡単なアイデアは、すべてのツリーt1、t2、..を1つの大きなツリーTに格納し、各エッジについて、そのツリーが含まれているツリーのセットを思い出すことです。次に、fが格納されたツリーの1つのサブツリーであるかどうかを判断するには、まずfがTのサブツリーであるかどうかを判断し、そうである場合は、そのサブツリーのすべてのエッジラベルセットと交差します。答えは、交差点が空ではない場合です。(2つのステップを組み合わせることもできます)。
マーティンB.

回答:


5

g-triesをチェックしてみてください。これは基本的には探しているデータ構造ですが、ツリーだけでなく一般的なグラフで使用するように設計されています。そのため、g-triesが優れた理論的保証を持っているかどうかはわかりません-彼らはサブルーチンとしてグラフ標準化アルゴリズムを使用していると思います-しかし実際にはそれらはうまく機能しているようです。

(リンクされた論文が「生物学的ネットワークのネットワークモチーフ」に関するものであることを恐れないでください:g-trieはグラフにとって完全に優れた抽象的なデータ構造です。)


4

これの特別な形式は永続性です。Driscoll、Sarnak、Sleator、およびTarjanによる永続的なデータ構造の作成に関するペーパー、およびSarnak&Tarjanによる永続的検索ツリーを使用したPlanar Point Locationを参照してください。


1
参考にしていただきありがとうございます。現在、データ構造の永続化にアクセスすることはできませんが、永続化の概念にはある程度精通しています。ただし、永続化を使用して問題を解決する方法がわかりません。私は実際に、ツリーをブール値にマップする辞書を使用したいと思います。同じツリーが、異なる辞書の異なる値のキーになる可能性があります。
Abdallah

1
私はあなたのアプリケーションが何であるかがわからなかったので、プレフィックスを共有することによって文字列を保存するtryへのアナロジーをトリガーしました。しかし、「同じツリーが異なる辞書の異なる値の鍵になる可能性がある」というあなたのコメントは、試みにも適合しないようです。たぶん、検索できるツリー(およびそのすべてのサブツリー)の署名のコレクションが必要なだけですか?(たとえば、バイナリツリーにはカタロニア語の番号を、ラベル付きツリーにはプルーファーコードを使用します。)
Jack

1

これは森のように聞こえます(ばらばらに設定された森)...

ランクによる結合パス圧縮を使用した検索操作と呼ばれる手法により、挿入のコストを償却します。Sylvain ConchonとJean-ChristopheFilliâtreによって開発されたこの構造の永続的なバージョンもあることは知っていますが、これがジャックが言及しているものと同じであるかどうかはわかりません...



0

「Purely Functional Data Structures」(1998)で、Chris Okasakiは型集約(10.3.2)を使用した二分木の試行を提案しています。

これがすぐに役立つかどうかはわかりません。そこで与えられた解決策は直接実装できないかもしれません。


0

プログラマー用語:共通のサブ式/ツリー/ DAGからツリーを作成すると、素晴らしいコンパクトなモデルになります。そのように指示された非循環グラフ。次に、木のセットで十分です。

public class Tree {文字列操作; Tree []サブツリー。

public int compareTo(Tree rhs) {
    if (rhs == null) return false;
    int cmp = operation.compareTo(rhs.operation);
    if (cmp == 0) {
        cmp = Arrays.compareTo(subtrees, rhs.subtrees);
    }
    return cmp;
}

...}

map commonSubExpressions = new HashMap();

Tree get(String expressionSyntax){Tree t = new Tree(); t.operation = ...; t.subtrees = ...部分式を取得するための再帰呼び出し。ツリーt2 = commonSubExpressions.get(t); if(t2 == null){t2 = t; commonSubExpressions.put(t2、t2); } t2を返します。}}

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