ocaml中优先级队列的功能

时间:2013-06-12 23:09:26

标签: ocaml priority-queue

ocaml中是否有一个库可以创建优先级队列并处理它?<​​/ p>

我检查了这个“http://holgerarnold.net/software/ocaml/doc/base/PriorityQueue.Make.html” 但它没有任何关于如何使用这些命令的例子。

3 个答案:

答案 0 :(得分:6)

OCaml Batteries包含名为BatHeap的模块中的多态优先级队列。您可以通过向空堆添加元素来使用它,依此类推。

Jane Stree Core在名为Heap的模块中有一个看起来更漂亮的优先级队列。

<强>更新

Jane Stree Core的堆真的很花哨。描述它的一种方法是堆有两个接口。第一个接口是有序值的集合,其最小元素可以在恒定时间内定位并在日志时间中删除。第二个接口将堆视为容器的集合(“堆元素”),其中包含有序值。如果您愿意明确地处理这些容器,可以更快地执行一些堆操作。

这是一个非常简单的示例,它使用堆(第一个接口)对列表进行排序:

let heapsort l =
    let heap = Core.Std.Heap.create compare in
    List.iter (fun x -> ignore (Core.Std.Heap.push heap x)) l;
    let rec extract () =
        match Core.Std.Heap.pop heap with
        | None -> []
        | Some x -> x :: extract ()
    in
    extract ()

(这段代码有点人为;它只是展示了如何将值放入堆中并将它们取回。)

以下是运行此代码的示例(在具有Core支持的OCaml顶层中):

# #use "sort.ml";;
val heapsort : 'a list -> 'a list = <fun>
# heapsort [3;1;4;1;5;9];;
- : int list = [1; 1; 3; 4; 5; 9]
# 

答案 1 :(得分:6)

OCaml手册的The module system章节以实现优先级队列的代码示例开头。这是我优先队列的首选实现,因为整个实现适合25行,所以很容易使用和理解。

答案 2 :(得分:5)

这是一个稍微大一点的Core堆教程。

open Core.Std

(* A heap only expects a comparsion function on its elements. Use
  polymorphic compare if you just want something tham makes sense most
  of the time *)

let pq = Heap.create compare

let reverse_pq = Heap.create ~min_size:10 (Fn.flip compare)

(* The optional min size argument is there for optimization purposes. If you
   know that your heap will grow past a certain size you can allocate the array
   of that size in advance to save copying/resizing later on since the heap is
   array based *)

let () = 
  let random_list = List.init 10 ~f:(fun _ -> Random.int 10) in
  (* core wraps values inserted into the heap in the type 'el heap_el
    where 'el is the type of elements in your heap *)
  let heap_el = Heap.push pq (Random.int 10) in
  (* this gives you O(1) existence check in the heap: *)
  let x = Heap.heap_el_mem pq heap_el in (* true in O(1) *)
  let value_in_el = Heap.heap_el_get_el heap_el in
  (* now standard heap stuff, insert a list into a heap *)
  random_list |> List.iter ~f:(Fn.compose ignore (Heap.push pq));
  (* now drain the heap and get a list in sorted order, for reverse
  order you'd us reverse_pq *)
  let sorted_list = 
    let rec loop acc =
      match Heap.pop pq with
      | None -> acc
      | Some e -> loop (e::acc)
    in loop [] in
  printf "Sorted: %s\n" 
    (Sexp.to_string_hum (List.sexp_of_t Int.sexp_of_t sorted_list))

不要犹豫使用Core。它会让你的OCaml更加愉快。欢迎提出更多问题。