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
next prev parent 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