caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Diego Olivier FERNANDEZ PONS <diego.fernandez_pons@etu.upmc.fr>
To: Pietro Abate <Pietro.Abate@anu.edu.au>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Reordering continuations (was :Type inference inside exceptions ?)
Date: Mon, 16 Oct 2006 11:25:15 +0200	[thread overview]
Message-ID: <20061016112515.ircc0o7sgsssowcs@webmail.etu.upmc.fr> (raw)
In-Reply-To: <20061014215653.by7emka3kgscccsc@webmail.etu.upmc.fr>

     Bonjour,

Here is some code that shows the effect of reordering continuations in  
a combinatorial problem. The first one is the minimum cardinality  
subset-sum problem, the second returns the order in which the leaves  
of the search tree are visited.

Each time a solution is found, the number of failures is printed. This  
gives an idea of how much time was spent to find the solution.

(* subsetsum in depth first search *)
# let p = smc 47 [39;32;20;19;16;9;1] in solve p (new stack);;
0 fails : 39 1 1 1 1 1 1 1 1
8 fails : 32 9 1 1 1 1 1 1
47 fails : 20 16 9 1 1
61 fails : 20 9 9 9
118 fails : 19 19 9
- : int list list * int =
([[39; 1; 1; 1; 1; 1; 1; 1; 1]; [32; 9; 1; 1; 1; 1; 1; 1]; [20; 16; 9; 1; 1];
   [20; 9; 9; 9]; [19; 19; 9]],
  457)

(* subset sum in limited discrepancy search *)
# let p = smc 47 [39;32;20;19;16;9;1] in solve p (new queue);;
0 fails : 39 1 1 1 1 1 1 1 1
0 fails : 32 9 1 1 1 1 1 1
16 fails : 19 19 9
- : int list list * int =
([[39; 1; 1; 1; 1; 1; 1; 1; 1]; [32; 9; 1; 1; 1; 1; 1; 1]; [19; 19; 9]], 459

The second example builds a tree which leaves are labelled from 0 to  
2^n - 1 from left to right. The order in which the leaves are visited  
is returned.

# let p = label 4 in solve p (new stack);;
- : int list * int =
([0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15], 0)

# let p = label 4 in solve p (new queue);;
- : int list * int =
([0; 8; 4; 2; 1; 12; 10; 9; 6; 5; 3; 14; 13; 11; 7; 15], 0)

Here is the complete code

class type ['a] continuationQueue =
   object
     method push : 'a -> unit
     method pop : 'a
     method is_empty : bool
     method length : int
   end

class ['a] queue =
   (object
     val contents = (Queue.create () : 'a Queue.t)
     method push = fun x -> Queue.push x contents
     method pop = Queue.pop contents
     method is_empty = Queue.is_empty contents
     method length = Queue.length contents
   end : ['a] continuationQueue)

class ['a] stack =
   (object
     val contents = (Stack.create () : 'a Stack.t)
     method push = fun x -> Stack.push x contents
     method pop = Stack.pop contents
     method is_empty = Stack.is_empty contents
     method length = Stack.length contents
   end : ['a] continuationQueue)

type 'a environment = {
     mutable backtracks : int;
     mutable objective : int;
     mutable queue : 'a queue
  }

exception Fail

type 'a continuation = Cont of (unit -> 'a)

let rec print_list = function
   | [] -> print_newline()
   | x :: tail -> print_int x; print_string " "; print_list tail

let rec min_card env = fun to_reach chosen candidates ->
   if (to_reach = 0) then
     match compare env.objective (List.length chosen) with
     | n when n <= 0 ->
	env.backtracks <- env.backtracks + 1;
	raise Fail
     | _ ->
	env.objective <- List.length chosen;
	print_int env.backtracks;
	print_string " fails : ";
	print_list (List.rev chosen);
	(List.rev chosen)
   else
     match candidates with
     | [] ->
	env.backtracks <- env.backtracks + 1;
	raise Fail
     | x :: tail when x > to_reach -> min_card env to_reach chosen tail
     | x :: tail ->
	let c = Cont (fun () -> min_card env to_reach chosen tail) in
	env.queue#push c;
	min_card env (to_reach - x) (x :: chosen) candidates

let smc = fun to_reach list ->
   function env ->
     let c = Cont (function () -> min_card env to_reach [] list) in
     env.queue#push c; env

let rec label_nodes env = fun count remaining_depth ->
   match remaining_depth with
     | 0 -> count
     | n ->
	let c = Cont (fun () -> label_nodes env (2 * count + 1) (n - 1)) in
	  env.queue#push c;
	  label_nodes env (2 * count) (n - 1)

let label = function depth ->
   function env ->
     let c = Cont (fun () -> label_nodes env 0 depth) in
       env.queue#push c; env

let rec solve_rec = function env ->
   if env.queue#is_empty then []
   else
     let Cont c = env.queue#pop in
     try
       let s = c () in
       s :: solve_rec env
     with Fail -> solve_rec env

let solve = fun f queue ->
   let env = { backtracks = 0; objective = max_int; queue = queue } in
   let solutions = solve_rec (f env) in
   (solutions, env.backtracks)

         Diego Olivier


  reply	other threads:[~2006-10-16  9:25 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-10-06 18:16 Type inference inside exceptions ? Diego Olivier FERNANDEZ PONS
2006-10-06 20:20 ` [Caml-list] " ketty .
2006-10-10 10:28   ` Diego Olivier FERNANDEZ PONS
2006-10-11 22:50 ` Stéphane Glondu
2006-10-13 12:23   ` Diego Olivier FERNANDEZ PONS
2006-10-13 12:42     ` Pietro Abate
2006-10-14 19:56       ` Reordering continuations (was :Type inference inside exceptions ?) Diego Olivier FERNANDEZ PONS
2006-10-16  9:25         ` Diego Olivier FERNANDEZ PONS [this message]
2006-10-17 12:33           ` [Caml-list] " Diego Olivier FERNANDEZ PONS
2006-10-19  7:32             ` Looking for references to usage of ocaml in data mining, knowleadge discovery, etc  Dr. Axel Poigné 
2006-10-19 14:06               ` [Caml-list] " Markus Mottl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20061016112515.ircc0o7sgsssowcs@webmail.etu.upmc.fr \
    --to=diego.fernandez_pons@etu.upmc.fr \
    --cc=Pietro.Abate@anu.edu.au \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).