open Graph open Tools open Display open List open Printf let rec way g n1 n2 = let rec inner g (xs, capa) visited n1 n2 = match n1, n2 with | a, b when a = n2 -> Some ((List.rev xs), capa) | a, b -> let findNext x (arcId, arcCapa) = match x with | None -> inner g (arcId :: xs, (min capa arcCapa)) (arcId :: visited) arcId n2 | Some a -> Some a in let out = List.filter (fun x -> not (List.exists (fun y -> (fst x) = y) visited)) (out_arcs g a) in if List.length out > 0 then fold_left findNext None out else None in if n1 == n2 then None else inner g ([n1], (maxCapaGraph g)) [] n1 n2 (*updates the difference graph according to a path, removes any 0-worth edge and tests for the graph sanity (only positive-valued edges)*) let update g (nodes,capa) = let rec updateCapacityAlongPath g (nodes,capa) = match nodes with | [] -> g | x :: [] -> g | x::y::xs -> let removedCapcityUsed = sub_arc g x y capa in let addPossibleUndo = add_arc removedCapcityUsed y x capa in updateCapacityAlongPath addPossibleUndo (y::xs,capa) in testGraphSanity ( clearNull ( updateCapacityAlongPath g (nodes,capa) ) ) (*takes a graph, a start/end node and returns a finished difference graph*) let rec main g idS idE = let path = way g idS idE in match path with | None -> g | Same (xs, capa) -> main (update g (xs, capa) idS IdE)