Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file rand.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241(**************************************************************************)(* *)(* Ocamlgraph: a generic graph library for OCaml *)(* Copyright (C) 2004-2010 *)(* Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles *)(* *)(* 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. *)(* *)(**************************************************************************)(* $Id: rand.ml,v 1.18 2005-03-31 13:32:51 filliatr Exp $ *)moduletypeS=sigtypegraphtypevertextypeedge_labelvalgraph:?loops:bool->v:int->e:int->unit->graphvallabeled:(vertex->vertex->edge_label)->?loops:bool->v:int->e:int->unit->graph(* DEBUG *)valrandom_few_edges:loops:bool->v:int->e:int->graphvalrandom_many_edges:loops:bool->v:int->e:int->graphvalgnp:?loops:bool->v:int->prob:float->unit->graphvalgnp_labeled:(vertex->vertex->edge_label)->?loops:bool->v:int->prob:float->unit->graphendmoduleMake(B:Builder.INT)=structopenBtypegraph=G.ttypevertex=G.V.ttypeedge_label=G.E.labelopenInt64letmax_edges~loops~v~e=ifv<=0||e<0theninvalid_arg"random";letv64=of_intvinletmax_e=mulv64(predv64)inletmax_e=ifG.is_directedthenmax_eelsedivmax_e(of_int2)inletmax_e=ifloopsthenaddmax_ev64elsemax_einifof_inte>max_etheninvalid_arg"random: too many edges";max_eletfold_fori0i1f=letrecloopiv=ifi>i1thenvelseloop(i+1)(fvi)inloopi0(* naive implementation: we randomly chose edges up to [e] different edges *)letrandom_few_edgesadd_edge~loops~v~e=let_=max_edges~loops~v~einleta=Array.initvG.V.createinletg=Array.fold_leftadd_vertex(empty())ainletrecrandom_edgeg=leti=Random.intvinletj=Random.intvinif(i=j&¬loops)||G.mem_edgega.(i)a.(j)thenrandom_edgegelseadd_edgega.(i)a.(j)infold_for1e(fung_->random_edgeg)g(* other implementation in O(v * v); faster when [e] is large *)letrandom_many_edgesadd_edge~loops~v~e=letv64=of_intvinletmax_e=max_edges~loops~v~einleta=Array.initvG.V.createinletg=Array.fold_leftadd_vertex(empty())ainletrecadd_edgesijmaxnbg=assert(max>=0L&&max_e=addmax(add(mul(of_inti)v64)(of_int(j-(matchG.is_directed,loopswith|true,true->0|true,false->ifj>itheni+1elsei|false,true->i*(i-1)/2+ifj>ithenielsej|false,false->i*(i+1)/2+ifj>itheni+1elsej)))));ifnb=0thengelseletadd_edges=leti,j=ifj=v-1theni+1,0elsei,j+1inadd_edgesijinif(i=j&¬loops)||(notG.is_directed&&i>j)thenadd_edgesmaxnbgelseletadd_edges=add_edges(predmax)inifRandom.int64max<of_intnbthenadd_edges(nb-1)(add_edgega.(i)a.(j))elseadd_edgesnbginadd_edges00max_eegletrandom~loops~v~e=letr=floate/.(floatv*.floatv)in(ifr<0.4thenrandom_few_edgeselserandom_many_edges)~loops~v~eletgraph?(loops=false)~v~e()=randomB.add_edge~loops~v~eletlabeledf?(loops=false)~v~e()=random(fungv1v2->B.add_edge_eg(G.E.createv1(fv1v2)v2))~loops~v~e(* DEBUG *)letrandom_few_edges=random_few_edgesB.add_edgeletrandom_many_edges=random_many_edgesB.add_edge(** G(n,p) graphs
See https://en.wikipedia.org/wiki/Random_graph *)letgnp_genericadd_edge?(loops=false)~v~prob()=ifnot(0.0<=prob&&prob<=1.0)theninvalid_arg"gnp";letvertices=Array.initv(funi->B.G.V.createi)inletg=Array.fold_leftB.add_vertex(B.empty())verticesinletg=refginfori=0tov-1doforj=0to(ifG.is_directedthenv-1elsei)doif(loops||j<>i)&&(prob=1.0||Random.float1.0<prob)theng:=add_edge!gvertices.(i)vertices.(j)donedone;!gletgnp?(loops=false)~v~prob()=gnp_genericB.add_edge~loops~v~prob()letgnp_labeledf?(loops=false)~v~prob()=gnp_generic(fungv1v2->B.add_edge_eg(G.E.createv1(fv1v2)v2))~loops~v~prob()endmoduleP(G:Sig.PwithtypeV.label=int)=Make(Builder.P(G))moduleI(G:Sig.IwithtypeV.label=int)=Make(Builder.I(G))(** Random planar graphs *)modulePlanar=structmoduletypeS=sigtypegraphvalgraph:?loops:bool->xrange:int*int->yrange:int*int->prob:float->int->graphendmoduleMake(B:Builder.SwithtypeG.V.label=int*intandtypeG.E.label=int)=structtypegraph=B.G.topenB.GmodulePoint=structtypepoint=V.tletccwv1v2v3=Delaunay.IntPoints.ccw(V.labelv1)(V.labelv2)(V.labelv3)letin_circlev1v2v3v4=Delaunay.IntPoints.in_circle(V.labelv1)(V.labelv2)(V.labelv3)(V.labelv4)letdistancev1v2=letx1,y1=V.labelv1inletx2,y2=V.labelv2inletsqrx=letx=floatxinx*.xintruncate(sqrt(sqr(x1-x2)+.sqr(y1-y2)))endmoduleTriangulation=Delaunay.Make(Point)letgraph?(loops=false)~xrange:(xmin,xmax)~yrange:(ymin,ymax)~probv=ifnot(0.0<=prob&&prob<=1.0)theninvalid_arg"Planar.graph";ifv<2theninvalid_arg"Planar.graph";(* [v] random points and their Delaunay triangulation *)letrandom_point()=xmin+Random.int(1+xmax-xmin),ymin+Random.int(1+ymax-ymin)inletvertices=Array.initv(fun_->V.create(random_point()))inlett=Triangulation.triangulateverticesin(* a graph with [v] vertices and random loops if any *)letg=Array.fold_leftB.add_vertex(B.empty())verticesinletg=ifloopsthenArray.fold_left(fungv->ifRandom.float1.0<probthengelselete=E.createv0vinB.add_edge_ege)gverticeselsegin(* we keep some edges from the triangulation according to [prob] *)letadd_edgev1v2g=ifRandom.float1.0<probthengelselete=E.createv1(Point.distancev1v2)v2inB.add_edge_egeinTriangulation.fold(funv1v2g->letg=add_edgev1v2ginifis_directedthenadd_edgev2v1gelseg)tgendmoduleP(G:Sig.PwithtypeV.label=int*intandtypeE.label=int)=Make(Builder.P(G))moduleI(G:Sig.IwithtypeV.label=int*intandtypeE.label=int)=Make(Builder.I(G))end(*
Local Variables:
compile-command: "make -C .. src/rand.cmo"
End:
*)