[jboss-svn-commits] JBL Code SVN: r15151 - labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sun Sep 16 08:33:35 EDT 2007


Author: ge0ffrey
Date: 2007-09-16 08:33:33 -0400 (Sun, 16 Sep 2007)
New Revision: 15151

Added:
   labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Score_calculation.xml
   labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Solver_configuration.xml
   labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/screenshotSolvedNQueens8.png
Modified:
   labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Local_Search_Solver.xml
   labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Solver_introduction.xml
Log:
section 2 & 3

Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Local_Search_Solver.xml
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Local_Search_Solver.xml	2007-09-16 05:17:24 UTC (rev 15150)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Local_Search_Solver.xml	2007-09-16 12:33:33 UTC (rev 15151)
@@ -30,4 +30,10 @@
     <para>Drools-solver's local search implementation combines both and offers
     additional support for benchmarking etc.</para>
   </section>
+
+  <section>
+    <title>Getting started</title>
+
+    <para></para>
+  </section>
 </section>
\ No newline at end of file

Added: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Score_calculation.xml
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Score_calculation.xml	                        (rev 0)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Score_calculation.xml	2007-09-16 12:33:33 UTC (rev 15151)
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section>
+  <title>Score calculation with a rule engine</title>
+
+  <section>
+    <title>Rule based score calculation</title>
+
+    <para>Score calculation of a planning problem is based on constraints
+    (such as hard constraints, soft constraints, rewards, ...). A rules
+    engine, such as drools, make it easy to implement those constraints as
+    <emphasis>score rules</emphasis>.</para>
+
+    <para>Here's an example of a constraint implemented as a score rule in
+    drools:</para>
+
+    <example>
+      <title>Score rule for multiple queens on the same horizontal
+      line</title>
+
+      <programlisting>rule "multipleQueensHorizontal"
+  when
+    $q1 : Queen($id : id, $y : y);
+    $q2 : Queen(id &gt; $id, y == $y);
+  then
+    // trigger a change in the score
+end</programlisting>
+    </example>
+
+    <para>This score rule will fire once for each 2 queens with the same
+    <literal>y</literal>. The <literal>(id &gt; $id)</literal> condition is
+    needed to assure that for 2 queens a and b, it can only fire for (a,b) and
+    not for (b,a), (a,a) or (b,b).</para>
+
+    <para>It's recommended to use drools in forward-chaining mode (which is
+    the default), as for most solver implementations this will create the
+    effect of a <emphasis>delta based score calculation</emphasis> instead of
+    a full score calculation on each solution evaluation. For example, if
+    queen a moves from y <literal>0</literal> to <literal>3</literal>, it
+    won't bother to recalculate the "multiple queens on the same horizontal
+    line" constraint for queens with y <literal>1</literal> or
+    <literal>2</literal>. This is a huge performance gain. <emphasis
+    role="bold">Drools-solver gives you this huge performance gain without
+    forcing you to write very complicated delta based score calculation
+    algorithms.</emphasis> Just let the drools rule engine do the hard
+    work.</para>
+
+    <para><emphasis role="bold">Adding more constraints is scalable and
+    easy</emphasis> (if you understand the drools rule syntax). This allows
+    you to add it a bunch of soft constraint score rules on top of the hard
+    constraints score rules with few effort. For example, for a freight
+    routing problem you could add a soft constraint to avoid the certain
+    flagged highways at rush hour.</para>
+  </section>
+
+  <section>
+    <title>The ScoreCalculator interface</title>
+
+    <para>The <literal>ScoreCalculator</literal> interface allows the solver
+    to calculate the score of the currently evaluated solution. The score must
+    a <literal>Number</literal> instance and the instance type (for example
+    <literal>Double</literal> or <literal>Integer</literal>) must be stable
+    through the problem.</para>
+
+    <para>The solver aims to find the solution with the highest score. Most
+    planning problems tend to use negative scores (the amount of negative
+    constraints being broken) with an impossible perfect score of 0.</para>
+
+    <para>A <literal>ScoreCalculator</literal> instance is configured in the
+    solver configuration:</para>
+
+    <programlisting>    &lt;scoreCalculator&gt;
+        &lt;scoreCalculatorType&gt;SIMPLE&lt;/scoreCalculatorType&gt;
+    &lt;/scoreCalculator&gt;</programlisting>
+
+    <para>There are a couple of build-in <literal>ScoreCalculator</literal>
+    implementations:</para>
+
+    <itemizedlist>
+      <listitem>
+        <para>SIMPLE: A <literal>SimpleScoreCalculator</literal> instance
+        which has a <literal>setScore(Number)</literal> method for use in the
+        score rules.</para>
+      </listitem>
+
+      <listitem>
+        <para>HARD_AND_SOFT_CONSTRAINTS: A
+        <literal>HardAndSoftConstraintScoreCalculator</literal> instance,
+        which has a <literal>setHardConstraintsBroken(Number)</literal> and a
+        <literal>setSoftConstraintsBroken(Number)</literal> method for use in
+        the score rules.</para>
+      </listitem>
+
+      <listitem>
+        <para>DYNAMIC_HARD_AND_SOFT_CONSTRAINTS: A special
+        <literal>HardAndSoftConstraintScoreCalculator</literal> instance, for
+        more information see the javadocs. </para>
+      </listitem>
+    </itemizedlist>
+
+    <para>You can plug in your own custom <literal>ScoreCalculator</literal>
+    too.</para>
+
+    <para>The <literal>ScoreCalculator</literal> instance is asserted into the
+    working memory as a global called <literal>scoreCalculator</literal>. Your
+    score rules will (indirectly) update that instance. Usually you 'll make a
+    single rule as an aggregation of the other rules to update the
+    score:</para>
+
+    <programlisting>global SimpleScoreCalculator scoreCalculator;
+
+// ...
+
+rule "multipleQueensHorizontal"
+  // ...
+end
+
+rule "multipleQueensAscendingDiagonal"
+  // ...
+end
+
+rule "multipleQueensDescendingDiagonal"
+  // ...
+end
+
+rule "constraintsBroken"
+  when
+    $hardCount : Number() from accumulate(
+       $w : ...,
+       count($w)
+    );
+  then
+    scoreCalculator.setScore(- $hardCount);
+end</programlisting>
+  </section>
+
+  <section>
+    <title>Tips and tricks</title>
+
+    <itemizedlist>
+      <listitem>
+        <para>If you know a certain constraint can never be broken, don't
+        bother writing a score rule for it. For example the NQueens example
+        doesn't have a "multipleQueensVertical" rule because a queen's
+        <literal>x</literal> never changes. </para>
+      </listitem>
+
+      <listitem>
+        <para>Verify that your score calculation happens in the correct Number
+        type. If you're making the sum of nothing but integer values, don't
+        let drools use Double's or your performance will hurt.</para>
+      </listitem>
+    </itemizedlist>
+  </section>
+</section>
\ No newline at end of file

Added: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Solver_configuration.xml
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Solver_configuration.xml	                        (rev 0)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Solver_configuration.xml	2007-09-16 12:33:33 UTC (rev 15151)
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section>
+  <title>Solver configuration</title>
+
+  <section>
+    <title>The Solver interface</title>
+
+    <para>Every build-in solver implemented in drools-solver implements the
+    <literal>Solver</literal> interface:</para>
+
+    <programlisting>public interface Solver {
+
+    void setStartingSolution(Solution solution);
+
+    Number getBestScore();
+    Solution getBestSolution();
+    
+    void solve();
+
+    // ...
+
+}</programlisting>
+
+    <para>Solving a planning problem with drools-solver consists out of 4
+    steps:</para>
+
+    <orderedlist>
+      <listitem>
+        <para>Build a solver, for example a tabu search solver for any NQueens
+        puzzle.</para>
+      </listitem>
+
+      <listitem>
+        <para>Set a starting solution on the solver, for example an 4 Queens
+        puzzle instance.</para>
+      </listitem>
+
+      <listitem>
+        <para>Solve it.</para>
+      </listitem>
+
+      <listitem>
+        <para>Get the best solution found by the solver.</para>
+      </listitem>
+    </orderedlist>
+
+    <para>A <literal>Solver</literal> should currently directly be accessed
+    from a single thread. Support from accessing it from a different thread,
+    for example to finish solving early or to change the problem facts in
+    real-time, will be added in future releases.</para>
+  </section>
+
+  <section>
+    <title>Building a solver</title>
+
+    <para>You can build a <literal>Solver</literal> instance with the
+    <literal>XmlSolverConfigurer</literal> by configuring it with a solver
+    configuration xml file:</para>
+
+    <programlisting>    XmlSolverConfigurer configurer = new XmlSolverConfigurer();
+    configurer.configure("/org/drools/solver/examples/nqueens/solver/nqueensSolverConfig.xml");
+    Solver solver = configurer.buildSolver();</programlisting>
+
+    <para>A basic solver configuration file looks something like this:</para>
+
+    <programlisting>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;localSearchSolver&gt;
+    &lt;scoreDrl&gt;/org/drools/solver/examples/nqueens/solver/nQueensScoreRules.drl&lt;/scoreDrl&gt;
+    &lt;scoreCalculator&gt;
+        &lt;scoreCalculatorType&gt;SIMPLE&lt;/scoreCalculatorType&gt;
+    &lt;/scoreCalculator&gt;
+    &lt;finish&gt;
+        &lt;feasableScore&gt;0.0&lt;/feasableScore&gt;
+    &lt;/finish&gt;
+    &lt;selector&gt;
+        &lt;moveFactoryClass&gt;org.drools.solver.examples.nqueens.solver.NQueensMoveFactory&lt;/moveFactoryClass&gt;
+    &lt;/selector&gt;
+    &lt;accepter&gt;
+        &lt;completeSolutionTabuSize&gt;1000&lt;/completeSolutionTabuSize&gt;
+    &lt;/accepter&gt;
+    &lt;forager&gt;
+        &lt;foragerType&gt;MAX_SCORE_OF_ALL&lt;/foragerType&gt;
+    &lt;/forager&gt;
+&lt;/localSearchSolver&gt;</programlisting>
+
+    <para>This is a tabu search configuration (which is a form of local
+    search) for NQueens. We 'll explain the various parts of a configuration
+    later in this manual.</para>
+
+    <para><emphasis role="bold">Drools-solver makes it relatively easy to
+    switch a solver type just by changing the configuration.</emphasis>
+    There's even a benchmark utility which allows you to play out different
+    configurations against each other and report the most appropriate
+    configuration for your problem. You could for example play out tabu search
+    versus simulated annealing, on a set of instances of your planning
+    problem.</para>
+  </section>
+
+  <section>
+    <title>The Solution interface</title>
+
+    <para>A Solver can only solve 1 problem at a time. One problem has a lot
+    of solutions, but few optimal solutions.</para>
+
+    <para>You need to present the problem as a starting
+    <literal>Solution</literal> instance to the Solver. Usually you will make
+    that starting solution with a simple filler algorithm, for example: all
+    queens on a different x and all on y = 0. It will probably be far from
+    optimal, but that's ok, as it's the solver's job to find a much better
+    solution.</para>
+
+    <para>Here is the <literal>Solution</literal> interface:</para>
+
+    <programlisting>public interface Solution {
+
+    Solution cloneSolution();
+
+    Collection&lt;? extends Object&gt; getFacts();
+
+}</programlisting>
+
+    <para>Most solvers use the <literal>cloneSolution()</literal> method to
+    clone the solution each time they encounter a new best solution. The
+    <literal>cloneSolution()</literal> method should clone no more and no less
+    than the parts of the <literal>Solution</literal> that can change during
+    solving. For example, in the lesson schedule example the lessons are
+    cloned, but teachers, groups and timeslots are not cloned because only a
+    lesson's appointed timeslot changes during solving:</para>
+
+    <programlisting>    /**
+     * Clone will only deep copy the lessons
+     */
+    public LessonSchedule cloneSolution() {
+        LessonSchedule clone = new LessonSchedule();
+        clone.timeslotList = timeslotList; // No Deep copy
+        clone.teacherList = teacherList; // No Deep copy
+        clone.groupList = groupList; // No Deep copy
+        List&lt;Lesson&gt; clonedLessonList = new ArrayList&lt;Lesson&gt;(lessonList.size());
+        for (Lesson lesson : lessonList) {
+            clonedLessonList.add(lesson.clone());
+        }
+        clone.lessonList = clonedLessonList;
+        return clone;
+    }</programlisting>
+
+    <para>The <literal>NQueens</literal> implementation just clones all
+    <literal>Queen</literal> instances.</para>
+
+    <para>All Objects returned by the <literal>getFacts()</literal> method
+    will be asserted into the drools working memory. Those facts can be used
+    by the score calculation rules. For example, <literal>NQueens</literal>
+    just returns all <literal>Queen</literal> instances.</para>
+
+    <programlisting>    public Collection&lt;? extends Object&gt; getFacts() {
+        return queenList;
+    }</programlisting>
+  </section>
+
+  <section>
+    <title>Solving a problem</title>
+
+    <para>Solving a problem is quite easy once you have a solver and the
+    starting solution:</para>
+
+    <programlisting>    solver.setStartingSolution(startingSolution);
+    solver.solve();
+    Solution bestSolution = solver.getBestSolution();</programlisting>
+
+    <para>The <literal>solve()</literal> method will take a long time
+    (depending on the problem size and the solver configuration). After a
+    problem is solved, you can reuse the same solver to solve another problem
+    (of the same problem type).</para>
+  </section>
+</section>
\ No newline at end of file

Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Solver_introduction.xml
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Solver_introduction.xml	2007-09-16 05:17:24 UTC (rev 15150)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Solver_introduction.xml	2007-09-16 12:33:33 UTC (rev 15151)
@@ -9,6 +9,32 @@
     module of drools-solver. The API is far from stable and backward
     incompatible changes occur now and then. A recipe to upgrade and apply
     those API changes between versions will be maintained soon.</para>
+
+    <para>No releases have been made yet, but you can easily build it from
+    source yourself by checking out drools and building with the solver
+    profile:</para>
+
+    <programlisting>$ svn checkout http://anonsvn.labs.jboss.com/labs/jbossrules/trunk/ drools
+...
+$ cd drools
+$ mvn -Psolver clean install
+...</programlisting>
+
+    <para>After that, you can run an example directly from the command line
+    like this:</para>
+
+    <programlisting>$ cd drools-solver/drools-solver-examples/
+$ mvn exec:java -Dexec.mainClass="org.drools.solver.examples.nqueens.app.NQueensApp"
+...</programlisting>
+
+    <para>Here's a screenshot of the NQueens example, which is the simplest of
+    all the examples:</para>
+
+    <mediaobject>
+      <imageobject>
+        <imagedata fileref="screenshotSolvedNQueens8.png" />
+      </imageobject>
+    </mediaobject>
   </section>
 
   <section>
@@ -55,7 +81,7 @@
       </listitem>
     </itemizedlist>
 
-    <para>Usually a planning problem consists out of a number of constraints.
+    <para>A planning problem consists out of a number of constraints.
     Generally, there are 3 types of constraints:</para>
 
     <itemizedlist>
@@ -81,27 +107,28 @@
     </itemizedlist>
 
     <para>The constraints define the score function of a planning problem.
-    Usually a planning problems has a very large number of possible solutions.
-    Each solution has a score. Usually, most solutions are not feasible,
+    Planning problems tend to have a very large number of possible solutions.
+    Each solution has a score. Most of those solutions are not feasible,
     because they break a negative hard constraint. Usually, of all the
-    feasible solutions (if any), there is only 1 or very few optimal
-    solutions.</para>
+    feasible solutions (if any), there is only 1 optimal solution, but
+    sometimes there are a few.</para>
 
     <para>The drools rule engine turns out to be a very good way to implement
-    a score function a number of rule constraints.</para>
+    a score function based on a number of rule constraints.</para>
   </section>
 
   <section>
     <title>Types of solvers</title>
 
     <para>Different solvers solve problems in different ways. Each type has
-    advantages and disadvantages. These are a few of the solver types.</para>
+    advantages and disadvantages. We 'll roughly discuss a few of the solver
+    types. You can safely skip this section.</para>
 
     <section>
       <title>Brute force</title>
 
       <para>Brute force creates and evaluates every possible solution, usually
-      by create a search tree.</para>
+      by creating a search tree.</para>
 
       <para>Advantages:</para>
 
@@ -150,7 +177,7 @@
 
       <itemizedlist>
         <listitem>
-          <para>It scales very badly.</para>
+          <para>It still scales very badly.</para>
         </listitem>
       </itemizedlist>
 
@@ -340,11 +367,12 @@
         </mediaobject>
       </figure>
 
-      <para>A Queen instance has an x (its column, for example: 1 is column A,
-      2 is column B, ...) and a y (its row, for example: 1 is row 1, 2 is row
-      2, ...). Based on the x and y, the ascending diagonal line as well as
-      the descending diagonal line can be calculated. The x and y indexes
-      start from the upper left corner of the chessboard.</para>
+      <para>A <literal>Queen</literal> instance has an x (its column, for
+      example: 0 is column A, 1 is column B, ...) and a y (its row, for
+      example: 0 is row 1, 1 is row 2, ...). Based on the x and y, the
+      ascending diagonal line as well as the descending diagonal line can be
+      calculated. The x and y indexes start from the upper left corner of the
+      chessboard.</para>
 
       <table>
         <title>A solution for the 4 queens puzzle show in the domain
@@ -377,23 +405,23 @@
 
               <entry>A2</entry>
 
+              <entry>0</entry>
+
               <entry>1</entry>
 
-              <entry>2</entry>
+              <entry>1 (**)</entry>
 
-              <entry>3 (**)</entry>
-
               <entry>-1</entry>
             </row>
 
             <row>
               <entry>B1</entry>
 
-              <entry>2</entry>
+              <entry>1</entry>
 
-              <entry>1 (*)</entry>
+              <entry>0 (*)</entry>
 
-              <entry>3 (**)</entry>
+              <entry>1 (**)</entry>
 
               <entry>1</entry>
             </row>
@@ -401,11 +429,11 @@
             <row>
               <entry>C3</entry>
 
-              <entry>3</entry>
+              <entry>2</entry>
 
-              <entry>3</entry>
+              <entry>2</entry>
 
-              <entry>6</entry>
+              <entry>4</entry>
 
               <entry>0</entry>
             </row>
@@ -413,11 +441,11 @@
             <row>
               <entry>D1</entry>
 
-              <entry>4</entry>
+              <entry>3</entry>
 
-              <entry>1 (*)</entry>
+              <entry>0 (*)</entry>
 
-              <entry>5</entry>
+              <entry>3</entry>
 
               <entry>3</entry>
             </row>
@@ -425,10 +453,10 @@
         </tgroup>
       </table>
 
-      <para>A single NQueens instance contains a list of all Queens. It is
-      effectively the <emphasis>Solution</emphasis> object which will be
-      supplied to and retrieved from drools-solver. Notice that in the 4
-      queens example, NQueens's <literal>getN()</literal> method will always
+      <para>A single <literal>NQueens</literal> instance contains a list of
+      all Queens. It is the <literal>Solution</literal> implementation which
+      will be supplied to and retrieved from drools-solver. Notice that in the
+      4 queens example, NQueens's <literal>getN()</literal> method will always
       return 4.</para>
 
       <para>You can find the source code of this example (as well as well as

Added: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/screenshotSolvedNQueens8.png
===================================================================
(Binary files differ)


Property changes on: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/screenshotSolvedNQueens8.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream




More information about the jboss-svn-commits mailing list