|
|
1.1 root 1: (* Copyright 1989 by AT&T Bell Laboratories *)
2: signature UNIONFIND =
3: sig
4: exception Union
5: val new : (int -> bool) ->
6: {union: int * int -> int,
7: find : int -> int}
8: end
9:
10:
11: structure Unionfind : UNIONFIND =
12: struct
13: exception Union
14: fun new (fixed) =
15: let open Intmap (* locally rebinding new, of course! *)
16: exception UnionM and UnionN
17: val m = new(32, UnionM) : int intmap
18: and n = new(32, UnionN) : int intmap
19: fun find x =
20: let val z = find(map m x)
21: in add m (x,z); z
22: end
23: handle UnionM => x
24: fun union (x,y) =
25: let val x' = find x and y' = find y
26: val xn = map n x' handle UnionN => 1
27: and yn = map n y' handle UnionN => 1
28: in if x' <> y'
29: then if fixed(x')
30: then if fixed(y')
31: then raise Union
32: else (add m (y', x'); add n (x',xn+yn); x')
33: else if fixed(y')
34: then (add m (x', y'); add n (y',xn+yn); y')
35: else if xn < yn
36: then (add m (x', y'); add n (y',xn+yn); y')
37: else (add m (y', x'); add n (x',xn+yn); x')
38: else x'
39: end
40: in {union=union, find=find}
41: end
42: end
43:
44:
45: signature SIBLINGS =
46: sig
47: type 't siblingClass
48: val new : (int -> bool) -> '1t siblingClass
49: (* assoc(i,x) must be called for any element i before
50: i is used as an argument to union or find or getassoc *)
51: end
52:
53:
54: structure Siblings : SIBLINGS =
55: struct
56: type 't siblingClass =
57: {assoc : int * 't -> unit,
58: union : int * int -> int,
59: find : int -> int,
60: getassoc : int -> 't list}
61: fun new(fixed: int -> bool) : '1t siblingClass =
62: let val {union = uni, find = find} = Unionfind.new(fixed)
63: exception UnionA
64: val a = Intmap.new(32, UnionA) : ('1t * int list) Intmap.intmap
65: val add = Intmap.add a
66: val map = Intmap.map a
67: fun assoc (i,x) =
68: let val (_,l) = map i handle UnionA => (x,nil)
69: in add (i,(x,l))
70: end
71: fun join(i,j) =
72: let val (x,l) = map j
73: in add (j,(x,i::l)); j
74: end
75: fun union (i,j) =
76: let val i' = find i and j' = find j
77: in if i' = j' then i'
78: else let val k = uni(i',j')
79: in if k=i' then join(j',k) else join(i',k)
80: end
81: end
82: fun get(i,l) =
83: let fun f (a::b) = get(a,f(b)) | f nil = l
84: val (x,r) = map i
85: in x::f(r)
86: end
87: fun getassoc i = get(find i,nil)
88: in {assoc=assoc, union=union, find=find, getassoc=getassoc}
89: end
90: end (* structure Siblings *)
91:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.