58 lines
1.7 KiB
OCaml
58 lines
1.7 KiB
OCaml
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)
|
|
|