From eo at rhyhann.net Sat Dec 27 05:58:39 2008 From: eo at rhyhann.net (Othmane Benkirane (Rhyhann)) Date: Sat, 27 Dec 2008 10:58:39 +0000 Subject: [gecoder-users] May, not must (preference instead of obligation) Message-ID: <20081227105839.704a40e1@eo> Hi, I would like to use Gecoder for a scholar scedule generator, and Gecode is the library I have chosen :). I must use it for obligations constraints, but it will also be awesome if you point me some trick on how to make preferences possible (In short, I would say "If you can make this, it's awesome (and add a good note to it), and if you can't, just go to the next step, it's not obliged (and add a bad note to it)") Thank you by advance! Othmane Benkirane. From rubyforge at lokorin.org Mon Dec 29 06:03:29 2008 From: rubyforge at lokorin.org (Andreas Launila) Date: Mon, 29 Dec 2008 12:03:29 +0100 Subject: [gecoder-users] May, not must (preference instead of obligation) In-Reply-To: <20081227105839.704a40e1@eo> References: <20081227105839.704a40e1@eo> Message-ID: <4958AE81.8030809@lokorin.org> Othmane Benkirane (Rhyhann) wrote: > I must use it for obligations constraints, but it will also be awesome > if you point me some trick on how to make preferences possible (In > short, I would say "If you can make this, it's awesome (and add a good > note to it), and if you can't, just go to the next step, it's not > obliged (and add a bad note to it)") > If I understand correctly then you want to have optional constraints that should be satisfied when possible. One way to do that is to use reified constraints, having a boolean variable represent whether or not an optional constraint has been satisfied. You can then assign a weight to each optional constraint, i.e. assign a measure of goodness of each optional constraint being satisfied. You can then use the optimization search to maximize the level of goodness of the solution, e.g. have it satisfy as many of the optional constraints as possible. An example with three optional constraints where the third is considered three times as important as each of the first two: require 'rubygems' require 'gecoder' solution = Gecode.maximize(:goodness) do x_is_an int_var(0..9) optional_satisfied = bool_var_array(3) optional_satisfied_int = int_var_array( optional_satisfied.size, 0..1) goodness_is_an int_var # Three optional constraints. x.must_be.less_than(5, :reify => optional_satisfied[0]) x.squared.must_be.less_than(16, :reify => optional_satisfied[1]) x.squared.must_be.greater_than(36, :reify => optional_satisfied[2]) # Channel the boolean variables with integer variables (basically # cast the boolean variables into integer variables). optional_satisfied_int.each_with_index do |int, i| int.must == optional_satisfied[i] end # Weight the optional constraints so that the third is three # times as important as the first two. I'm keeping it verbose # to make it simple to see what is going on. goodness.must == optional_satisfied_int[0] * 1 + optional_satisfied_int[1] * 1 + optional_satisfied_int[2] * 3 branch_on x branch_on goodness end p solution.x.value p solution.goodness.value The above will satisfy the third optional constraint, but not the two first (since they contradict each other and the third constraint is worth more in terms of goodness). Playing around with the weights has the desired effect. [1] http://gecoder.rubyforge.org/documentation/operands/index.html#options [2] http://gecoder.rubyforge.org/documentation/searching_for_solutions.html#searching_for_the_optimal_solution -- Andreas Launila