岡崎以来の純粋に機能的なデータ構造の新機能


563

Chris Okasakiの1998年の本「純粋に機能的なデータ構造」以来、私はあまりにも多くの新しいエキサイティングな純粋に機能的なデータ構造が登場するのを見ていません。ほんの数例を挙げます。

  • IntMap(1998年に岡崎によって発明されましたが、その本にはありません)
  • フィンガーツリー(およびモノイドに対する一般化)

「入れ子型」や「一般化代数データ型」を使用してツリーの不変式を確保するなど、既知のデータ構造を実装する興味深い方法もいくつかあります。

この分野で1998年以降に登場した他の新しいアイデアはどれですか?


20
いい質問です。私はこれについて生徒に尋ねましたが、答えがわかりませんでした。
スレシュヴェンカト

ここでは問題ありませんが、Stack Overflowでより良い答えが得られる場合があります。そこで質問する場合は、ここでの議論に必ずリンクしてください。
チャールズ・スチュワート

3
Haskell Redditがこれを見てきたので、そこからいくつかの良い答えがありますが、素晴らしい質問があります。岡崎の本の中途半端だったので、自分も同じことを考えていた。+1
ロバートマサイオリ


回答:


553

1998年以降に公開された新しい純粋に機能的なデータ構造:

  • 2001:Ideal Hash Treesおよびその2000年の前身、Phil BagwellによるFast And Space Efficient Trie Searches:Clojureの標準ライブラリの基本的な構成要素として使用されているようです。

  • 2001:Ralf HinzeによるPriority Search Queuesの簡単な実装テクニック:この重要なデータ構造を実装するための本当にシンプルで美しいテクニック(たとえば、ダイクストラアルゴリズムで有用)。「ビューパターン」を多用するため、実装は特に美しく、読みやすくなっています。

  • 2002:片側フレキシブルアレイのブートストラップ、Ralf Hinze著:Okasakiのランダムアクセスリストに似ていますがcons、インデックスとインデックスの作成の時間的トレードオフを変更するように調整できます。

  • 2003:Radu MihaescuとRobert Tarjanによる新しいcatenableとnon-catenable deques:岡崎が引用する古い作品(KaplanとTarjanによる)の新しいテイク(Kaplan&Tarjanの作品の最新バージョンは2000年に公開されました)。このバージョンはいくつかの点で単純です。

  • 2005:Maxiphobic heaps(コード)、Chris Okasaki著:より効率的な新しい構造としてではなく、優先キューを教える方法として発表されました。

  • 2006:純粋に機能的な最悪の場合の一定時間ケータブルソートリスト、GerthStøltingBrodal、Christos Makris、Kostas Tsichlas著:O(lg n)挿入、検索、削除およびOを使用して構造を示すことにより、カプランとタージャンの顕著な質問に答えます(1)連結。

  • 2008:Erik D. Demaine、Stefan Langerman、およびEric Priceによる、効率的なバージョン管理のためのConfluently Persistent Tries:葉の近くで効率的なナビゲーションと変更を行うためのいくつかのデータ構造を提示します。いくつかは純粋に機能的です。他の人は実際にディーツらによる長年のデータ構造を改善しています。完全に永続的な(ただし、コンフルエントに永続的でも純粋に機能的でもない)アレイの場合。このペーパーでは、「動的ツリー」と呼ばれることもある純粋に機能的なリンクカットツリーも紹介します。

  • 2010:Matt Mightによる赤黒木の新しい純粋に機能的な削除アルゴリズム:岡崎の赤黒木の挿入アルゴリズムのように、これは新しいデータ構造またはデータ構造の新しい操作ではなく、新しい、より簡単な方法です既知の操作を記述します。

  • 2012:RRB-Trees:Efficient Immutable Vectors、Phil BagwellおよびTiark Rompf:Hash Array Mapped Triesの拡張、不変ベクトル連結、挿入時、およびO(lg n)時間での分割のサポート、インデックスの更新、更新、および元の不変ベクトルの挿入速度。

1997年に知られていますが、岡崎の本では説明されていません。

  • バランスの取れた検索ツリーの他の多くのスタイル。AVL、brother、rank-balanced、bounded-balance、および他の多くのバランスの取れた検索ツリーは、パスコピーによって純粋に機能的に実装できます(および実装されています)。おそらく、特に言及するに値するものは次のとおりです。

    • Biased Search Trees、Samuel W. Bent、Daniel D. Sleator、Robert E. Tarjan:Brodalらの2006年の論文とDemaineらの2008年の論文の重要な要素。
  • MartínEscardóによる、高速で徹底的な検索を許可する無限集合:おそらくデータ構造そのものではありません。

  • Chris OkasakiによるBraun Treesの3つのアルゴリズム:Braun treesは、最悪の場合のO(lg n)で多くのスタック操作を提供します。この境界は他の多くのデータ構造によって凌edされますが、ブラウンツリーのcons2番目の引数には操作が遅延しているため、他の構造では不可能な方法で無限スタックとして使用できます。

  • 緩和された最小-最大ヒープ:マージ可能なダブルエンド優先キューKDヒープ:効率的な多次元優先キュー、Yuzheng DingおよびMark Allen Weissによる:これらは純粋に機能しますが、これは論文では説明されていません。達成された時間制限は、フィンガーツリー(Hinze&PatersonまたはKaplan&Tarjan)をk次元の優先キューとして使用することで達成できる時間制限よりも優れているとは思いませんが、Ding&Weissの構造はより少ないスペースを使用すると思います。

  • GérardHuetのThe Zipper:他の多くのデータ構造(Hinze&Patersonの指の木など)で使用されている、これはデータ構造を裏返しにする方法です。

  • 差分リストは、通常のconsリストへのO(n)変換を伴うO(1)catenable リストです。それらはPrologコミュニティで古くから知られており、そこでは通常のconsリストへのO(1)変換があります。O(1)変換は従来の関数型プログラミングでは不可能と思われますが、POPL '98のMinamide のホール抽象化では、純粋な関数型プログラミング内でO(1)の追加とO(1)の変換を許可する方法について説明しています。関数のクロージャに基づいた差分リストの通常の関数型プログラミング実装とは異なり、穴の抽象化はProlog差分リストと本質的に同じです(使用と実装の両方)。しかし、これに気づいた人は何年もの間だったようです南出のレビュアーの一人

  • O(n)Θ(nlgn)Θ(nlgn)Θ(lg2n)

ほぼ機能的なデータ構造、岡崎の本の前、最中、後:

  • O(m)mO(lglgn)

  • 1989:Cecilia R. AragonとRaimund Seidelによるランダム化された検索ツリー:これらは、Treatsを使用したFast Set Operationsの Guy E. BlellochとMargaret Reid-Miller、 およびFunctional Set Operationsの Dan BlandfordとGuy Blelloch による純粋に機能的な設定で議論されましたトレジャーコード)。それらは、純粋に機能的なフィンガーツリーとバイアス検索ツリーのすべての操作を提供しますが、ランダム性のソースを必要とするため、純粋に機能的ではありません。また、これは、操作の時間を計り、長い操作を繰り返すことができる敵を想定して、トレジャー上の操作の時間の複雑さを無効にする可能性があります。(これは、永続的な設定では命令型の償却引数が有効ではない理由と同じですが、ストップウォッチを持つ敵が必要です)

  • 1997:スキップツリー、同時アプローチのスキップリストの代替データ構造、Xavier Messeguer、スキップリストとバイナリ検索ツリーの双対性の探索、ブライアンC.ディーンとザカリーH.ジョーンズ:スキップリストは純粋ではありません機能的ですが、機能的にツリーとして実装できます。トレジャーと同様に、ランダムビットのソースが必要です。(スキップリストを確定的にすることは可能ですが、それらをツリーに変換した後は、2〜3本のツリーを見る別の方法だと思います。)

  • 1998:岡崎の本の償却された構造のすべて!岡崎は、以前は互換性がないと考えられていた償却と機能データ構造を混合するこの新しい方法を発明しました。これはメモ化に依存します。メモ化は、カプランとタージャンが時々言及したように、実際には副作用です。場合によっては(パフォーマンス上の理由でSSD上のPFDSなど)、これは不適切な場合があります。

  • 1998:Haim Kaplan、Chris Okasaki、Robert E. TarjanによるSimple Confluently Persistent Catenable Lists:ボンネットの下の修正を使用して、償却されたO(1)catable dequeを提供し、以前と同じインターフェースを提供します(純粋に機能しますが、メモ付きです) )岡崎の本に登場するバージョン。KaplanとTarjanは、以前は純粋に機能的なO(1)ワーストケース構造を作成していましたが、かなり複雑です。

  • 2007:このページの別の回答で述べたように、Sylvain ConchonとJean-ChristopheFilliâtreによる半永続的なデータ構造永続的なユニオン検索

岡崎の本の前、最中、後の機能データ構造を検証するための手法:

岡崎の本では説明されていないが、純粋に機能的なデータ構造に関連する命令型のデータ構造または分析:

  • ソフトヒープ:最適なエラーレートを備えた近似優先度キュー、 Bernard Chazelle氏:このデータ構造は配列を使用していないため、最初に#haskell IRCチャネルその後のStack Overflowユーザーを誘惑しましたがdelete、o(lg n)に含まれています、通常は機能的な設定では不可能であり、命令的な償却分析は純粋に機能的な設定では有効ではありません。

  • O(1)フィンガー更新によるバランスの取れたバイナリ検索ツリーデータ構造の永続化永続的な更新のみをO(1)スペースを必要とするように、ジェームズ・Rドリスコル、ニールサーナク、ダニエルD. Sleator、およびロバートE. Tarjanは赤黒木のノードをグループ化するための方法を提示します。Tarjan、Kaplan、およびMihaescuによって設計された純粋に機能的な両端キューおよびフィンガーツリーはすべて、非常に類似したグループ化手法を使用して、両端でO(1)更新を許可します。Athanasios K. Tsakalidisによるローカライズ検索用のAVLツリーも同様に機能します。

  • より高速なペアリングヒープまたはペアリングヒープのためのより良い範囲:Okasakiの本が出版されたので、不可欠ペアリングヒープのいくつかの新しい分析を含む、登場している(nはログログ)Oとのペアリングヒープコストを下げるアムルElmasryでとペアリングヒープの最終的な分析に向けてによってセス・ペティ。この作業の一部を岡崎の怠laなペアリングヒープに適用することは可能かもしれません。

  • 決定論的偏りのある指のツリーBiased Skip Listsでは、Amitabha Bagchi、Adam L. Buchsbaum、およびMichael T. Goodrichによる、決定論的偏りのあるスキップリストの設計が提示されています。上記のスキップリスト/ツリー変換により、決定論的なバイアスのある検索ツリーを作成できる場合があります。その後、Mergeable DictionariesでJohn IaconoとÖzgürÖzkanによって記述されたフィンガーバイアススキップリストは、バイアススキップツリーで可能になります。バイアスのかかった指の木は、Demaine等によって提案されています。試行における指の更新の時間と空間の限界を減らす方法として、純粋に機能的な試行に関する論文(上記参照)で。

  • 文字列Bツリー:外部メモリでの文字列検索の新しいデータ構造とその応用 Paolo FerraginaとRoberto Grossiによる試みは、試行とBツリーの利点を組み合わせたよく研究されたデータ構造です。


5
この回答の「コミュニティwiki」ボックスをチェックしたことを覚えていません。元に戻す方法はありますか?
jbapple

7
@jbapple:一定数の編集を行うと、すべての投稿がコミュニティWikiになります。それはそこの印象的な徹底的なレビューです。ありがとうございました。
フィルミラー

29
素晴らしいリスト!岡崎が第2版を出版することを願っています。
ラドゥグリゴール

4
Isabelle / HOLは、SML、OCaml、Haskell、Scalaのコードを生成できることに注意してください。Haskabelleツールは、HaskellをIsabelle / HOLにインポートすることもできます。
マカリウス

2
「プログラム抽出」の用語はCoqの1つです。建設的な証明を取り、そこから実行可能なプログラムを作成し、いくつかのことを取り除きます。Isabelleでは、これは「コード生成」と呼ばれ、HOL 仕様を証明ではなく擬似コードとして使用して、異なる動作をします。Berghoferによると、Isabelle / HOLでのプルーフ抽出はCoqと同様に機能しますが、最近ではほとんど使用されません。
マカリウス

63

すでに作成されたすばらしいメモに、Zippersを追加します。

ヒュー、ジェラード。「Functional Pearl:The Zipper」Journal of Functional Programming 7(5):549-554、1997年9月。

ウィキペディア:Zipper(データ構造)


4
ジッパーは素晴らしいです。多くのユースケースのために、彼らは、ツリーベースの表現は、それが少し複雑になるだろうそれ以外の場合は、データの多くの種類のための「右」の選択肢になることを許可
カーターTazio Schonwaldの

1
XML操作のためのそれらの使用の例:anti-xml.org/zippers.html
機械カタツムリ

40

うわー、永続的なUNION-FIND!ありがとう!
jkff

3
まあ、ちょっと...記事を見てください。
ラドゥグリゴール

1
...または、あなたが好むならば、(マット・パーキンソンで)いくつかのコードを参照してくださいgithub.com/septract/jstar/blob/master/src/utils/...
ラドゥグリゴール

5
今では、「種類」のコメントに賛成があった理由がわかりました。永続性をほとんど排他的に使用するか、常にバックトラックする場合にのみ、優れたパフォーマンスが得られます。「新しい」バージョンと「古い」バージョンの両方を頻繁に使用する場合は、手間がかかります。しかし、クールなルート変更のアイデア。
jkff


20

マクブライド版のジッパーをデータ型の派生物として追加します。


私はそのようなものが大好きです。デリバティブが変化率を見つけることとは大きく異なるアプリケーションを持っているのはとてもクールです!
SamB

3
SamB、正規表現の派生物にも興味があるかもしれません(それらについてまだ知らなかった場合)。
jbapple


14

レンジマップ

これは特殊なデータ構造ですが、Martin ErwigのDIETの代替として使用でき、プロパティがわずかに異なるため、少なくとも1つの既存のデータ構造と比較する必要があります。DIET自体は1998年のJFPの記事で説明されていたため、おそらく純粋に機能的なデータ構造には含まれていません。


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