PFDS 10.2.2 heaps with efficient merging

405 views
338 views

Published on

Purely Functional Data Structures

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
405
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

PFDS 10.2.2 heaps with efficient merging

  1. 1. PFDS #11 復習 10.2.2 Heaps With Efficient Merging @yuga 2012-11-08 (初版) 2012-11-10 (2版) 2012-11-30 (3版)Copyright © 2012 yuga 1
  2. 2. 動機 HeapをO(1)でマージしたいよ!Copyright © 2012 yuga 2
  3. 3. Heapってなに? こんなの。 HEAP : module type HEAP = sig module Elem : ORDERED type heap val empty : heap val isEmpty : heap -> bool val insert : Elem.t * heap -> heap val merge : heap * heap -> heap val findMin : heap -> Elem.t val deleteMin : heap -> heap endCopyright © 2012 yuga 3
  4. 4. 解決の方針 HeapをO(1)でマージしたいなら HeapをHeapで管理すればいいじゃない! 一方のHeap(BootStrapped type)の内部Heap(Primitive type)に もう一方のHeap(BootStrapped type)をそのまま入れる  BootStrapped type BootStrappedHeap  Primitive type これまでに登場したやつ BootStrappedHeap同士の大小比較はルートノードで判定するCopyright © 2012 yuga 4
  5. 5. 図解: 解決の方針 絵にすると(ここでは例として Primitive type に BinomialHeap を使用) BinomialHeap の状態 BinomialHeap の状態 2 3 9 6 4 7 5 4 9 6 merge 5 7 8 BootStrappedHeap BinomialHeapCopyright © 2012 yuga 5
  6. 6. 図解: 解決の方針 merge結果 2 BinomialHeap の状態 BootStrappedHeap 同士の大小比較は 3 ルートノードの値で判定 3 4 6 9 7 5 4 6 9 5 7Copyright © 2012 yuga 6
  7. 7. 実行時間 これまでに登場したheapのだいたいの性能 insert / findMin : O(1) merge / deleteMin : O(log n) … Worst-Case だったり Amortized だったり それらを用いて作ると BootStrappedHeap: findMin は Primitive type に関係ない ⇒ O(1) insert / merge は Primitive type の insert に依存 ⇒ O(1) deleteMin は Primitive type の findMin / deleteMin に依存 ⇒ O(log n) … Worst-Case timeかどうかはPrimitive typeに依存Copyright © 2012 yuga 7
  8. 8. 実装 そんなわけでこれまでに登場したHeapを使って Heapを作ります。  本に載ってるコードは、例によって実際にはコンパイルが通らない SMLコード  本文はその意図するところの説明に費やされている  これをOCamlで動くものにかえるぜCopyright © 2012 yuga 8
  9. 9. 難しいOCaml OCamlのモジュール難しい orz https://twitter.com/camloeba/status/265702576954171392Copyright © 2012 yuga 9
  10. 10. 実装: OCamlでの完成形 open Ordered;; open Heap;; module BootStrappedHeap = functor (MakeH : functor (Element : ORDERED) -> HEAP with module Elem = Element) -> functor (Element : ORDERED) -> struct module Elem = Element exception Empty module rec BootStrappedElem : sig 最後 functor が HEAP を返すように type t = E | H of Elem.t * PrimH.heap 型を明示したいけど書けない include ORDERED with type t := t もっと別の書き方もある?? end = struct type t = E 追記: あった => P13へ | H of Elem.t * PrimH.heap let eq = function (* snip *) end and PrimH : HEAP with module Elem := BootStrappedElem = MakeH (BootStrappedElem) include BootStrappedElem type heap = t let empty = E let isEmpty = function (* snip *) end open ScheduledBinomialHeap;; module IntBootStrappedHeap : HEAP with module Elem = Int = BootStrappedHeap (ScheduledBinomialHeap) (Int) Ocamlで実際に動かしてみたやつ: https://github.com/yuga/readpfds/blob/master/OCaml/bootStrappedHeap.mlCopyright © 2012 yuga 10
  11. 11. 実装: メモ #1 (MakeHについて) open Ordered;; open Heap;; module BootStrappedHeap = functor (MakeH : functor (Element : ORDERED) -> HEAP with module Elem = Element) -> functor (Element : ORDERED) -> struct module Elem = Element exception Empty module rec BootStrappedElem : sig type t = E | H of Elem.t * PrimH.heap include ORDERED with type t := t MakeH には ORDERED型のパラメタを受け取りHEAP を返すfunctorである end = struct type t = E ScheduledBinomialHeap がアサインされる | H of Elem.t * PrimH.heap 結果、MakeH により BootStrappedElem 型の要素を持つ HEAP が作られる let eq = function (* snip *) end and PrimH : HEAP with module Elem := BootStrappedElem = MakeH (BootStrappedElem) include BootStrappedElem type heap = t let empty = E ScheduledBinomialHeap の型は let isEmpty = function (* snip *) functor (Element : ORDERED) -> HEAP with module Elem = Element end open ScheduledBinomialHeap;; module IntBootStrappedHeap : HEAP with module Elem = Int = BootStrappedHeap (ScheduledBinomialHeap) (Int)Copyright © 2012 yuga 11
  12. 12. 実装: メモ #2 open Ordered;; open Heap;; module BootStrappedHeap = functor (MakeH : functor (Element : ORDERED) -> HEAP with module Elem = Element) -> functor (Element : ORDERED) -> struct Element には Int がアサインされる module Elem = Element exception Empty HEAP は要素のシグネチャを Elem で持つ module rec BootStrappedElem : sig type t = E Elem.t の型は int になる | H of Elem.t * PrimH.heap PrimH は MakeH により作られる HEAP include ORDERED with type t := t end = struct BootStrappedElem と PrimH は相互依存するので rec 指定 type t = E | H of Elem.t * PrimH.heap BootStrappedElem は HEAP に格納される要素になるので、 let eq = function (* snip *) ORDERED のシグネチャを実装する end and PrimH : HEAP with module Elem := BootStrappedElem = MakeH (BootStrappedElem) include BootStrappedElem BootStrappedHeap は、BootStrappedElem 内で定義した型 t が type heap = t 自分の型 heap でもあるので、include で自分の中に展開し heap にアサイン let empty = E let isEmpty = function BootStrappedHeap が ORDERED のシグネチャを持つ (* snip *) end Int を要素として格納するよう指定 open ScheduledBinomialHeap;; module IntBootStrappedHeap : HEAP with module Elem = Int = BootStrappedHeap (ScheduledBinomialHeap) (Int)Copyright © 2012 yuga 12
  13. 13. 実装: OCamlでの完成形(その2) open Ordered;; open Heap;; module BootStrappedHeap (MakeH : functor (Element : ORDERED) -> HEAP with module Elem = Element) (Element : ORDERED) : (HEAP with module Elem = Element) = struct module Elem = Element exception Empty こう書くことができた module rec BootStrappedElem : sig type t = E | H of Elem.t * PrimH.heap include ORDERED with type t := t end = struct type t = E | H of Elem.t * PrimH.heap let eq = function (* snip *) end and PrimH : HEAP with module Elem := BootStrappedElem = MakeH (BootStrappedElem) include BootStrappedElem type heap = t let empty = E let isEmpty = function (* snip *) end open ScheduledBinomialHeap;; module IntBootStrappedHeap : HEAP with module Elem = Int = BootStrappedHeap (ScheduledBinomialHeap) (Int) Ocamlで実際に動かしてみたやつ: https://github.com/yuga/readpfds/blob/master/OCaml/bootStrappedHeap.mlCopyright © 2012 yuga 13

×