Проблема заключается в следующем: учитывая ориентированный взвешенный граф, начальный узел, конечный узел и число k, проверьте, существует ли путь от начального узла до конечного узла по крайней мере длиной k.
Это это код, который я написал, и это правильно, но только в указанном c графике. Например, g1
с weights1
выглядит следующим образом:
let weights1 = [(2,1,1);(2,1,3);(2,1,4);(1,1,5);(5,1,2);(5,1,6);(3,1,6);(6,1,7);(4,1,3)];;
let f1 = function
1 -> [5]
| 2 -> [1;3;4]
| 3 -> [6]
| 4 -> [3]
| 5 -> [2;6]
| 6 -> [7]
| _ -> [];;
type 'a graph = Graph of ('a -> 'a list);;
let g1 = Graph f1;;
let weights2 = [(1,3,2);(1,9,5);(2,2,3);(5,4,6);(3,1,6);(3,7,4);(6,2,7);(4,4,6);(6,1,2)];;
let f2 = function
1 -> [2;5]
| 2 -> [3]
| 3 -> [4;6]
| 4 -> [6]
| 5 -> [6]
| 6 -> [2;7]
| _ -> [];;
let g2 = Graph f2;;
exception NotFound;;
exception Errore;;
(* Function that return the weight of an edge given 2 nodes*)
let rec get_k x y = function
[] -> 0
|(a,b,c)::rest -> if((a=x && c=y))then b else get_k x y rest;;
(* Function that calculate the total cost of a given path*)
let cost_of_path path weight =
let rec sum cost = function
[]->raise Errore
|x::y::rest -> sum (cost + get_k x y weight) (y::rest)
|_::[]->cost
in sum 0 path;;
(*this function print the list of the path*)
let rec printList = function [] -> print_newline()
| x::rest -> print_int(x); print_string("; "); printList rest;;
(* Simple bfs function, return only 1 path that connect the start node to the final node*)
let bfs start last_node (Graph succ) =
let extends path = printList path;
List.map (function x -> x::path) (List.filter (function x -> not (List.mem x path)) (succ (List.hd path)))
in let rec aux last_node = function
[] -> raise Not_found
| path::rest ->
if (last_node = List.hd path) then List.rev path
else aux last_node (rest @ (extends path))
in aux last_node [[start]];;
let loghest_path start final_node k weight (Graph succ)=
let extends path = printList path;
List.map (function x -> x::path)(succ (List.hd path))
in let rec aux final_node = function
[] -> raise NotFound
| path::rest ->
(*if the cost of this path is >= k and the last node is the final node, return that path.*)
if ((cost_of_path (List.rev path) weight >= k) && (List.hd path == final_node)) then List.rev path
(*HERE IS THE ERROR: if the total weight of the singole path is >= k but the last node is not the final node,
find a path that connect the last node of this path to the final node using bfs. It can happen that the path exists
but it return "Not_Found".*)
else if((cost_of_path (List.rev path) weight) >= k)
then (List.rev (List.tl path)) @ bfs (List.hd path) (final_node) (Graph succ)
(* If the weight is not yet k than extend the path and try another one in list 'rest' *)
else aux final_node (rest @ (extends path))
in aux final_node [[start]];;
(*Function that calls the other function 'loghest_path' and print the result *)
let find_path start final_node k weigths (Graph succ)=
let result = (loghest_path start final_node k weigths (Graph succ)) in
print_string("Final Path:"); printList result ;
print_string("The weight is:"); print_int (cost_of_path result weigths); print_newline();;
И выполнение моего кода с использованием весов1 и g1:
Теперь, если я выполню свой код в другом графике, например:
let weights3 =[(1,1,2);(1,1,3);(1,1,4);(2,1,5);(2,1,6);(3,1,7);(3,1,8);(4,1,9);(4,1,10);(10,1,1)];;
let f3 = function
1 -> [2;3;4]
| 2 -> [5;6]
| 3 -> [7;8]
| 4 -> [9;10]
| 10 -> [1]
| _ -> [];;
let g3 = Graph f3;;
При следующем выполнении Мой код завершается ошибкой:
Это потому, что последний путь перед поиском пути, который по крайней мере k, начинается с узла 2, и нет пути, который может соединить 2 с 10, но путь от 1 до 10 весов 10 существует, и он не был выбран. Может кто-нибудь объяснить мне, как я могу изменить свой код, чтобы убедиться, что проблема решена в каждом типе графика?