タグ付けされた質問 「data-structures」

アルゴリズムで有利に使用できるようにデータを保存する方法に関する質問。

1
パーティションの洗練に基づくアルゴリズムが対数線形時間よりも高速に実行される問題
パーティションの洗練は、オブジェクトの有限セットから始めて、セットを徐々に分割する手法です。DFA最小化などの一部の問題は、パーティションの洗練を非常に効率的に使用して解決できます。ウィキペディアのページにリストされているもの以外のパーティションの改良を使用して通常解決される他の問題は知りません。これらすべての問題のうち、ウィキペディアのページでは、パーティションの洗練に基づくアルゴリズムが線形時間で実行される2つについて言及しています。辞書編集的に順序付けられたトポロジカルソート[1]と辞書編集幅優先検索アルゴリズム[2]があります。 パーティションの絞り込みを非常に効率的に使用して解決できる問題の例や参考文献はありますか? [1] Sethi、Ravi、「2つのプロセッサでのグラフのスケジューリング」、SIAM Journal on Computing 5(1):73–82、1976 [2] Rose、DJ、Tarjan、RE、Lueker、GS、「グラフ上の頂点除去のアルゴリズム的側面」、SIAM Journal on Computing 5(2):266–283、1976

1
SATローカル検索のデータ構造のサポート
WalkSATとGSATは、ブール充足可能性問題を解決するためのよく知られたシンプルなローカル検索アルゴリズムです。GSATアルゴリズムの擬似コードは、質問「GSATアルゴリズムの実装-反転するリテラルの選択方法」からコピーされています。以下に示します。 procedure GSAT(A,Max_Tries,Max_Flips) A: is a CNF formula for i:=1 to Max_Tries do S <- instantiation of variables for j:=1 to Max_Iter do if A satisfiable by S then return S endif V <- the variable whose flip yield the most important raise in the number of satisfied clauses; S …

2
自己順序付けバイナリツリーの作成
バイナリ検索ツリーを使用して自己アクセス順序に変更する必要がある割り当てがあり、最もアクセスされる(優先度が高い)アイテムがツリーの最上部にあり、ルートが最もアクセスされるノードです。 教授は私にBSTとノード構造体を提供してくれましたが、挿入中にツリーを更新するアルゴリズムに頭を悩ませようとすると混乱します。 挿入が発生すると、現在のノードのデータが現在のノードより少ないか大きいかをチェックし、nullポインターを見つけてそこに挿入するまで再帰的に正しい方向に進みます。挿入された後、優先度が1増加します。 template <class Type> void BinarySearchTree<Type> :: insert( const Type & x, BinaryNode<Type> * & t ) { if( t == NULL ) t = new BinaryNode<Type>( x, NULL, NULL ); else if( x < t->element ) insert( x, t->left ); else if( t->element < x ) insert( …

5
ラベルなしツリーの効率的な圧縮
ラベルのない、ルート付きのバイナリツリーを検討してください。私たちはできる圧縮サブツリーへのポインタがあるたび:そのような木をTTTとT′T′T'とT=T′T=T′T = T'(通訳===構造的平等など)、我々は保存(WLOG)TTTとのすべてのポインタ置き換えるT′T′T'へのポインタでTTT。例については、uliの回答を参照してください。 上記の意味でツリーを入力として使用し、圧縮後に残る(最小限の)ノード数を計算するアルゴリズムを提供します。このアルゴリズムは、入力のノード数nで、時間O(n log n )O(nlogn)O(nlog⁡n)\cal{O}(n\log n)(均一コストモデル)で実行する必要があります。nnn これは試験問題であり、良い解決策を思い付くことができず、見たこともありません。

2
最大フロー計算または他のアプリケーションのために、実際にリンクカットツリーは使用されていますか?
私がよく実装する多くの最大フローアルゴリズム、ダイニックのアルゴリズム、プッシュ再ラベルなどでは、動的ツリー(リンクカットツリーとも呼ばれます)を使用することで漸近的な時間コストを改善できます。 プッシュ再ラベルは、通常またはまたはますが、動的ツリーO (V 3)O (V 2 √O (V2E)O(V2E)O(V^2E)O (V3)O(V3)O(V^3)O(VElog(V2/E))O (V2E−−√)O(V2E)O(V^2\sqrt{E})O (VEログ(V2/ E))O(VElog⁡(V2/E))O(VE \log(V^2/E)) Dinicのアルゴリズムはで実行されますが、動的ツリーO (V E log (V ))O (V2E)O(V2E)O(V^2E)O (VEログ(V))O(VElog⁡(V))O(VE\log(V)) ただし、ほとんどのライブラリでのmax-flowアルゴリズムの実用的な実装では、このデータ構造を使用していないようです。ダイナミックツリーは、実際には最大フロー計算に使用されていますか?または、実際の問題のサイズに役立つにはオーバーヘッドが大きすぎますか? リンクカットツリーが使用される他の問題ドメインはありますか? この質問は、cstheoryで私が尋ねた質問に関連しています。最先端のMaximum Flowアルゴリズムは実用的ですか?

1
なぜ関数型プログラミングは動的ツリーを研究していないのですか?
動的ツリーは、ネットワークフロー、動的グラフ、組み合わせの問題(TarjanおよびWerneckによる「Dynamic Trees in Practice」)や最近の辞書のマージ(Adam Karczmarzによる「A Simple Mergeable Dictionary」)などの問題の解決に重要な役割を果たします。 動的ツリーについては、1983年のSleator&Tarjanの論文「動的ツリーのデータ構造」に記載されている定義を参照します。 Edward Kmettは、主にC ++の対応物の翻訳として、STツリーのバージョンを実装しました。リンクカットツリーを参照してください。 クリス・オカサキは、著名な著書「純粋に機能的なデータ構造」に、スプレイツリーの限定的な実装を書いています。 Ralf HinzeとRoss Patersonは、2〜3本のフィンガーツリーと呼ばれる機能的なデータ構造を導入しましたが、動的ツリーの元の定義とは多少異なる目的があります。 動的ツリーの実装(およびパフォーマンス)は、次の3つのアプローチに従って分割されます。 ETツリー(オイラーツアー)が重要な役割を果たす線形化。純粋に機能的な研究は見つかりませんでした。 STツリーが主力であるパス分解では、Kmettのバージョンが見つかりました。 ツリーの収縮。トップツリー、トポロジツリー、およびRCツリーがプレーヤーです。純粋に機能的な研究は見つかりませんでした。 純粋に機能的な分析と実装は、Splay、AVL、赤黒木で見つけることができますが、それらは動的な木ではありません。前者は後者のシャドウ(仮想または補助とも呼ばれる)データ構造と見なされます。 だから、私の質問は: 関数型プログラミング研究コミュニティが動的ツリーデータ構造に参加しない理由(欠点、弱点)は何ですか?

12
文字列間の違いをすばやく見つけるためのデータ構造またはアルゴリズム
私はすべて長さの100,000文字列の配列を持っています。各文字列を他のすべての文字列と比較して、2つの文字列が1文字異なるかどうかを確認します。現時点では、各文字列を配列に追加するときに、配列内の既存のすべての文字列に対してチェックしています。これは、時間の複雑さを持っています。kkkn (n − 1 )2kn(n−1)2k\frac{n(n-1)}{2} k 私がすでにやっていることよりも速く文字列を互いに比較できるデータ構造またはアルゴリズムはありますか? 追加情報: 注文事項は:abcdeとxbcdeしながら、1つの文字によって異なるabcdeとedcba4つの文字で異なります。 1文字異なる文字列のペアごとに、それらの文字列の1つを配列から削除します。 現在、私は1文字だけ異なる文字列を探していますが、その1文字の差を、たとえば2、3、または4文字に増やすことができればいいと思います。ただし、この場合、文字差の制限を大きくする能力よりも効率のほうが重要だと思います。 kkkは通常20〜40の範囲です。

1
どのクラスのデータ構造を永続化できますか?
永続データ構造は不変のデータ構造です。それらに対する操作は、データ構造の新しい「コピー」を返しますが、操作によって変更されます。ただし、古いデータ構造は変更されません。一般に、効率性は、基礎となるデータの一部を共有し、データ構造の完全なコピーを回避することにより達成されます。 質問: (同じまたは非常に類似した複雑さを維持しながら)永続化できるデータ構造のクラスに関する結果はありますか? (同じまたは非常に類似した複雑さを維持しながら)すべてのデータ構造を永続化できますか? (同じまたは非常に類似した複雑さを維持しながら)永続化できないデータ構造はありますか?

1
最後のN個の数値の加重合計
ストリームで数値を受け取っているとします。各数値を受信した後、最後の数値の加重合計を計算する必要があります。加重は常に同じですが、任意です。NNN 計算を支援するためにデータ構造を保持することが許可されている場合、これはどの程度効率的に実行できますか?よりも良いこと、つまり数字を受け取るたびに合計を再計算することはできますか?Θ(N)Θ(N)\Theta(N) 例:重みがます。ある時点で、最後の数値のリストと、加重和ます。W=⟨w1,w2,w3,w4⟩W=⟨w1,w2,w3,w4⟩W= \langle w_1, w_2, w_3, w_4\rangleNNNL1=⟨a,b,c,d⟩>L1=⟨a,b,c,d⟩>L_1= \langle a, b, c, d \rangle>S1=w1∗a+w2∗b+w3∗c+w4∗dS1=w1∗a+w2∗b+w3∗c+w4∗dS_1=w_1*a+w_2*b+w_3*c+w_4*d 別の番号を受け取ったら、リストを更新してをし、を計算する必要があります。eeeL2=⟨b,c,d,e⟩L2=⟨b,c,d,e⟩L_2= \langle b,c,d,e\rangleS2=w1∗b+w2∗c+w3∗d+w4∗eS2=w1∗b+w2∗c+w3∗d+w4∗eS_2=w_1*b+w_2*c+w_3*d+w_4*e FFTを使用した検討 この問題の特殊なケースは、高速フーリエ変換を使用することで効率的に解決できるようです。ここでは、倍数で加重和を計算します。言い換えれば、数値を受け取り、対応する加重和を計算することができます。これを行うには、過去の数(合計が既に計算されている)と、合計個の新しい数が必要です。SSSNNNNNNNNNN−1N−1N-1NNN2N−12N−12N-1 この入力数のベクトルと重みベクトル、係数を逆にして多項式との係数を定義する場合、積はaからまでの係数を持つ多項式が、求める重み付き和になります。これらは、時間でFFTを使用して計算できます。これにより、入力数ごとのΘ(\ log(N))時間の平均が得られます。WWWP(x)P(x)P(x)Q(x)Q(x)Q(x)QQQP(x)×Q(x)P(x)×Q(x)P(x)\times Q(x)xN−1xN−1x^{N-1}x2N−2x2N−2x^{2N-2}Θ(N∗log(N))Θ(N∗log⁡(N))\Theta(N*\log (N))Θ(log(N))Θ(log⁡(N))Θ(\log (N)) ただし、新しい数値が受信されるたびに加重和を効率的に計算する必要があるため、これは前述の問題の解決策ではありません。計算を遅らせることはできません。

1
Ukkonenのアルゴリズムの実行時間はアルファベットサイズにどのように依存しますか?
Ukkonenのアルゴリズムの漸近的な実行時間、おそらく線形(?)時間でサフィックスツリーを構築するための最も一般的なアルゴリズムの問題に関心があります。 これは、ダンガスフィールドによる本「ストリング、ツリー、シーケンスのアルゴリズム」からの引用です(セクション6.5.1)。 "... Aho-Corasick、Weiner、Ukkonen、およびMcCreightアルゴリズムはすべてスペースを必要とするか、O (m )時間境界を最小のO (m log m )およびOに置き換える必要があります(m log |Θ (m | Σ |)Θ(m|Σ|)\Theta(m|\Sigma|)O (m )O(m)O(m)O (m ログm )O(mログ⁡m)O(m \log m) "。O (m ログ| Σ | )O(mログ⁡|Σ|)O(m \log|\Sigma|) [ mmmは文字列の長さ、はアルファベットのサイズ]ΣΣ\Sigma なぜそうなのか分かりません。 スペース:まあ、サイズ配列を使用してノードからの分岐を表す場合、実際、Θ (m | Σ |)スペース使用になります。ただし、私の知る限り、ハッシュテーブル(Pythonの辞書など)を使用してブランチを保存することもできます。その後、O (1 )の子ノードにアクセスできる一方で、すべてのハッシュテーブルにΘ (m )ポインターのみを格納します(ツリーにはΘ (m )エッジがあるため)。Θ (| Σ |)Θ(|Σ|)\Theta(|\Sigma|)Θ (m | Σ …


1
配列の初期化を保存する
私は最近、初期化する必要のない配列を持つことができる、つまり、各メンバーをデフォルト値に設定しようとする時間を費やすことなく使用できることを読みました。つまり、初期化せずにデフォルト値で初期化されたかのように配列の使用を開始できます。(申し訳ありませんが、これをどこで読んだか覚えていません)。 たとえば、なぜそれが驚くべきことなのかについて: 範囲の整数の最悪のケースハッシュテーブル(各挿入/削除/検索用)をモデル化しようとしているとします 。O(1)O(1)\mathcal{O}(1)[1,n2][1,n2][1, n^2] サイズビットの配列を割り当て、個々のビットを使用してハッシュテーブル内の整数の存在を表すことができます。注:メモリの割り当てはO(1 )時間と見なされます。n2n2n^2O(1)O(1)\mathcal{O}(1) これで、この配列をまったく初期化する必要がなかった場合、このハッシュテーブルでの操作のシーケンスは、最悪の場合O(n )になります。nnnO(n)O(n)\mathcal{O}(n) したがって、実際には、「完全な」ハッシュ実装があります。これは、操作に対して Θ (n 2)スペースを使用しますが、O(n )時間で実行されます。nnnΘ(n2)Θ(n2)\Theta(n^2)O(n)O(n)\mathcal{O}(n) 通常、ランタイムは少なくともスペース使用量と同じくらい悪いことが予想されます! 注:上記の例は、スパースセットまたはスパースマトリックスの実装に使用される可能性があるため、理論的に興味深いだけではありません。 質問は次のとおりです。 初期化ステップをスキップできるデータ構造のような配列を持つことはどのように可能ですか?

4
セット交差点のデータ構造?
次の操作をサポートするセットの集合を保持するデータ構造はありますか?準線形の実行時間はありがたいですか? 空のセットを初期化します。 セットに要素を追加します。 2つのセットを指定して、それらが交差するかどうかを報告します。


2
垂直方向の可視性問題のための効率的なアルゴリズム
1つの問題を考えると、次のタスクを解決する効率的なアルゴリズムを作成する必要があることに気付きました。 問題:辺が軸に平行な辺 2次元の正方形の箱が与えられます。頂上から見ることができます。ただし、水平セグメントもあります。各セグメントには整数座標()および()があり、ポイントおよび(下の写真)。m個のY 0 ≤ Y ≤ N X 0 ≤ X 1 &lt; X 2 ≤ N (X 1、Y )、 (X 2、Y )nnnmmmyyy0≤y≤n0≤y≤n0 \le y \le nxxx0≤x1&lt;x2≤n0≤x1&lt;x2≤n0 \le x_1 < x_2 \le n(x1,y)(x1,y)(x_1,y)(x2,y)(x2,y)(x_2,y) ボックスの上部にある各ユニットセグメントについて、このセグメントを覗いた場合にボックス内をどのくらい深く見ることができるかを知りたいと思います。 正式には、場合、。x∈{0,…,n−1}x∈{0,…,n−1}x \in \{0,\dots,n-1\}maxi: [x,x+1]⊆[x1,i,x2,i]yimaxi: [x,x+1]⊆[x1,i,x2,i]yi\max_{i:\ [x,x+1]\subseteq[x_{1,i},x_{2,i}]} y_i 例:次の図のようにn=9n=9n=9およびm=7m=7m=7セグメントがある場合、結果は(5,5,5,3,8,3,7,8,7)(5,5,5,3,8,3,7,8,7)(5, 5, 5, 3, 8, 3, 7, 8, …

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