Changed return type of [repr]. Added [mem].
This commit is contained in:
parent
43eb5dd13f
commit
3fc434d0d7
|
@ -43,13 +43,19 @@ module type S =
|
||||||
|
|
||||||
(** {1 Projection} *)
|
(** {1 Projection} *)
|
||||||
|
|
||||||
(** The value of the call [repr i p] is [Some j], if the item [i]
|
(** The value of the call [repr i p] is [j] if the item [i] is in
|
||||||
is in the partition [p] and its representative is [j]. If [i]
|
the partition [p] and its representative is [j]. If [i] is not
|
||||||
is not in [p], then the value is [None]. *)
|
in [p], then the value is [i]. *)
|
||||||
val repr : item -> partition -> item option
|
val repr : item -> partition -> item
|
||||||
|
|
||||||
(** The side-effect of the call [print p] is the printing of the
|
(** The value of the call [mem i p] is [Some j] if the item [i] is
|
||||||
partition [p] on a buffer, based on [Ord.to_string]. *)
|
in the partition [p] and its representative is [j]. If [i] is
|
||||||
|
not in [p], then the value is [None]. *)
|
||||||
|
val mem : item -> partition -> item option
|
||||||
|
|
||||||
|
(** The call [print p] is a value of type [Buffer.t] containing
|
||||||
|
strings denoting the partition [p], based on
|
||||||
|
[Ord.to_string]. *)
|
||||||
val print : partition -> Buffer.t
|
val print : partition -> Buffer.t
|
||||||
|
|
||||||
(** {1 Predicates} *)
|
(** {1 Predicates} *)
|
||||||
|
@ -58,7 +64,8 @@ module type S =
|
||||||
items [i] and [j] belong to the same equivalence class in the
|
items [i] and [j] belong to the same equivalence class in the
|
||||||
partition [p], that is, [i] and [j] have the same
|
partition [p], that is, [i] and [j] have the same
|
||||||
representative. In particular, if either [i] or [j] do not
|
representative. In particular, if either [i] or [j] do not
|
||||||
belong to [p], the value of [is_equiv i j p] is [false].*)
|
belong to [p], the value of [is_equiv i j p] is [false]. See
|
||||||
|
[mem] above. *)
|
||||||
val is_equiv : item -> item -> partition -> bool
|
val is_equiv : item -> item -> partition -> bool
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,12 @@
|
||||||
|
|
||||||
module Make (Item: Partition.Item) =
|
module Make (Item: Partition.Item) =
|
||||||
struct
|
struct
|
||||||
|
|
||||||
type item = Item.t
|
type item = Item.t
|
||||||
|
|
||||||
let equal i j = Item.compare i j = 0
|
let equal i j = Item.compare i j = 0
|
||||||
|
|
||||||
module ItemMap = Map.Make (Item)
|
module ItemMap = Map.Make (Item)
|
||||||
|
|
||||||
type height = int
|
|
||||||
|
|
||||||
type partition = item ItemMap.t
|
type partition = item ItemMap.t
|
||||||
type t = partition
|
type t = partition
|
||||||
|
|
||||||
|
@ -23,14 +20,14 @@ module Make (Item: Partition.Item) =
|
||||||
else repr parent partition
|
else repr parent partition
|
||||||
|
|
||||||
let is_equiv (i: item) (j: item) (p: partition) : bool =
|
let is_equiv (i: item) (j: item) (p: partition) : bool =
|
||||||
try equal (repr i p) (repr j p) with
|
try equal (repr i p) (repr j p) with Not_found -> false
|
||||||
Not_found -> false
|
|
||||||
|
|
||||||
let get_or_set (i: item) (p: partition) : item * partition =
|
let get_or_set (i: item) (p: partition) : item * partition =
|
||||||
try repr i p, p with Not_found -> i, ItemMap.add i i p
|
try repr i p, p with Not_found -> i, ItemMap.add i i p
|
||||||
|
|
||||||
let repr item partition =
|
let mem i p = try Some (repr i p) with Not_found -> None
|
||||||
try Some (repr item partition) with Not_found -> None
|
|
||||||
|
let repr i p = try repr i p with Not_found -> i
|
||||||
|
|
||||||
let equiv (i: item) (j: item) (p: partition) : partition =
|
let equiv (i: item) (j: item) (p: partition) : partition =
|
||||||
let ri, p = get_or_set i p in
|
let ri, p = get_or_set i p in
|
||||||
|
@ -48,6 +45,5 @@ module Make (Item: Partition.Item) =
|
||||||
Printf.sprintf "%s -> %s\n"
|
Printf.sprintf "%s -> %s\n"
|
||||||
(Item.to_string src) (Item.to_string dst)
|
(Item.to_string src) (Item.to_string dst)
|
||||||
in Buffer.add_string buffer link
|
in Buffer.add_string buffer link
|
||||||
in ItemMap.iter print p; buffer
|
in (ItemMap.iter print p; buffer)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(* Persistent implementation of Union/Find with height-balanced
|
(* Persistent implementation of Union/Find with height-balanced
|
||||||
forests and without path compression: O(n*log(n)).
|
forests and no path compression: O(n*log(n)).
|
||||||
|
|
||||||
In the definition of type [t], the height component is that of the
|
In the definition of type [t], the height component is that of the
|
||||||
source, that is, if [ItemMap.find i m = (j,h)], then [h] is the
|
source, that is, if [ItemMap.find i m = (j,h)], then [h] is the
|
||||||
|
@ -26,18 +26,18 @@ module Make (Item: Partition.Item) =
|
||||||
let j, _ as i' = ItemMap.find i p in
|
let j, _ as i' = ItemMap.find i p in
|
||||||
if equal i j then i' else seek j p
|
if equal i j then i' else seek j p
|
||||||
|
|
||||||
let repr item partition = fst (seek item partition)
|
let repr i p = fst (seek i p)
|
||||||
|
|
||||||
let is_equiv (i: item) (j: item) (p: partition) : bool =
|
let is_equiv (i: item) (j: item) (p: partition) : bool =
|
||||||
try equal (repr i p) (repr j p) with
|
try equal (repr i p) (repr j p) with Not_found -> false
|
||||||
Not_found -> false
|
|
||||||
|
|
||||||
let repr item partition =
|
|
||||||
try Some (repr item partition) with Not_found -> None
|
|
||||||
|
|
||||||
let get_or_set (i: item) (p: partition) =
|
let get_or_set (i: item) (p: partition) =
|
||||||
try seek i p, p with
|
try seek i p, p with
|
||||||
Not_found -> let i' = i,0 in (i', ItemMap.add i i' p)
|
Not_found -> let i' = i,0 in i', ItemMap.add i i' p
|
||||||
|
|
||||||
|
let mem i p = try Some (repr i p) with Not_found -> None
|
||||||
|
|
||||||
|
let repr i p = try repr i p with Not_found -> i
|
||||||
|
|
||||||
let equiv (i: item) (j: item) (p: partition) : partition =
|
let equiv (i: item) (j: item) (p: partition) : partition =
|
||||||
let (ri,hi), p = get_or_set i p in
|
let (ri,hi), p = get_or_set i p in
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(** Persistent implementation of the Union/Find algorithm with
|
(** Persistent implementation of the Union/Find algorithm with
|
||||||
height-balanced forests and without path compression. *)
|
height-balanced forests and no path compression. *)
|
||||||
|
|
||||||
module Make (Item: Partition.Item) =
|
module Make (Item: Partition.Item) =
|
||||||
struct
|
struct
|
||||||
|
@ -59,19 +59,20 @@ module Make (Item: Partition.Item) =
|
||||||
Root hi -> i,hi
|
Root hi -> i,hi
|
||||||
| Link (j,_) -> seek j p
|
| Link (j,_) -> seek j p
|
||||||
|
|
||||||
let repr item partition = fst (seek item partition)
|
let repr i p = fst (seek i p)
|
||||||
|
|
||||||
let is_equiv (i: item) (j: item) (p: partition) : bool =
|
let is_equiv (i: item) (j: item) (p: partition) : bool =
|
||||||
try equal (repr i p) (repr j p) with
|
try equal (repr i p) (repr j p) with
|
||||||
Not_found -> false
|
Not_found -> false
|
||||||
|
|
||||||
let repr item partition =
|
|
||||||
try Some (repr item partition) with Not_found -> None
|
|
||||||
|
|
||||||
let get_or_set (i: item) (p: partition) =
|
let get_or_set (i: item) (p: partition) =
|
||||||
try seek i p, p with
|
try seek i p, p with
|
||||||
Not_found -> let n = i,0 in (n, root n p)
|
Not_found -> let n = i,0 in (n, root n p)
|
||||||
|
|
||||||
|
let mem i p = try Some (repr i p) with Not_found -> None
|
||||||
|
|
||||||
|
let repr i p = try repr i p with Not_found -> i
|
||||||
|
|
||||||
let equiv (i: item) (j: item) (p: partition) : partition =
|
let equiv (i: item) (j: item) (p: partition) : partition =
|
||||||
let (ri,hi as ni), p = get_or_set i p in
|
let (ri,hi as ni), p = get_or_set i p in
|
||||||
let (rj,hj as nj), p = get_or_set j p in
|
let (rj,hj as nj), p = get_or_set j p in
|
||||||
|
|
|
@ -14,7 +14,11 @@ module Make (Item: Partition.Item) =
|
||||||
upwardly and otherwise is a link to another node. Those trees
|
upwardly and otherwise is a link to another node. Those trees
|
||||||
are height-balanced. The type [node] implements nodes in those
|
are height-balanced. The type [node] implements nodes in those
|
||||||
trees. *)
|
trees. *)
|
||||||
type node = {item: item; mutable height: int; mutable parent: node}
|
type node = {
|
||||||
|
item : item;
|
||||||
|
mutable height : int;
|
||||||
|
mutable parent : node
|
||||||
|
}
|
||||||
|
|
||||||
module ItemMap = Map.Make (Item)
|
module ItemMap = Map.Make (Item)
|
||||||
|
|
||||||
|
@ -39,21 +43,22 @@ module Make (Item: Partition.Item) =
|
||||||
if node.parent == node then node else find_root node.parent
|
if node.parent == node then node else find_root node.parent
|
||||||
in find_root (ItemMap.find i p)
|
in find_root (ItemMap.find i p)
|
||||||
|
|
||||||
let repr item partition = (seek item partition).item
|
let repr i p = (seek i p).item
|
||||||
|
|
||||||
let is_equiv (i: item) (j: item) (p: partition) : bool =
|
let is_equiv (i: item) (j: item) (p: partition) : bool =
|
||||||
try equal (repr i p) (repr j p) with
|
try equal (repr i p) (repr j p) with
|
||||||
Not_found -> false
|
Not_found -> false
|
||||||
|
|
||||||
let repr item partition =
|
|
||||||
try Some (repr item partition) with Not_found -> None
|
|
||||||
|
|
||||||
let get_or_set item (p: partition) =
|
let get_or_set item (p: partition) =
|
||||||
try seek item p, p with
|
try seek item p, p with
|
||||||
Not_found ->
|
Not_found ->
|
||||||
let rec loop = {item; height=0; parent=loop}
|
let rec loop = {item; height=0; parent=loop}
|
||||||
in loop, ItemMap.add item loop p
|
in loop, ItemMap.add item loop p
|
||||||
|
|
||||||
|
let mem i p = try Some (repr i p) with Not_found -> None
|
||||||
|
|
||||||
|
let repr i p = try repr i p with Not_found -> i
|
||||||
|
|
||||||
let link src dst = src.parent <- dst
|
let link src dst = src.parent <- dst
|
||||||
|
|
||||||
let equiv (i: item) (j: item) (p: partition) : partition =
|
let equiv (i: item) (j: item) (p: partition) : partition =
|
||||||
|
|
Loading…
Reference in New Issue
Block a user