Advertisement
Guest User

Untitled

a guest
Jan 9th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 2.84 KB | None | 0 0
  1. open PMap
  2.  
  3. (** wyjatek rzucany przez [topol] gdy zaleznosci sa cykliczne *)
  4. exception Cykliczne
  5.  
  6. (* funkcja pomocnicza do folda przy tworzeniu grafu
  7. w - wierzchołek *)
  8. let tworz_graf graf (w, sasiedzi) =
  9.   if not (mem w graf) then add w sasiedzi graf else
  10.   (* dodajemy nowych sąsiadów do już istniejących *)
  11.   let dotychczasowi_sasiedzi = find w graf in
  12.   add w (dotychczasowi_sasiedzi @ sasiedzi) graf
  13.  
  14. (** Dla danej listy [(a_1,[a_11;...;a_1n]); ...; (a_m,[a_m1;...;a_mk])]
  15.     zwraca liste, na ktorej kazdy z elementow a_i oraz a_ij wystepuje
  16.     dokladnie raz i ktora jest uporzadktowana w taki sposob, ze kazdy
  17.     element a_i jest przed kazdym z elementow a_i1 ... a_il *)
  18. let topol lista_sasiedztwa =
  19.   if lista_sasiedztwa = [] then [] else
  20.   (* mapa, która przechowuje listę sąsiadów każdego wierzchołka *)
  21.   let graf = List.fold_left tworz_graf empty lista_sasiedztwa in
  22.   (* lista zawierająca pierwsze elementy z par z listy lista_sasiedztwa *)
  23.   let wierzcholki_poczatkowe =
  24.     List.fold_left (fun l (w, sasiedzi) -> w :: l) [] lista_sasiedztwa in
  25.   (* funkcja pomocnicza służąca do przetworzenia wierzchołków i zwrócenia
  26.     odpowiedniego wyniku
  27.     stan odwiedzenia:
  28.     - gdy nie istnieje dowiązanie do jakiegoś wierzchołka to nie zaczął on być
  29.       przetwarzany
  30.     - 1 - wierzchołek jest w trakcie przetwarzania
  31.     - 2 - wierzchołek jest przetworzony *)
  32.   let rec dfs (wynik, stan_odwiedzenia) wierzcholek =
  33.     (* sprawdzenie czy wierzchołek zaczął być przetwarzany *)
  34.     if not (mem wierzcholek stan_odwiedzenia)
  35.     then
  36.       (* aktualizacja stanu wierzchołka *)
  37.       let stan_odw1 = add wierzcholek 1 stan_odwiedzenia in
  38.       (* gdy wierzchołek ma jakichkolwiek sąsiadów to wywoływana jest dla nich
  39.       funkcja dfs i zwracana jest para postaci (stan_odwiedzenia, wynik),
  40.       gdy nie ma tych sąsiadów zwracana jest para *)
  41.       if mem wierzcholek graf
  42.       then
  43.         (* (stan_odw2, wyn2) - pomocnicza para przechowująca wynik zwracany
  44.         przez folda *)
  45.         let (wyn2, stan_odw2) = List.fold_left dfs (wynik, stan_odw1)
  46.           (find wierzcholek graf) in
  47.         (wierzcholek :: wyn2, add wierzcholek 2 stan_odw2)
  48.       else (wierzcholek :: wynik, add wierzcholek 2 stan_odw1)
  49.     (* gdy w funkcja dfs zostaje wywołana dla już przetwarzanego wierzchołka
  50.     (takiego, że jego stan odwiedzenia jest równy 1) to znaczy, że w grafie jest
  51.     cykl, więc zostaje podniesiony wyjątek *)
  52.     else if (find wierzcholek stan_odwiedzenia) = 1 then raise Cykliczne else
  53.     (* dany wierzchołek został już przetworzony, więc zostaje zwrócony wynik*)
  54.       (wynik, stan_odwiedzenia)
  55.   in
  56.   (* wywołanie funkcji dfs dla wszystkich wierzchołków, które mają sąsiadów
  57.   i zwrócenie wyniku *)
  58.   fst(List.fold_left dfs ([], empty) wierzcholki_poczatkowe)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement