Advertisement
Guest User

Untitled

a guest
Jan 9th, 2018
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 5.95 KB | None | 0 0
  1. (* Coder: Rafał Łyżwa
  2.  * Reviewer: Marek Żochowski *)
  3.  
  4. type ('k, 'v) map =
  5.   | Empty
  6.   | Node of ('k, 'v) map * 'k * 'v * ('k, 'v) map * int
  7.  
  8. type ('k, 'v) t =
  9.   {
  10.     cmp : 'k -> 'k -> int;
  11.     map : ('k, 'v) map;
  12.   }
  13.  
  14. let height = function
  15.   | Node (_, _, _, _, h) -> h
  16.   | Empty -> 0
  17.  
  18. let make l k v r = Node (l, k, v, r, max (height l) (height r) + 1)
  19.  
  20. let bal l k v r =
  21.   let hl = height l in
  22.   let hr = height r in
  23.   if hl > hr + 2 then
  24.     match l with
  25.     | Node (ll, lk, lv, lr, _) ->
  26.         if height ll >= height lr then make ll lk lv (make lr k v r)
  27.         else
  28.           (match lr with
  29.           | Node (lrl, lrk, lrv, lrr, _) ->
  30.               make (make ll lk lv lrl) lrk lrv (make lrr k v r)
  31.           | Empty -> assert false)
  32.     | Empty -> assert false
  33.   else if hr > hl + 2 then
  34.     match r with
  35.     | Node (rl, rk, rv, rr, _) ->
  36.         if height rr >= height rl then make (make l k v rl) rk rv rr
  37.         else
  38.           (match rl with
  39.           | Node (rll, rlk, rlv, rlr, _) ->
  40.               make (make l k v rll) rlk rlv (make rlr rk rv rr)
  41.           | Empty -> assert false)
  42.     | Empty -> assert false
  43.   else Node (l, k, v, r, max hl hr + 1)
  44.  
  45. let rec min_binding = function
  46.   | Node (Empty, k, v, _, _) -> k, v
  47.   | Node (l, _, _, _, _) -> min_binding l
  48.   | Empty -> raise Not_found
  49.  
  50. let rec remove_min_binding = function
  51.   | Node (Empty, _, _, r, _) -> r
  52.   | Node (l, k, v, r, _) -> bal (remove_min_binding l) k v r
  53.   | Empty -> invalid_arg "PMap.remove_min_binding"
  54.  
  55. let merge t1 t2 =
  56.   match t1, t2 with
  57.   | Empty, _ -> t2
  58.   | _, Empty -> t1
  59.   | _ ->
  60.       let k, v = min_binding t2 in
  61.       bal t1 k v (remove_min_binding t2)
  62.  
  63. let create cmp = { cmp = cmp; map = Empty }
  64. let empty = { cmp = compare; map = Empty }
  65.  
  66. let is_empty x =
  67.     x.map = Empty
  68.  
  69. let add x d { cmp = cmp; map = map } =
  70.   let rec loop = function
  71.     | Node (l, k, v, r, h) ->
  72.         let c = cmp x k in
  73.         if c = 0 then Node (l, x, d, r, h)
  74.         else if c < 0 then
  75.           let nl = loop l in
  76.           bal nl k v r
  77.         else
  78.           let nr = loop r in
  79.           bal l k v nr
  80.     | Empty -> Node (Empty, x, d, Empty, 1) in
  81.   { cmp = cmp; map = loop map }
  82.  
  83. let find x { cmp = cmp; map = map } =
  84.   let rec loop = function
  85.     | Node (l, k, v, r, _) ->
  86.         let c = cmp x k in
  87.         if c < 0 then loop l
  88.         else if c > 0 then loop r
  89.         else v
  90.     | Empty -> raise Not_found in
  91.   loop map
  92.  
  93. let remove x { cmp = cmp; map = map } =
  94.   let rec loop = function
  95.     | Node (l, k, v, r, _) ->
  96.         let c = cmp x k in
  97.         if c = 0 then merge l r else
  98.         if c < 0 then bal (loop l) k v r else bal l k v (loop r)
  99.     | Empty -> Empty in
  100.   { cmp = cmp; map = loop map }
  101.  
  102. let mem x { cmp = cmp; map = map } =
  103.   let rec loop = function
  104.     | Node (l, k, v, r, _) ->
  105.         let c = cmp x k in
  106.         c = 0 || loop (if c < 0 then l else r)
  107.     | Empty -> false in
  108.   loop map
  109.  
  110. let exists = mem
  111.  
  112. let iter f { map = map } =
  113.   let rec loop = function
  114.     | Empty -> ()
  115.     | Node (l, k, v, r, _) -> loop l; f k v; loop r in
  116.   loop map
  117.  
  118. let map f { cmp = cmp; map = map } =
  119.   let rec loop = function
  120.     | Empty -> Empty
  121.     | Node (l, k, v, r, h) ->
  122.       let l = loop l in
  123.       let r = loop r in
  124.       Node (l, k, f v, r, h) in
  125.   { cmp = cmp; map = loop map }
  126.  
  127. let mapi f { cmp = cmp; map = map } =
  128.   let rec loop = function
  129.     | Empty -> Empty
  130.     | Node (l, k, v, r, h) ->
  131.       let l = loop l in
  132.       let r = loop r in
  133.       Node (l, k, f k v, r, h) in
  134.   { cmp = cmp; map = loop map }
  135.  
  136. let fold f { cmp = cmp; map = map } acc =
  137.   let rec loop acc = function
  138.     | Empty -> acc
  139.     | Node (l, k, v, r, _) ->
  140.       loop (f v (loop acc l)) r in
  141.   loop acc map
  142.  
  143. let foldi f { cmp = cmp; map = map } acc =
  144.   let rec loop acc = function
  145.     | Empty -> acc
  146.     | Node (l, k, v, r, _) ->
  147.        loop (f k v (loop acc l)) r in
  148.   loop acc map
  149.  
  150. exception Cykliczne
  151.  
  152. let szukaj graf =
  153. (* mapa trzymająca stopnie wchodzące wierzchołków    *)
  154.   let stopien = ref empty in
  155. (* mapa trzymająca listy krawędzi wychodzących       *)
  156.   let krawedzie = ref empty in
  157. (* lista wierzchołków o zerowym stopniu wchodzącym   *)
  158.   let zerowe = ref [] in
  159. (* lista wierzchołków posortowanych topologicznie    *)
  160.   let posortowane = ref [] in
  161. (* lista zwracana jako wynik                         *)
  162.   let wynik = ref [] in
  163. (* ilość wierzchołków w grafie                       *)
  164.   let ile = ref 0 in
  165.   let sprawdzczyzerowy wierzcholek =
  166.     if find wierzcholek !stopien = 0 then
  167.       zerowe := wierzcholek :: !zerowe in
  168.   let powieksz wierzcholek =
  169.     stopien := (add wierzcholek (find wierzcholek !stopien + 1) !stopien) in
  170.   let zmniejsz wierzcholek =
  171.     stopien := (add wierzcholek (find wierzcholek !stopien - 1) !stopien);
  172.     sprawdzczyzerowy wierzcholek in
  173. (* utwórz w mapach pola dotyczące danego wierzchołka *)
  174.   let dotknij wierzcholek =
  175.     if mem wierzcholek !krawedzie = false then
  176.       krawedzie := (add wierzcholek [] !krawedzie);
  177.     if mem wierzcholek !stopien = false then
  178.       stopien := (add wierzcholek 0 !stopien) in
  179.   let przetworz (aktualny, listakrawedzi) =
  180.     dotknij aktualny;
  181.     krawedzie := (add aktualny (listakrawedzi@(find aktualny !krawedzie)) !krawedzie);
  182.     List.iter dotknij listakrawedzi;
  183.     List.iter powieksz listakrawedzi in
  184.   let usun wierzcholek =
  185.     posortowane := wierzcholek :: !posortowane;
  186.     List.iter zmniejsz (find wierzcholek !krawedzie) in
  187.   let aktualny = ref (fst (List.hd graf)) in
  188.   List.iter przetworz graf;
  189.   iter (fun x y -> sprawdzczyzerowy x) !stopien;
  190.   while (!zerowe <> [])
  191.   do
  192.     aktualny := (List.hd !zerowe);
  193.     zerowe := List.tl !zerowe;
  194.     usun !aktualny
  195.   done;
  196.   iter (fun x y -> ile := !ile + 1) !stopien;
  197.   if List.length !posortowane < !ile then
  198.     raise Cykliczne
  199.   else
  200.     wynik := (List.rev !posortowane);
  201.   !wynik
  202.  
  203. let topol graf =
  204.   match graf with
  205.   | [] -> []
  206.   | h::t -> szukaj graf
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement