Я написал некоторую функцию для поиска списка возможных путей от начального узла до конечного узла. Функция list_of_paths
правильно возвращает все возможные пути от начальной точки до конечной точки, но тот же путь внутри списка повторяется, даже если он уже был найден.
Например, вызов функции:
list_of_paths 2 7 (List.rev (bfs g1 2)) (node_succ g1) 2
возвращает:
[[2; 3; 6; 7]; [2; 3; 6; 7]; [2; 3; 4; 6; 7]; [2; 3; 6; 7]; [2; 1; 5; 6; 7]; [2; 3; 6; 7]; [2; 1; 5; 6; 7]]
Как видите, одни и те же пути повторяются. Может кто-нибудь сказать мне, где ошибка? Это код, который я написал:
type weight = int;;
type 'a graph = Gr of (int * weight * int) list;;
let g1 = Gr [(1,3,2);(1,9,5);(2,2,3);(5,4,6);(3,1,6);(3,7,4);(6,2,7);(4,4,6)];;
let rec node_succ (Gr graph) node =
let rec f_aux = function
[] -> []
| (x,y,z)::tail ->
if x = node then z::f_aux tail
else if z = node then x::f_aux tail
else f_aux tail in f_aux graph;;
let bfs graph s =
let rec search visited_nodes = function
[] -> visited_nodes
| head::tail ->
if List.mem head visited_nodes then search visited_nodes tail
else search (head::visited_nodes) (tail @ (node_succ graph head)) in search [] [s];;
let find_paths_bfs start stop graph =
let extends paths =
List.map (function x -> x::paths) (List.filter (function x -> not (List.mem x paths)) (graph (List.hd paths)))
in let rec s_aux stop = function
[] -> raise Not_found
| paths::tail ->
if stop = List.hd paths then List.rev paths
else s_aux stop (tail @ (extends paths)) in s_aux stop [[start]];;
let rec list_of_paths start stop reachable_nodes fun_graph_succ s =
if reachable_nodes = [] then []
else ((find_paths_bfs s start fun_graph_succ)@(List.tl(find_paths_bfs start stop fun_graph_succ)))
::(list_of_paths (List.hd reachable_nodes) stop (List.tl reachable_nodes) fun_graph_succ s);;
Функция node_succ
возвращает всех возможных преемников узла.
Функция bfs
возвращает все достижимые узлы из начального узла.
Функция find_paths_bfs
находит один путь, начиная с узла и заканчивая другим.