From 680b45f731c649216595cc7a41c729632af9871f Mon Sep 17 00:00:00 2001 From: Erwan Jahier <erwan.jahier@univ-grenoble-alpes.fr> Date: Wed, 6 Apr 2022 14:56:05 +0200 Subject: [PATCH] feat: add a --global-init-search option --- lib/sasacore/sasArg.ml | 27 ++++++++++++------- lib/sasacore/sasArg.mli | 8 +++--- lib/sasacore/simuState.ml | 13 +++++---- lib/sasacore/simuState.mli | 4 ++- lib/sasacore/worstInit.ml | 54 +++++++++++++++++++++++++++++++++++--- lib/sasacore/worstInit.mli | 28 ++++++++++++++++++++ src/sasaMain.ml | 22 +++++++++++----- 7 files changed, 125 insertions(+), 31 deletions(-) create mode 100644 lib/sasacore/worstInit.mli diff --git a/lib/sasacore/sasArg.ml b/lib/sasacore/sasArg.ml index 1a41a5ba..8eaf4f60 100644 --- a/lib/sasacore/sasArg.ml +++ b/lib/sasacore/sasArg.ml @@ -1,5 +1,7 @@ -(* Time-stamp: <modified the 14/11/2021 (at 18:34) by Erwan Jahier> *) +(* Time-stamp: <modified the 06/04/2022 (at 10:07) by Erwan Jahier> *) +type init_search = + No_init_search | Local of int | Global of int | Annealing of int type t = { mutable topo: string; @@ -17,8 +19,7 @@ type t = { mutable dummy_input: bool; mutable output_algos: bool; mutable gen_register: bool; - mutable init_search_max_trials: int option; - mutable init_search_sa: bool; + mutable init_search: init_search; mutable _args : (string * Arg.spec * string) list; mutable _user_man : (string * string list) list; @@ -52,8 +53,7 @@ let (make_args : unit -> t) = dummy_input = false; output_algos = false; gen_register = false; - init_search_max_trials = None; - init_search_sa = false; + init_search = No_init_search; _args = []; _user_man = []; _hidden_man = []; @@ -153,15 +153,22 @@ let (mkoptab : string array -> t -> unit) = (* (Arg.Int (fun i -> args.daemon <- DaemonType.Bad i)) *) (* ["Use a daemon that tries to maximize the potential function, "; *) (* "considering sub-graphs of a given maximal size"]; *) - mkopt args ["--init-search";"-is"] - (Arg.Int(fun i -> args.init_search_max_trials <- Some i)) + mkopt args ["--local-init-search";"-is"] + (Arg.Int(fun i -> args.init_search <- Local i)) ["Use local search algorithms to find an initial configuration that pessimize "; "the step number. The argument is the maximum number of trials to do the search. "; "Require the state_to_nums Algo.to_register field to be defined."] ~arg:" <int>"; - mkopt args ["--init-search-sa";"-issa"] - (Arg.Int(fun i -> args.init_search_sa <- true; args.init_search_max_trials <- Some i)) - ["ditto + simulated annealing. XXX experimental"] ~arg:" <int>"; + mkopt args ["--global-init-search";"-gis"] + (Arg.Int(fun i -> args.init_search <- Global i)) + ["Use global (i.e., completely random) search to find an initial configuration "; + "that pessimize the step number. The argument is the maximum number of trials"; + " to do the search. "] ~arg:" <int>"; + +(* mkopt args ["--init-search-simulated-annealing";"-issa"] + (Arg.Int(fun i -> args.init_search <- Annealing i)) + ["ditto + simulated annealing. XXX NOT YET IMPLEMENTED"] ~arg:" <int>"; +*) mkopt args ["--cores-nb";"-cn"] (Arg.Int(fun i -> args.cores_nb <- i)) ["Number of cores to use during --init-search simulations (default is 1)"]; diff --git a/lib/sasacore/sasArg.mli b/lib/sasacore/sasArg.mli index 800c0e67..ab229e78 100644 --- a/lib/sasacore/sasArg.mli +++ b/lib/sasacore/sasArg.mli @@ -1,4 +1,7 @@ -(* Time-stamp: <modified the 14/11/2021 (at 18:34) by Erwan Jahier> *) +(* Time-stamp: <modified the 06/04/2022 (at 09:32) by Erwan Jahier> *) + +type init_search = + No_init_search | Local of int | Global of int | Annealing of int type t = { mutable topo: string; @@ -16,8 +19,7 @@ type t = { mutable dummy_input: bool; mutable output_algos: bool; mutable gen_register: bool; - mutable init_search_max_trials: int option; - mutable init_search_sa: bool; + mutable init_search: init_search; mutable _args : (string * Arg.spec * string) list; mutable _user_man : (string * string list) list; diff --git a/lib/sasacore/simuState.ml b/lib/sasacore/simuState.ml index 3fe54131..bd988062 100644 --- a/lib/sasacore/simuState.ml +++ b/lib/sasacore/simuState.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 08/11/2021 (at 10:59) by Erwan Jahier> *) +(* Time-stamp: <modified the 06/04/2022 (at 11:07) by Erwan Jahier> *) open Register open Topology @@ -265,7 +265,10 @@ let (make : bool -> string array -> 'v t) = let e = update_env_with_init e pl in let algo_neighors = List.map (update_neighbor_env e) algo_neighors in let pl_n = List.combine pl algo_neighors in - + let neighbors = + List.fold_left (fun acc (p,nl) -> StringMap.add p.pid nl acc) + StringMap.empty pl_n + in if !Register.verbose_level > 1 then List.iter (dump_process "") pl_n; if args.gen_lutin then ( let fn = (Filename.remove_extension args.topo) ^ ".lut" in @@ -317,13 +320,9 @@ let (make : bool -> string array -> 'v t) = (fun a -> ignore (RifRead.bool (args.verbose>1) p.pid (StringOf.action a))) p.actions) pl; - Printf.eprintf "Ignoring the first vectors of sasa inputs\n%!"; + Printf.eprintf "Ignoring the first vector of sasa inputs\n%!"; ); if !Register.verbose_level > 0 then Printf.eprintf "==> SimuState.make done !\n%!"; - let neighbors = - List.fold_left (fun acc (p,nl) -> StringMap.add p.pid nl acc) - StringMap.empty pl_n - in { sasarg = args; network = pl; diff --git a/lib/sasacore/simuState.mli b/lib/sasacore/simuState.mli index e6e4efa7..156738d9 100644 --- a/lib/sasacore/simuState.mli +++ b/lib/sasacore/simuState.mli @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 31/03/2022 (at 17:13) by Erwan Jahier> *) +(* Time-stamp: <modified the 06/04/2022 (at 14:51) by Erwan Jahier> *) (** The module is used by - the main sasa simulation loop (in ../../src/sasaMain.ml) @@ -27,6 +27,8 @@ val get_enable_processes: 'v t -> 'v enable_processes (** [update_config e c] updates c using e *) val update_config: 'v Conf.t -> 'v t -> 'v t +val update_env_with_init : 'v Conf.t -> 'v Process.t list -> 'v Conf.t + (** Get pid's state and neighbors *) val neigbors_of_pid : 'v t -> string -> 'v * ('v Register.neighbor * string) list diff --git a/lib/sasacore/worstInit.ml b/lib/sasacore/worstInit.ml index a4e86f18..ba9a5330 100644 --- a/lib/sasacore/worstInit.ml +++ b/lib/sasacore/worstInit.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 17/11/2021 (at 12:06) by Erwan Jahier> *) +(* Time-stamp: <modified the 06/04/2022 (at 14:52) by Erwan Jahier> *) open Register @@ -261,9 +261,57 @@ let (fchc : out_channel -> ('v SimuState.t -> int) -> 'v SimuState.t -> int ) ) - in - + in match LocalSearch.run g None with | LocalSearch.Stopped -> assert false (* SNO *) | LocalSearch.NoMore-> assert false (* SNO *) | LocalSearch.Sol (sol, more) -> run_more sol more + +open Topology +open SimuState +open Process +(* generate a new random configuration using the user init functions *) +let reinit_simu g ss = + let pl = List.map2 + (fun n p -> + { p with + init = let algo_id = Filename.chop_suffix n.Topology.file ".ml" in + Register.get_init_state algo_id (List.length (g.succ p.pid)) p.pid + }) + g.nodes + ss.network + in + let e = Conf.init () in + let e = SimuState.update_env_with_init e pl in + + update_config e ss + +(*****************************************************************************) +(* Global search : use no heuristic, the init wtate is chosen at random *) +let (global : out_channel -> ('v SimuState.t -> int) -> 'v SimuState.t -> int + -> 'v SimuState.t) = + fun log run ss_init dmax -> + let dot_file = ss_init.sasarg.topo in + let g = Topology.read dot_file in + let percent_done = ref 0 in + let rec loop cpt (ss_worst, worst) = + let ss = reinit_simu g ss_init in + let ss_worst, worst = + let res = run ss in + Printf.fprintf log "simu %d, cost=%d\n%!" cpt res; + if res > worst then ( + Printf.printf "Hey, I've found a conf of cost %d! (simu #%d)\n%!" res cpt; + ss, res + ) + else + ss_worst, worst + in + let n_percent_done = cpt / (dmax / 100) in + if n_percent_done <> !percent_done then ( + percent_done := n_percent_done; + Printf.printf "%d%% of the %d simulations have been tryied so far...\r%!" + n_percent_done dmax + ); + if cpt > dmax then ss_worst else loop (cpt+1) (ss_worst, worst) + in + loop 1 (ss_init, run ss_init) diff --git a/lib/sasacore/worstInit.mli b/lib/sasacore/worstInit.mli new file mode 100644 index 00000000..7adaef62 --- /dev/null +++ b/lib/sasacore/worstInit.mli @@ -0,0 +1,28 @@ +(* Time-stamp: <modified the 06/04/2022 (at 14:55) by Erwan Jahier> *) + +(** First Choice Hill Climbing: a successor is chosen at random (using + some heuristics), and became the current state if its cost is + better. + + The heuristic to choose the succ is chosen at random using various + heuristics. *) +val fchc : out_channel -> ('v SimuState.t -> int) -> 'v SimuState.t -> int -> + 'v SimuState.t + +(** Global search : use no heuristic, the init wtate is chosen at + random using the user init functionstype 's node = { st : 's; d : int; cost : int; cpt : int; } +val debug : bool +type distance = Far | Close +val mutate_value : 'a -> 'b -> 'c +val one_dim_succ : 'a -> 'b array -> 'b array +val ran_dim_succ : 'a -> 'b array -> 'b array +val all_dim_succ : 'a -> 'b array -> 'b array +val tf : int -> float +val ti : float -> int +module ValueArrayNode : sig val compare : 'a node -> 'b node -> int end +module Q : sig end +val value2str : 'a -> 'b +val point2str : 'a array -> string +val reinit_simu : 'a -> 'b -> 'ca*) +val global : out_channel -> ('v SimuState.t -> int) -> 'v SimuState.t -> int -> + 'v SimuState.t diff --git a/src/sasaMain.ml b/src/sasaMain.ml index 3b4bfa36..6cd7cf0c 100644 --- a/src/sasaMain.ml +++ b/src/sasaMain.ml @@ -7,7 +7,7 @@ let (print_step : out_channel -> 'v SimuState.t -> int -> int -> string -> strin 'v Conf.t -> 'v Process.t list -> string -> bool list list -> unit) = fun log st n i legitimate pot args e pl activate_val enab_ll -> let enable_val = bll2str enab_ll in - if st.sasarg.init_search_max_trials <> None then ( + if st.sasarg.init_search <> No_init_search then ( (* Printf.fprintf log "\n#step %s\n%!" (string_of_int (n-i)); *) (* Printf.fprintf log "%s %s %s %s\n%!" (StringOf.env_rif e pl) enable_val legitimate pot; *) ) else @@ -191,8 +191,8 @@ let () = let n = st.sasarg.length in let oc_rif = match st.sasarg.output_file_name with None -> stdout | Some fn -> open_out fn in try - match st.sasarg.init_search_max_trials, st.sasarg.daemon with - | None, (ExhaustSearch|ExhaustCentralSearch) -> + match st.sasarg.init_search, st.sasarg.daemon with + | No_init_search, (ExhaustSearch|ExhaustCentralSearch) -> let log = open_out (st.sasarg.topo ^ ".log") in let path = ExhaustSearch.f log (st.sasarg.daemon=ExhaustCentralSearch) st in List.iteri @@ -213,13 +213,15 @@ let () = (if st.sasarg.rif then "#" else "#") !moves (plur !moves) i (plur i) !rounds (plur !rounds); - | None,_ -> + | No_init_search, _ -> ignore (simuloop stdout n n "" st) - | Some maxt, _ -> + | Annealing _, _ -> assert false (* TODO *) + | (Local maxt|Global maxt) , _ -> let log = open_out (st.sasarg.topo ^ ".log") in let newdot_fn = (Filename.chop_extension st.sasarg.topo) ^ "_wi.dot" in let newdot = open_out newdot_fn in + let search_kind = match st.sasarg.init_search with Local _ -> "local" | _ -> "global" in let run s = moves := 0; rounds := 0; @@ -245,7 +247,8 @@ let () = if res = n then ( Printf.printf " (%s)\n%!" (StringOf.env_rif s.config st.network); Printf.fprintf newdot "%s\n" (SimuState.to_dot s); - Printf.printf "%s and %s have been generated\n" (s.sasarg.topo ^ ".log") newdot_fn; + Printf.printf "%s and %s have been generated using a %s search\n" + (s.sasarg.topo ^ ".log") newdot_fn search_kind; flush_all(); close_out newdot; close_out log; @@ -257,7 +260,12 @@ let () = else res in - let st = (WorstInit.fchc log run st maxt) in + let st = + if search_kind = "local" then + WorstInit.fchc log run st maxt + else + WorstInit.global log run st maxt + in Printf.printf " (%s)\n%!" (StringOf.env_rif st.config st.network); Printf.fprintf newdot "%s\n" (SimuState.to_dot st); Printf.printf "%s and %s have been generated\n" (st.sasarg.topo ^ ".log") newdot_fn; -- GitLab