Я только начинающий в Ocaml, и я хотел изучить теорию графов, но с реализациями в Ocaml.И у меня есть проблема, чтобы что-то сделать: я просто хотел перечислить связанные компоненты графика, используя поиск в глубину.Итак, я сделал:
#open "stack" ;;
let non_empty pile =
try push (pop pile) pile ; true with Empty -> false ;;
let connected_comp g =
let already_seen = make_vect (vect_length g) false in
let comp = [] in
let dfs s lst =
let totreat = new () in
already_seen.(s) <- true; push s totreat;
let rec add_neighbour l = match l with
| [] -> ()
| q::r when already_seen.(q) = false -> push q totreat; already_seen.(q) <- true; add_neighbour r
| q::r -> add_neighbour r
in
while non_empty totreat do
let s = pop totreat in
already_seen.(s) <- true;
(* we want to add s to the list lst *) s::lst;
add_neighbour g.(s);
done
in
let rec head_list l = match l with
| [] -> failwith "Empty list"
| p::q -> p
in
let rec aux comp t = match t with
| t when t = vect_length g -> comp
| t when already_seen.(t) = true -> aux comp (t+1)
| t -> aux ((dfs t [])::comp) (t+1) (* we want that dfs t [] return the list lst modified *)
in aux comp 0;;
И получаю:
> | t -> (dfs t [])::comp ; aux comp (t+1) (* we want that dfs t [] return the list lst modified *)
> ^^^^^^^^^^^^^^^^
Warning : this expression is of type unit list,
but is used with the type unit.
connected_comp : int list vect -> unit list = <fun>
- : unit list = []
- : unit = ()
Конечно, я не удивлен.Но я хочу, чтобы функция dfs
возвращала список, отправленный по аргументу (список lst
), но измененный, и здесь дело обстоит не так, поскольку функция имеет тип unit, потому что она ничего не возвращает.Но в Окамле, поскольку язык создан для возврата последнего выражения, я думаю, я не знаю, как это сделать.Я мог бы также использовать рекурсивный алгоритм для функции dfs
, так как с помощью фильтрации это позволило бы мне вернуть список, но я просто хотел узнать об Ocaml и изменил (даже если он не оптимален) мой алгоритм.
Кто-нибудь может мне помочь, пожалуйста?
Редактировать: Когда мы спросим меня, я постараюсь сократить свой код и перейти к сути.Итак, у меня есть функция dfs
, которая соответствует первому поиску по глубине (для графика)
let dfs s lst =
let totreat = new () in
already_seen.(s) <- true; push s totreat;
let rec add_neighbour l = match l with
| [] -> ()
| q::r when already_seen.(q) = false -> push q totreat; already_seen.(q) <- true; add_neighbour r
| q::r -> add_neighbour r
in
while non_empty totreat do
let s = pop totreat in
already_seen.(s) <- true;
(* we want to add s to the list lst *) s::lst;
add_neighbour g.(s);
done
in
(уже определен вектор логического типа, определенный ранее)
И мой единственныйпроблема в том, что я хочу, чтобы функция возвращала список lst
, модифицированный (в цикле while), когда в этот момент это единичная функция.
Я попытался определить lst как ссылку, но затемЯ не знаю, как его вернуть ...
Надеюсь, это более понятно, на данный момент я не знаком со всем этим ...
Спасибо!