1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798(**************************************************************************)(* *)(* Ocamlgraph: a generic graph library for OCaml *)(* Copyright (C) 2013-2014 *)(* David Monniaux, Gabriel Radanne *)(* *)(* This software is free software; you can redistribute it and/or *)(* modify it under the terms of the GNU Library General Public *)(* License version 2.1, with the special exception on linking *)(* described in file LICENSE. *)(* *)(* This software is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *)(* *)(**************************************************************************)moduletypeG=sigtypetmoduleV:Sig.VERTEXvalsucc:t->V.t->V.tlistendmoduleMake(G:G)=structmoduleH=Hashtbl.Make(G.V)letfind_defaulthtblx=tryH.findhtblxwithNot_found->falseletmin_cutsetgrfirst_node=letn_labels=H.create97inletl_labels=H.create97inletalready_processed=H.create97inletis_already_processedx=find_defaultalready_processedxinleton_the_stack=H.create97inletis_on_the_stackx=find_defaulton_the_stackxinletcut_set=ref[]inletcounter=ref1inletrecstep2toprest_of_stack=assert(not(is_already_processedtop));assert(not(is_on_the_stacktop));H.addon_the_stacktoptrue;H.addn_labelstop!counter;counter:=!counter+1;H.addl_labelstop0;H.addalready_processedtoptrue;step3(G.succgrtop)toprest_of_stackandstep3successorstoprest_of_stack=matchsuccessorswith|successor::other_successors->ifnot(is_already_processedsuccessor)(* step 4 *)thenstep2successor((top,successors)::rest_of_stack)(* step 5 *)elsebeginletx=ifis_on_the_stacksuccessorthenH.findn_labelssuccessorelseH.findl_labelssuccessorinH.addl_labelstop(max(H.findl_labelstop)x);step3other_successorstoprest_of_stackend|[]->begin(* step 7 *)ifH.findl_labelstop=H.findn_labelstopthenbegincut_set:=top::!cut_set;H.addl_labelstop0;end;(* check added between algorithms C and D *)ifH.findl_labelstop>H.findn_labelstopthenraise(Invalid_argument"Graph.Mincut: graph not reducible")(* step 8 *)elsematchrest_of_stackwith|[]->!cut_set(* SUCCESS *)|(new_top,new_successors)::new_tail->beginH.addon_the_stacktopfalse;H.addl_labelsnew_top(max(H.findl_labelstop)(H.findl_labelsnew_top));step3new_successorsnew_topnew_tailendendin(* step 2 *)step2first_node[]end