[jboss-svn-commits] JBL Code SVN: r15292 - labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sat Sep 22 16:51:57 EDT 2007
Author: ge0ffrey
Date: 2007-09-22 16:51:57 -0400 (Sat, 22 Sep 2007)
New Revision: 15292
Modified:
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Local_Search_Solver.xml
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/Section-Solver_introduction.xml
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/allStepsNQueens04.png
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/allStepsNQueens04.svg
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/decideNextStepNQueens04.png
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/decideNextStepNQueens04.svg
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/partiallySolvedNQueens04Explained.png
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/partiallySolvedNQueens04Explained.svg
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/possibleMovesNQueens04.png
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/possibleMovesNQueens04.svg
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/singleMoveNQueens04.png
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/singleMoveNQueens04.svg
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/solvedNQueens04.png
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/solvedNQueens04.svg
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/unsolvedNQueens04.png
labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/unsolvedNQueens04.svg
Log:
last chapter of the solver manual
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-22 16:53:16 UTC (rev 15291)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Local_Search_Solver.xml 2007-09-22 20:51:57 UTC (rev 15292)
@@ -5,79 +5,75 @@
<section>
<title>Overview</title>
- <para>A local search algoritm and the drools rule engine turn out to be a
- really nice combination, because:</para>
+ <para>In number of possible solutions for a planning problem can be mind
+ blowing. For example:</para>
<itemizedlist>
<listitem>
- <para>A rule engine such as Drools is great for <emphasis
- role="bold">calculating the score</emphasis> of a solution of a
- planning problem. It make it easy to add additional soft or hard
- constraints such as "a teacher shouldn't teach more then 7 hours a
- day". However it tends to be too complex to use to actually find new
- solutions.</para>
+ <para>4 queens has 256 possible solutions (<literal>n ^ n</literal>)
+ and 4 optimal solutions.</para>
</listitem>
<listitem>
- <para>A local search algoritm is great at <emphasis
- role="bold">finding new improving solutions</emphasis> for a planning
- problem, without brute-forcing every possibility. However it needs to
- know the score of a solution and normally offers no support in
- calculating that score.</para>
+ <para>5 queens has 3125 possible solutions (<literal>n ^ n</literal>)
+ and 1 optimal solution.</para>
</listitem>
- </itemizedlist>
- <para>Drools-solver's local search implementation combines both and offers
- additional support for benchmarking etc.</para>
- </section>
+ <listitem>
+ <para>8 queens has 16777216 possible solutions (<literal>n ^
+ n</literal>) and 92 optimal solutions.</para>
+ </listitem>
- <section>
- <title>A Move</title>
+ <listitem>
+ <para>Most real-life planning problems have an incredible number of
+ possible solutions and only 1 optimal solution.</para>
+ </listitem>
+ </itemizedlist>
- <para></para>
- </section>
+ <para>An algorithm that checks every possible solution (even with pruning)
+ can easily run for a couple of years on real-life planning problem. Most
+ of the time, we 're happy with a feasible solution found in a limited
+ amount of time. Local search is an algorithm that finds a feasible
+ solution relatively fast. Because it acts very much like a human, it's
+ also pretty natural to program.</para>
- <section>
- <title>A step</title>
+ <para>Local search solves a problem making a move on the current solution
+ to change it into a better solution. It than does that number of times
+ till it is satisfied with the solution. It starts with the starting
+ solution.</para>
- <para></para>
- </section>
+ <para>A local search algorithm and the drools rule engine turn out to be a
+ really nice combination, because:</para>
- <section>
- <title>Deciding the next step</title>
+ <itemizedlist>
+ <listitem>
+ <para>A rule engine such as Drools is <emphasis role="bold">great for
+ calculating the score</emphasis> of a solution of a planning problem.
+ It make it easy to add additional soft or hard constraints such as "a
+ teacher shouldn't teach more then 7 hours a day". However it tends to
+ be too complex to use to actually find new solutions.</para>
+ </listitem>
- <para></para>
+ <listitem>
+ <para>A local search algorithm is <emphasis role="bold">great at
+ finding new improving solutions</emphasis> for a planning problem,
+ without brute-forcing every possibility. However it needs to know the
+ score of a solution and normally offers no support in calculating that
+ score.</para>
+ </listitem>
+ </itemizedlist>
- <section>
- <title>Selector</title>
-
- <para></para>
- </section>
-
- <section>
- <title>Accepter</title>
-
- <para></para>
- </section>
-
- <section>
- <title>Forager</title>
-
- <para></para>
- </section>
+ <para>Drools-solver's local search implementation combines both. On top of
+ that, it also offers additional support for benchmarking etc.</para>
</section>
<section>
- <title>Finish</title>
+ <title>A move</title>
- <para></para>
- </section>
+ <para>A move is the change from a solution A to a solution B. For example,
+ here you can see a single move on the starting solution of 4 queens that
+ moves a single queen to another row:</para>
- <section>
- <title>ggg</title>
-
- <para>ggg</para>
-
<figure>
<title>A single move (4 queens example)</title>
@@ -92,8 +88,167 @@
</mediaobject>
</figure>
- <para>ggg</para>
+ <para>A move can have a small or large impact. In the above example, the
+ move of queen C0 to C2 is a small move. Some moves are of the same type.
+ Here are some possibilities for move types in 4 queens:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Move a single queen to another row. This is a small move. For
+ example C0 to C2.</para>
+ </listitem>
+
+ <listitem>
+ <para>Move all queens a number of rows down or up. This a big
+ move.</para>
+ </listitem>
+
+ <listitem>
+ <para>Move a single queen to another column. This is a small move. For
+ example queen on C2 to A0 (placing it on top of queen A0).</para>
+ </listitem>
+
+ <listitem>
+ <para>Add a queen to board at a certain row and column.</para>
+ </listitem>
+
+ <listitem>
+ <para>Remove a queen from the board.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Because we have decided that all queens will be on the board at all
+ times and each queen has an appointed column (for performance reasons),
+ only the first 2 move types are usable in our example. Furthermore, we 're
+ only using the first move type in the example because we think this gives
+ the best performance, but you are welcome to prove us wrong.</para>
+
+ <para>Each of your move types will be an implementation of the
+ <literal>Move</literal> interface:</para>
+
+ <programlisting>public interface Move {
+
+ boolean isMoveDoable(EvaluationHandler evaluationHandler);
+
+ Move createUndoMove(EvaluationHandler evaluationHandler);
+
+ void doMove(EvaluationHandler evaluationHandler);
+
+}</programlisting>
+
+ <para>Let's take a look at the <literal>Move</literal> implementation for
+ 4 queens which moves a queen to a different row:</para>
+
+ <programlisting>public class YChangeMove implements Move {
+
+ private Queen queen;
+ private int toY;
+
+ public YChangeMove(Queen queen, int toY) {
+ this.queen = queen;
+ this.toY = toY;
+ }
+
+ // ... see below
+
+}</programlisting>
+
+ <para>An instance of <literal>YChangeMove</literal> moves a queen from
+ it's current y to a different y.</para>
+
+ <para>Drool-solver calls the <literal>doMove(WorkingMemory)</literal>
+ method to do a move. The <literal>Move</literal> implementation must
+ notify the working memory of any changes it does on the solution
+ facts:</para>
+
+ <programlisting> public void doMove(WorkingMemory workingMemory) {
+ FactHandle queenHandle = workingMemory.getFactHandle(queen);
+ queen.setY(toY);
+ workingMemory.update(queenHandle, queen);
+ }</programlisting>
+
+ <para>Drools-solver automatically filters out <emphasis>non doable
+ moves</emphasis> by calling the <literal>isDoable(WorkingMemory)</literal>
+ method. A <emphasis>non doable move</emphasis> is:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>A move that changes nothing on the current solution. For example
+ a move in the starting solution to move queen B to y 1 is not
+ doable.</para>
+ </listitem>
+
+ <listitem>
+ <para>A move that is impossible to do on the current solution. For
+ example a move to move a queen B to row 10 is not doable.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>For example a move which moves the queen from it's current row to
+ the same row isn't doable:</para>
+
+ <programlisting> public boolean isMoveDoable(WorkingMemory workingMemory) {
+ int fromY = queen.getY();
+ return fromY != toY;
+ }</programlisting>
+
+ <para>A move that is currently non doable can become doable on a later
+ solution.</para>
+
+ <para>Each move has an <emphasis>undo move</emphasis>: a move (usually of
+ the same type) which does the exact opposite. In the above example the
+ undo move of C0 to C2 would be the move C2 to C0. An undo move can be
+ created from a move, but only before the move has been done on the current
+ solution.</para>
+
+ <programlisting> public Move createUndoMove(WorkingMemory workingMemory) {
+ return new YChangeMove(queen, queen.getY());
+ }</programlisting>
+
+ <para>A move must implement the <literal>equals()</literal> and
+ <literal>hashcode()</literal> methods so that 2 moves which make the same
+ change on a solution are equal.</para>
+
+ <programlisting> public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (o instanceof YChangeMove) {
+ YChangeMove other = (YChangeMove) o;
+ return new EqualsBuilder()
+ .append(queen, other.queen)
+ .append(toY, other.toY)
+ .isEquals();
+ } else {
+ return false;
+ }
+ }
+
+ public int hashCode() {
+ return new HashCodeBuilder()
+ .append(queen)
+ .append(toY)
+ .toHashCode();
+ }</programlisting>
+
+ <para>It's also recommended to implement the <literal>toString()</literal>
+ method as it will allow you to read drools-solver's logging:</para>
+
+ <programlisting> public String toString() {
+ return queen + " => " + toY;
+ }</programlisting>
+
+ <para>Now that we can make a single move, let's take a look at generating
+ moves.</para>
+ </section>
+
+ <section>
+ <title>Move generation</title>
+
+ <para>At each solution, local search will try all possible moves and pick
+ the best move as the step to change to the next solution. It's up to you
+ to generate those moves. Let's take a look at all the possible moves on
+ the starting solution of 4 queens:</para>
+
<figure>
<title>Possible moves at step 0 (4 queens example)</title>
@@ -108,8 +263,58 @@
</mediaobject>
</figure>
- <para>ggg</para>
+ <para>As you can see, not all the moves are doable. At the starting
+ solution we have 12 doable moves (<literal>n * (n - 1)</literal>), one of
+ which will be move which changes the starting solution into the next
+ solution. Notice that the number of possible solutions is 256 (<literal>n
+ ^ n</literal>), much more that the amount of doable moves. Don't make a
+ move to every possible solution. Instead use a number of small moves which
+ can be sequentially combined to get to every possible solution.</para>
+ <para>It's highly recommended that you verify all solutions are connected
+ by your move set. This means that by combining a finite number of moves
+ you can reach any solution from any solution. Otherwise you're already
+ excluding solutions at the start . Especially if you're using only big
+ moves, you should check it. Just because big moves outperform small moves
+ in a short test run, it doesn't mean that they will outperform them on a
+ long test run.</para>
+
+ <para>You can mix different move types. Usually you're better off
+ preferring small moves over big moves because the score delta calculation
+ will pay off more. However, as the traveling tournament example proves, if
+ you can remove a hard constraint by using a certain set of big moves, you
+ can win performance and scalability. Try it yourself: run both the simple
+ (small moves) and the smart (big moves) version of the traveling
+ tournament example. The smart version evaluates a lot less unfeasible
+ solutions.</para>
+
+ <para>Move generation currently happens with a
+ <literal>MoveFactory</literal>:</para>
+
+ <programlisting>public class NQueensMoveFactory extends CachedMoveListMoveFactory {
+
+ public List<Move> createMoveList(Solution solution) {
+ NQueens nQueens = (NQueens) solution;
+ List<Move> moveList = new ArrayList<Move>();
+ for (Queen queen : nQueens.getQueenList()) {
+ for (int n : nQueens.createNList()) {
+ moveList.add(new YChangeMove(queen, n));
+ }
+ }
+ return moveList;
+ }
+
+}</programlisting>
+
+ <para>But we'll be making move generation part of the drl's soon.</para>
+ </section>
+
+ <section>
+ <title>A step</title>
+
+ <para>A step is the winning move. The local search solver tries every move
+ on the current solution and picks the best accepted move:</para>
+
<figure>
<title>Decide the next step at step 0 (4 queens example)</title>
@@ -124,8 +329,17 @@
</mediaobject>
</figure>
- <para>ggg</para>
+ <para>Because the move <emphasis>B0 to 3</emphasis> has the highest score
+ (<literal>-3</literal>), it is picked as the next step. Notice that
+ <emphasis>C0 to 3</emphasis> (not shown) could also have been picked
+ because it also has score <literal>-3</literal>. If multiple moves have
+ the same highest score, one is picked randomly, in this case <emphasis>B0
+ to 3</emphasis>.</para>
+ <para>The step is made and from that new solution, the local search solver
+ tries the possible moves again, to decide the next step after that. It
+ continually does this in a loop, and we get something like this:</para>
+
<figure>
<title>All steps (4 queens example)</title>
@@ -139,5 +353,399 @@
</imageobject>
</mediaobject>
</figure>
+
+ <para>Notice that the local search solver doesn't use a search tree, but a
+ search path. The search path is highlighted by the green arrows. At each
+ step it tries all possible moves, but unless it's the step, it doesn't
+ investigate that solution further. This is one of the reasons why local
+ search is very scalable.</para>
+
+ <para>As you can see, the local search solver solves the 4 queens problem
+ by starting with the starting solution and make the following steps
+ sequentially:</para>
+
+ <orderedlist>
+ <listitem>
+ <para><emphasis>B0 to 3</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>D0 to 2</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>A0 to 1</emphasis></para>
+ </listitem>
+ </orderedlist>
+
+ <para>If we turn on INFO logging, this is reflected into the
+ logging:</para>
+
+ <programlisting>INFO Solving with random seed (0).
+INFO Initial score (-6.0) is starting best score. Updating best solution and best score.
+INFO Step (0), time spend (0) doing next step ([Queen-1] 1 @ 0 => 3).
+INFO New score (-3.0) is better then last best score (-6.0). Updating best solution and best score.
+INFO Step (1), time spend (0) doing next step ([Queen-3] 3 @ 0 => 2).
+INFO New score (-1.0) is better then last best score (-3.0). Updating best solution and best score.
+INFO Step (2), time spend (0) doing next step ([Queen-0] 0 @ 0 => 1).
+INFO New score (0.0) is better then last best score (-1.0). Updating best solution and best score.
+INFO Solved in 3 steps and 15 time millis spend.</programlisting>
+
+ <para>Notice that the logging used the <literal>toString()</literal>
+ method from our <literal>Move</literal> implementation: <literal>[Queen-1]
+ 1 @ 0 => 3</literal>.</para>
</section>
+
+ <section>
+ <title>Getting stuck in local optima</title>
+
+ <para>A simple local search always takes improving moves. This may seem
+ like a good thing, but it's not. It suffers from a number of
+ problems:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>It can get stuck in a local optimum. For example if it reaches a
+ solution X with a score -1 and there is no improving move, it is
+ forces to take a next step that leads to a solution Y with score -2,
+ however it's very real that after that it will pick the step back to
+ solution X with score -1. It will then start looping between solution
+ X and Y.</para>
+ </listitem>
+
+ <listitem>
+ <para>It can start walking in it's own footsteps, picking the same
+ next step at every step.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Luckily drools-solver implements better local searches, such tabu
+ search and simulated annealing which don't have these problems. It's
+ recommended to never use a simple local search, unless you're absolutely
+ sure there are no local optima in your planning problem.</para>
+ </section>
+
+ <section>
+ <title>Deciding the next step</title>
+
+ <para>The local search solver decides the next step with 3
+ components:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>A selector which selects (or generates) the possible moves of
+ the current solution.</para>
+ </listitem>
+
+ <listitem>
+ <para>An accepter which filters out unacceptable moves. It can also
+ weigh the moves it accepts.</para>
+ </listitem>
+
+ <listitem>
+ <para>A forager which gathers all accepted moves and picks the next
+ step from them.</para>
+ </listitem>
+ </itemizedlist>
+
+ <figure>
+ <title>Decide the next step at step 0 (4 queens example)</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="decideNextStepNQueens04.svg" />
+ </imageobject>
+
+ <imageobject>
+ <imagedata fileref="decideNextStepNQueens04.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>In the above example the selector generated the moves shown with the
+ blue lines, the accepter accepted all of them and the forager picked the
+ move <emphasis>B0 to 3</emphasis>.</para>
+
+ <para>If we turn on DEBUG logging, we can see the decision making in the
+ log:</para>
+
+ <programlisting>INFO Solving with random seed (0).
+INFO Initial score (-6.0) is starting best score. Updating best solution and best score.
+DEBUG Move ([Queen-0] 0 @ 0 => 0) ignored because not doable.
+DEBUG Move ([Queen-0] 0 @ 1 => 1) with score (-4.0) and acceptChance (1.0).
+DEBUG Move ([Queen-0] 0 @ 2 => 2) with score (-4.0) and acceptChance (1.0).
+...
+DEBUG Move ([Queen-1] 1 @ 3 => 3) with score (-3.0) and acceptChance (1.0).
+...
+DEBUG Move ([Queen-3] 3 @ 3 => 3) with score (-4.0) and acceptChance (1.0).
+INFO Step (0), time spend (0) doing next step ([Queen-1] 1 @ 0 => 3).
+INFO New score (-3.0) is better then last best score (-6.0). Updating best solution and best score.</programlisting>
+
+ <section>
+ <title>Selector</title>
+
+ <para>A selector is currently based on a <literal>MoveFactory</literal>.
+ We're working on improving this.</para>
+
+ <programlisting> <selector>
+ <moveFactoryClass>org.drools.solver.examples.nqueens.solver.NQueensMoveFactory</moveFactoryClass>
+ </selector></programlisting>
+
+ <para>You're not obligated to generate the same stable set of moves at
+ each step. You could start with generating only big moves initially, and
+ gradually switch to small moves. There's no build-in support for this
+ yet though.</para>
+ </section>
+
+ <section>
+ <title>Accepter</title>
+
+ <para>An accepter is used (together with a forager) to active tabu
+ search, simulated annealing, great deluge, ... For each move it
+ generates an accept chance. If a move is rejected it is given an accept
+ chance of <literal>0.0</literal>.</para>
+
+ <para>You can implement your own <literal>Accepter</literal>, although
+ the build-in accepters should suffice for most needs. You can also
+ combine several accepters, although that's probably a bad idea.</para>
+
+ <section>
+ <title>Tabu search accepter</title>
+
+ <para>When tabu search takes steps it creates tabu's. It does not
+ accept a move as the next step if that move breaks tabu. Drools-solver
+ implements several tabu types:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>Solution tabu</emphasis> makes recently visited
+ solutions tabu. It does not accept a move that leads to one of
+ those solutions.</para>
+
+ <programlisting> <accepter>
+ <completeSolutionTabuSize>1000</completeSolutionTabuSize>
+ </accepter></programlisting>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Move tabu</emphasis> makes recent steps tabu. It
+ does not accept a move equal to one of those steps.</para>
+
+ <programlisting> <accepter>
+ <completeMoveTabuSize>1000</completeMoveTabuSize>
+ </accepter></programlisting>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Undo move tabu </emphasis>makes the undo move of
+ recent steps tabu.</para>
+
+ <programlisting> <accepter>
+ <completeUndoMoveTabuSize>1000</completeUndoMoveTabuSize>
+ </accepter></programlisting>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Property tabu</emphasis> makes a property of
+ recent steps tabu. For example it can make the queen tabu, so that
+ a recently moved queen can't be moved.</para>
+
+ <programlisting> <accepter>
+ <completePropertyTabuSize>1000</completePropertyTabuSize>
+ </accepter></programlisting>
+
+ <para>To use property tabu, your moves must implement the
+ <literal>TabuPropertyEnabled</literal> interface, for
+ example:</para>
+
+ <programlisting>public class YChangeMove implements Move, TabuPropertyEnabled {
+
+ private Queen queen;
+ private int toY;
+
+ // ...
+
+ public List<? extends Object> getTabuPropertyList() {
+ return Collections.singletonList(queen);
+ }
+
+}</programlisting>
+ </listitem>
+ </itemizedlist>
+
+ <para>You can even combine them:</para>
+
+ <programlisting> <accepter>
+ <completeSolutionTabuSize>1000</completeSolutionTabuSize>
+ <completeUndoMoveTabuSize>10</completeUndoMoveTabuSize>
+ </accepter></programlisting>
+
+ <para>Tabu search should be used with a
+ <literal>MaxScoreOfAllForager</literal> or a
+ <literal>FirstImprovingScoreForager</literal>.</para>
+ </section>
+
+ <section>
+ <title>Simulated annealing accepter</title>
+
+ <para>Simulated annealing does not pick the move with the highest
+ score, neither does it evaluate all moves. At least at first. It gives
+ unimproving moves a chance, depending on it's score and the
+ temperature. The temperature depends on how long it has been solving.
+ In the end, it gradually turns into a simple local search, only
+ accepting improving moves.</para>
+
+ <para>Simulated annealing must be used with a
+ <literal>FirstRandomlyAcceptedForager</literal>.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Forager</title>
+
+ <para>A forager gathers all accepted moves and picks the move which is
+ the next step. A forager can choose to allow only a subset of all
+ selected moves to be evaluated, by quitting early if a suitable move has
+ been accepted.</para>
+
+ <para>You can implement your own <literal>Forager</literal>, although
+ the build-in foragers should suffice for most needs.</para>
+
+ <section>
+ <title>Maximum score of all forager</title>
+
+ <para>Allows all selected moves to be evaluated and picks the accepted
+ move with the highest score. If several accepted moves have the
+ highest score, one is picked randomly, weighted on their accept
+ chance.</para>
+
+ <programlisting> <forager>
+ <foragerType>MAX_SCORE_OF_ALL</foragerType>
+ </forager></programlisting>
+ </section>
+
+ <section>
+ <title>First improving score forager</title>
+
+ <para>Picks the first accepted move that improves the score of the
+ current solution. Ignores accept chance.</para>
+ </section>
+
+ <section>
+ <title>First randomly accepted forager</title>
+
+ <para>Generates a random number for each accepted move and if it's
+ below the move's accept chance, it picks it as the next move.</para>
+ </section>
+ </section>
+ </section>
+
+ <section>
+ <title>Best solution</title>
+
+ <para>Because the current solution can degrade (especially in tabu search
+ and simulated annealing), the local search solver remembers the best
+ solution it has encountered through the entire search path. Each time the
+ current solution is better than the last best solution, the current
+ solution is cloned and referenced as the new best solution.</para>
+ </section>
+
+ <section>
+ <title>Finish</title>
+
+ <para>Sooner or later the local search solver will have to stop solving.
+ This can be because of a number of reasons: the time is up, the perfect
+ score has been reached, ... The only thing it can't be is because the
+ optimal solution has been reached (unless you know the perfect score),
+ because a local search solver doesn't know that when it finds the optimal
+ solution. For real-life problems this doesn't turn out much of a problem,
+ because finding the optimal solution would take years (or centuries), so
+ you 'll want to finish early anyway.</para>
+
+ <para>You can configure when a solver search solver needs to stop by
+ configuring a Finish. You can implement your own
+ <literal>Finish</literal>, although the build-in finishes should suffice
+ for most needs.</para>
+
+ <section>
+ <title>TimeMillisSpendFinish</title>
+
+ <para>Finishes when an amount of time has been reached:</para>
+
+ <programlisting> <finish>
+ <maximumMinutesSpend>2</maximumMinutesSpend>
+ </finish></programlisting>
+
+ <para>or</para>
+
+ <programlisting> <finish>
+ <maximumHouresSpend>1</maximumHouresSpend>
+ </finish></programlisting>
+ </section>
+
+ <section>
+ <title>StepCountFinish</title>
+
+ <para>Finishes when an amount of steps has been reached:</para>
+
+ <programlisting> <finish>
+ <maximumStepCount>100</maximumStepCount>
+ </finish></programlisting>
+ </section>
+
+ <section>
+ <title>FeasableScoreFinish</title>
+
+ <para>Finishes when a feasible score has been reached. You can also use
+ this finish if you know the perfect score, for example in 4
+ queens:</para>
+
+ <programlisting> <finish>
+ <feasableScore>0.0</feasableScore>
+ </finish></programlisting>
+ </section>
+
+ <section>
+ <title>UnimprovedStepCountFinish</title>
+
+ <para>Finishes when the best score hasn't improved in a number of
+ steps:</para>
+
+ <programlisting> <finish>
+ <maximumUnimprovedStepCount>100</maximumUnimprovedStepCount>
+ </finish></programlisting>
+
+ <para>If it hasn't improved recently, it's probably not going to improve
+ soon anyway and it's not worth the effort to continue. We have observed
+ in several problems, that once a new best solution is found, the next
+ few step tend to give an even better solution.</para>
+ </section>
+
+ <section>
+ <title>Combining finishes</title>
+
+ <para>Finishes can be combined, for example: finish after 100 step or if
+ a score of 0.0 has been reached:</para>
+
+ <programlisting> <finish>
+ <finishCompositionStyle>OR</finishCompositionStyle>
+ <maximumStepCount>100</maximumStepCount>
+ <feasableScore>0.0</feasableScore>
+ </finish></programlisting>
+
+ <para>Alternatively you can use AND, for example: finish after reaching
+ a feasible score of at least -100 and no improvements in 5 steps:
+ </para>
+
+ <programlisting> <finish>
+ <finishCompositionStyle>AND</finishCompositionStyle>
+ <maximumUnimprovedStepCount>5</maximumUnimprovedStepCount>
+ <feasableScore>-100.0</feasableScore>
+ </finish></programlisting>
+
+ <para>This ensures it doesn't just finish after finding a feasible
+ solution, but also makes any obvious improvements on that solution
+ before finishing.</para>
+ </section>
+ </section>
</section>
\ No newline at end of file
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Score_calculation.xml
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Score_calculation.xml 2007-09-22 16:53:16 UTC (rev 15291)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Score_calculation.xml 2007-09-22 20:51:57 UTC (rev 15292)
@@ -47,8 +47,8 @@
</figure>
<para>In this starting solution the multipleQueensHorizontal score rule
- will fire for 6 queen couples: (a, b), (a, c), (a, d), (b, c), (b, d) and
- (c, d). Because none of the queens are on the same vertical or diagonal
+ will fire for 6 queen couples: (A, B), (A, C), (A, D), (B, C), (B, D) and
+ (C, D). Because none of the queens are on the same vertical or diagonal
line, this starting solution will have a score of <literal>-6</literal>.
An optimal solution of 4 queens has a score of <literal>0</literal>. More
on that later.</para>
@@ -74,12 +74,13 @@
calculation algorithm.</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 little effort. For example, for a freight
- routing problem you could add a soft constraint to avoid the certain
- flagged highways at rush hour.</para>
+ <para><emphasis role="bold">Adding more constraints is <emphasis
+ role="bold">easy and </emphasis>scalable</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 little effort
+ and a reasonable performance cost. 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>
@@ -89,7 +90,7 @@
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>
+ throughout the problem.</para>
<para>The solver aims to find the solution with the highest score.
<emphasis>The best solution</emphasis> is the solution with the highest
@@ -143,10 +144,12 @@
<programlisting>global SimpleScoreCalculator scoreCalculator;
-// ...
-
rule "multipleQueensHorizontal"
- // ...
+ when
+ $q1 : Queen($id : id, $y : y);
+ $q2 : Queen(id > $id, y == $y);
+ then
+ insertLogical(new WorkaroundMultiplePatternAccumulate("multipleQueensHorizontal", $q1, $q2));
end
rule "multipleQueensAscendingDiagonal"
@@ -160,12 +163,46 @@
rule "constraintsBroken"
when
$hardConstraintCount : Number() from accumulate(
- $w : ...,
+ $w : WorkaroundMultiplePatternAccumulate(),
count($w)
);
then
scoreCalculator.setScore(- $hardConstraintCount);
end</programlisting>
+
+ <para>You can also weigh your constraints differently, by multiplying the
+ count of each score rule with its weight. For example in freight routing,
+ you can make 5 broken "avoid crossroads" soft constraints count as much as
+ 1 broken "avoid highways at rush hour" soft constraint.</para>
+
+ <para>Here's an example of all the NQueens constraints written as a single
+ rule, using multi pattern accumulates and making multipleQueensHorizontal
+ constraint outweigh the other constraints 5 times:</para>
+
+ <programlisting>// Warning: This currently triggers backwards chaining instead of forward chaining and seriously hurts performance and scalability.
+rule "constraintsBroken"
+ when
+ $multipleQueensHorizontal : Long()
+ from accumulate(
+ $q1 : Queen($id : id, $y : y)
+ and Queen(id > $id, y == $y),
+ count($q1)
+ );
+ $multipleQueensAscendingDiagonal : Long()
+ from accumulate(
+ $q2 : Queen($id : id, $ascendingD : ascendingD)
+ and Queen(id > $id, ascendingD == $ascendingD),
+ count($q2)
+ );
+ $multipleQueensDescendingDiagonal : Long()
+ from accumulate(
+ $q3 : Queen($id : id, $descendingD : descendingD)
+ and Queen(id > $id, descendingD == $descendingD),
+ count($q3)
+ );
+ then
+ scoreCalculator.setScore(- (5 * $multipleQueensHorizontal) - $multipleQueensAscendingDiagonal - $multipleQueensDescendingDiagonal);
+end</programlisting>
</section>
<section>
@@ -177,7 +214,7 @@
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. This gives a performance gain,
- because </para>
+ because</para>
</listitem>
<listitem>
@@ -196,6 +233,31 @@
as 10 traveling teams. But always remember that premature optimization
is the root of all evil.</para>
</listitem>
+
+ <listitem>
+ <para>Currently, don't allow drools to switch to MVEL mode, for
+ performance. You can avoid this by using <literal>eval</literal>, for
+ example: <literal>eval(day.getIndex() == $day1.getIndex() +
+ 3)</literal>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Currently, don't allow drools to backward chain instead of
+ forward chain, so avoid query's.</para>
+ </listitem>
+
+ <listitem>
+ <para>If performance is important (and it will), use at least java 1.6
+ and always use server mode (<literal>java -server</literal>). We have
+ seen performance increases of 30% by switching from java 1.5 to 1.6
+ and 50% by turning on server mode.</para>
+ </listitem>
+
+ <listitem>
+ <para>If you're doing performance tests, always remember that the JVM
+ needs to warm up. First load your solver and do a short run, before
+ you start benchmarking it.</para>
+ </listitem>
</itemizedlist>
</section>
</section>
\ No newline at end of file
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Solver_configuration.xml
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Solver_configuration.xml 2007-09-22 16:53:16 UTC (rev 15291)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Solver_configuration.xml 2007-09-22 20:51:57 UTC (rev 15292)
@@ -83,9 +83,8 @@
</forager>
</localSearchSolver></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>This is a tabu search configuration 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>
@@ -94,6 +93,13 @@
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>
+
+ <para>A solver has a single <literal>Random</literal> instance. Some
+ solver configuration use that instance a lot more than others. For example
+ simulated annealing depends highly on random numbers, while tabu search
+ only depends on it to deal with score ties. In any case, during your
+ testing it's advisable to see that <literal>Random</literal> instance, so
+ your tests are reproducible.</para>
</section>
<section>
@@ -123,7 +129,7 @@
</figure>
<para>The starting solution will probably be far from optimal (or even
- feasible), but that's ok, as it's the solver's job to find a much better
+ feasible), 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>
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-22 16:53:16 UTC (rev 15291)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/Section-Solver_introduction.xml 2007-09-22 20:51:57 UTC (rev 15292)
@@ -26,6 +26,7 @@
<programlisting>$ cd drools-solver/drools-solver-examples/
$ mvn exec:java -Dexec.mainClass="org.drools.solver.examples.nqueens.app.NQueensApp"
$ mvn exec:java -Dexec.mainClass="org.drools.solver.examples.lessonschedule.app.LessonScheduleApp"
+$ mvn exec:java -Dexec.mainClass="org.drools.solver.examples.travelingtournament.app.simple.SimpleTravelingTournamentApp"
$ mvn exec:java -Dexec.mainClass="org.drools.solver.examples.travelingtournament.app.smart.SmartTravelingTournamentApp"
...</programlisting>
@@ -318,8 +319,8 @@
</mediaobject>
</figure>
- <para>The above solution is wrong because queens A1 and B1 can attack
- each other (as can queens B1 and D1). Removing queen B1 would respect
+ <para>The above solution is wrong because queens A1 and B0 can attack
+ each other (as can queens B0 and D0). Removing queen B0 would respect
the "no 2 queens can attack each other" constraint, but would break the
"place n queens" constraint.</para>
</section>
@@ -371,7 +372,7 @@
<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
+ example: 0 is row 0, 1 is row 1, ...). 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>
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/allStepsNQueens04.png
===================================================================
(Binary files differ)
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/allStepsNQueens04.svg
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/allStepsNQueens04.svg 2007-09-22 16:53:16 UTC (rev 15291)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/allStepsNQueens04.svg 2007-09-22 20:51:57 UTC (rev 15292)
@@ -49,11 +49,11 @@
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
- inkscape:zoom="1.0840356"
- inkscape:cx="300.84189"
- inkscape:cy="373.07973"
- inkscape:window-x="-4"
- inkscape:window-y="-4"
+ inkscape:zoom="3.0661157"
+ inkscape:cx="309.00454"
+ inkscape:cy="670.03821"
+ inkscape:window-x="0"
+ inkscape:window-y="52"
inkscape:current-layer="svg2"
inkscape:grid-points="true"
inkscape:object-nodes="true"
@@ -2116,50 +2116,6 @@
x="397.35553"
id="tspan2730"
sodipodi:role="line">D</tspan></text>
- <text
- transform="scale(1.2959225,0.7716511)"
- id="text2732"
- y="391.19003"
- x="244.97539"
- style="font-size:17.77661896px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="391.19003"
- x="244.97539"
- id="tspan2734"
- sodipodi:role="line">1</tspan></text>
- <text
- transform="scale(1.2662447,0.7897368)"
- id="text2736"
- y="420.21878"
- x="251.46623"
- style="font-size:17.06097984px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="420.21878"
- x="251.46623"
- id="tspan2738"
- sodipodi:role="line">2</tspan></text>
- <text
- transform="scale(1.2553041,0.7966197)"
- id="text2740"
- y="454.01208"
- x="253.6541"
- style="font-size:16.59692001px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="454.01208"
- x="253.6541"
- id="tspan2742"
- sodipodi:role="line">3</tspan></text>
- <text
- transform="scale(1.1714276,0.8536592)"
- id="text2744"
- y="459.03799"
- x="272.38632"
- style="font-size:16.06888008px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="459.03799"
- x="272.38632"
- id="tspan2746"
- sodipodi:role="line">4</tspan></text>
<rect
y="260.15536"
x="20.5"
@@ -7053,4 +7009,52 @@
y="898.20203"
x="28.681641"
sodipodi:role="line">Step 3</tspan></text>
+ <g
+ transform="translate(235.50001,-550.69796)"
+ id="g4074">
+ <text
+ xml:space="preserve"
+ style="font-size:16.19810677px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="67.903915"
+ y="1044.647"
+ id="text3352"
+ transform="scale(1.2251409,0.8162327)"><tspan
+ sodipodi:role="line"
+ id="tspan3354"
+ x="67.903915"
+ y="1044.647">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.77658844px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="63.251419"
+ y="1144.1229"
+ id="text3356"
+ transform="scale(1.2959246,0.7716499)"><tspan
+ sodipodi:role="line"
+ id="tspan3358"
+ x="63.251419"
+ y="1144.1229">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.06092262px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="65.482925"
+ y="1155.9114"
+ id="text3360"
+ transform="scale(1.2662496,0.7897337)"><tspan
+ sodipodi:role="line"
+ id="tspan3362"
+ x="65.482925"
+ y="1155.9114">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16.76036072px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="66.700623"
+ y="1172.045"
+ id="text3364"
+ transform="scale(1.2430621,0.804465)"><tspan
+ sodipodi:role="line"
+ id="tspan3366"
+ x="66.700623"
+ y="1172.045">3</tspan></text>
+ </g>
</svg>
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/decideNextStepNQueens04.png
===================================================================
(Binary files differ)
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/decideNextStepNQueens04.svg
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/decideNextStepNQueens04.svg 2007-09-22 16:53:16 UTC (rev 15291)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/decideNextStepNQueens04.svg 2007-09-22 20:51:57 UTC (rev 15292)
@@ -50,10 +50,10 @@
pagecolor="#ffffff"
id="base"
inkscape:zoom="3.0661157"
- inkscape:cx="496.68145"
- inkscape:cy="160.20349"
- inkscape:window-x="-4"
- inkscape:window-y="-4"
+ inkscape:cx="375.89512"
+ inkscape:cy="331.10114"
+ inkscape:window-x="0"
+ inkscape:window-y="29"
inkscape:current-layer="svg2"
inkscape:grid-points="true"
inkscape:object-nodes="true"
@@ -2115,50 +2115,6 @@
x="379.0188"
id="tspan2730"
sodipodi:role="line">D</tspan></text>
- <text
- transform="scale(1.2959225,0.7716511)"
- id="text2732"
- y="883.64056"
- x="229.54236"
- style="font-size:17.77661896px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="883.64056"
- x="229.54236"
- id="tspan2734"
- sodipodi:role="line">1</tspan></text>
- <text
- transform="scale(1.2662447,0.7897368)"
- id="text2736"
- y="901.39172"
- x="235.67149"
- style="font-size:17.06097984px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="901.39172"
- x="235.67149"
- id="tspan2738"
- sodipodi:role="line">2</tspan></text>
- <text
- transform="scale(1.2553041,0.7966197)"
- id="text2740"
- y="931.02765"
- x="237.72171"
- style="font-size:16.59692001px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="931.02765"
- x="237.72171"
- id="tspan2742"
- sodipodi:role="line">3</tspan></text>
- <text
- transform="scale(1.1714276,0.8536592)"
- id="text2744"
- y="904.18054"
- x="255.31316"
- style="font-size:16.06888008px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="904.18054"
- x="255.31316"
- id="tspan2746"
- sodipodi:role="line">4</tspan></text>
<rect
y="642.86212"
x="85.499992"
@@ -2784,4 +2740,52 @@
sodipodi:ry="10"
d="M 480 967.36218 A 35 10 0 1 1 410,967.36218 A 35 10 0 1 1 480 967.36218 z"
transform="matrix(1.1142855,0,0,1,-50.857047,0)" />
+ <g
+ transform="translate(215.50001,-170.69796)"
+ id="g4074">
+ <text
+ xml:space="preserve"
+ style="font-size:16.19810677px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="67.903915"
+ y="1044.647"
+ id="text3352"
+ transform="scale(1.2251409,0.8162327)"><tspan
+ sodipodi:role="line"
+ id="tspan3354"
+ x="67.903915"
+ y="1044.647">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.77658844px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="63.251419"
+ y="1144.1229"
+ id="text3356"
+ transform="scale(1.2959246,0.7716499)"><tspan
+ sodipodi:role="line"
+ id="tspan3358"
+ x="63.251419"
+ y="1144.1229">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.06092262px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="65.482925"
+ y="1155.9114"
+ id="text3360"
+ transform="scale(1.2662496,0.7897337)"><tspan
+ sodipodi:role="line"
+ id="tspan3362"
+ x="65.482925"
+ y="1155.9114">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16.76036072px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="66.700623"
+ y="1172.045"
+ id="text3364"
+ transform="scale(1.2430621,0.804465)"><tspan
+ sodipodi:role="line"
+ id="tspan3366"
+ x="66.700623"
+ y="1172.045">3</tspan></text>
+ </g>
</svg>
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/partiallySolvedNQueens04Explained.png
===================================================================
(Binary files differ)
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/partiallySolvedNQueens04Explained.svg
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/partiallySolvedNQueens04Explained.svg 2007-09-22 16:53:16 UTC (rev 15291)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/partiallySolvedNQueens04Explained.svg 2007-09-22 20:51:57 UTC (rev 15292)
@@ -52,9 +52,9 @@
inkscape:zoom="4.7564103"
inkscape:cx="157.5"
inkscape:cy="162.5"
- inkscape:window-x="-4"
- inkscape:window-y="-4"
- inkscape:current-layer="svg2"
+ inkscape:window-x="0"
+ inkscape:window-y="52"
+ inkscape:current-layer="g5308"
inkscape:grid-points="true"
inkscape:object-nodes="true"
inkscape:guide-points="true"
@@ -653,50 +653,6 @@
x="181.89893"
id="tspan3350"
sodipodi:role="line">D</tspan></text>
- <text
- transform="scale(1.2959225,0.7716511)"
- id="text3352"
- y="1104.5953"
- x="63.637344"
- style="font-size:17.77661896px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1104.5953"
- x="63.637344"
- id="tspan3354"
- sodipodi:role="line">1</tspan></text>
- <text
- transform="scale(1.2662447,0.7897368)"
- id="text3356"
- y="1117.2864"
- x="65.878044"
- style="font-size:17.06097984px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1117.2864"
- x="65.878044"
- id="tspan3358"
- sodipodi:role="line">2</tspan></text>
- <text
- transform="scale(1.2553041,0.7966197)"
- id="text3360"
- y="1145.057"
- x="66.448456"
- style="font-size:16.59692001px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1145.057"
- x="66.448456"
- id="tspan3362"
- sodipodi:role="line">3</tspan></text>
- <text
- transform="scale(1.1714276,0.8536592)"
- id="text3364"
- y="1103.9091"
- x="71.776421"
- style="font-size:16.06888008px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1103.9091"
- x="71.776421"
- id="tspan3366"
- sodipodi:role="line">4</tspan></text>
<rect
y="812.36218"
x="80"
@@ -704,5 +660,53 @@
width="155"
id="rect3368"
style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.2" />
+ <g
+ transform="translate(0.4999876,-0.5000605)"
+ id="g4074">
+ <text
+ xml:space="preserve"
+ style="font-size:16.19810677px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="67.903915"
+ y="1044.647"
+ id="text3352"
+ transform="scale(1.2251409,0.8162327)"><tspan
+ sodipodi:role="line"
+ id="tspan3354"
+ x="67.903915"
+ y="1044.647">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.77658844px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="63.251419"
+ y="1144.1229"
+ id="text3356"
+ transform="scale(1.2959246,0.7716499)"><tspan
+ sodipodi:role="line"
+ id="tspan3358"
+ x="63.251419"
+ y="1144.1229">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.06092262px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="65.482925"
+ y="1155.9114"
+ id="text3360"
+ transform="scale(1.2662496,0.7897337)"><tspan
+ sodipodi:role="line"
+ id="tspan3362"
+ x="65.482925"
+ y="1155.9114">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16.76036072px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="66.700623"
+ y="1172.045"
+ id="text3364"
+ transform="scale(1.2430621,0.804465)"><tspan
+ sodipodi:role="line"
+ id="tspan3366"
+ x="66.700623"
+ y="1172.045">3</tspan></text>
+ </g>
</g>
</svg>
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/possibleMovesNQueens04.png
===================================================================
(Binary files differ)
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/possibleMovesNQueens04.svg
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/possibleMovesNQueens04.svg 2007-09-22 16:53:16 UTC (rev 15291)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/possibleMovesNQueens04.svg 2007-09-22 20:51:57 UTC (rev 15292)
@@ -52,8 +52,8 @@
inkscape:zoom="3.8548387"
inkscape:cx="169.72997"
inkscape:cy="145.23264"
- inkscape:window-x="-4"
- inkscape:window-y="-4"
+ inkscape:window-x="0"
+ inkscape:window-y="52"
inkscape:current-layer="svg2"
inkscape:grid-points="true"
inkscape:object-nodes="true"
@@ -608,54 +608,6 @@
id="tspan3350"
sodipodi:role="line">D</tspan></text>
</g>
- <g
- id="g6465"
- transform="translate(-5.4999941,0.5000421)">
- <text
- transform="scale(1.2959225,0.7716511)"
- id="text3352"
- y="1103.9474"
- x="64.02317"
- style="font-size:17.77661896px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1103.9474"
- x="64.02317"
- id="tspan3354"
- sodipodi:role="line">1</tspan></text>
- <text
- transform="scale(1.2662447,0.7897368)"
- id="text3356"
- y="1116.6533"
- x="66.272911"
- style="font-size:17.06097984px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1116.6533"
- x="66.272911"
- id="tspan3358"
- sodipodi:role="line">2</tspan></text>
- <text
- transform="scale(1.2553041,0.7966197)"
- id="text3360"
- y="1144.4293"
- x="66.846764"
- style="font-size:16.59692001px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1144.4293"
- x="66.846764"
- id="tspan3362"
- sodipodi:role="line">3</tspan></text>
- <text
- transform="scale(1.1714276,0.8536592)"
- id="text3364"
- y="1103.3234"
- x="72.203247"
- style="font-size:16.06888008px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1103.3234"
- x="72.203247"
- id="tspan3366"
- sodipodi:role="line">4</tspan></text>
- </g>
<rect
style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.2"
id="rect3368"
@@ -797,4 +749,52 @@
id="path5306"
sodipodi:nodetypes="cccccccc" />
</g>
+ <g
+ transform="translate(0.5000063,-0.6979568)"
+ id="g4074">
+ <text
+ xml:space="preserve"
+ style="font-size:16.19810677px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="67.903915"
+ y="1044.647"
+ id="text5236"
+ transform="scale(1.2251409,0.8162327)"><tspan
+ sodipodi:role="line"
+ id="tspan5238"
+ x="67.903915"
+ y="1044.647">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.77658844px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="63.251419"
+ y="1144.1229"
+ id="text5240"
+ transform="scale(1.2959246,0.7716499)"><tspan
+ sodipodi:role="line"
+ id="tspan5242"
+ x="63.251419"
+ y="1144.1229">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.06092262px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="65.482925"
+ y="1155.9114"
+ id="text5244"
+ transform="scale(1.2662496,0.7897337)"><tspan
+ sodipodi:role="line"
+ id="tspan5246"
+ x="65.482925"
+ y="1155.9114">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16.76036072px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="66.700623"
+ y="1172.045"
+ id="text5248"
+ transform="scale(1.2430621,0.804465)"><tspan
+ sodipodi:role="line"
+ id="tspan5250"
+ x="66.700623"
+ y="1172.045">3</tspan></text>
+ </g>
</svg>
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/singleMoveNQueens04.png
===================================================================
(Binary files differ)
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/singleMoveNQueens04.svg
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/singleMoveNQueens04.svg 2007-09-22 16:53:16 UTC (rev 15291)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/singleMoveNQueens04.svg 2007-09-22 20:51:57 UTC (rev 15292)
@@ -51,9 +51,9 @@
id="base"
inkscape:zoom="3.0661157"
inkscape:cx="243.33909"
- inkscape:cy="197.373"
- inkscape:window-x="-4"
- inkscape:window-y="-4"
+ inkscape:cy="210.41882"
+ inkscape:window-x="0"
+ inkscape:window-y="29"
inkscape:current-layer="svg2"
inkscape:grid-points="true"
inkscape:object-nodes="true"
@@ -1113,54 +1113,6 @@
id="tspan3350"
sodipodi:role="line">D</tspan></text>
</g>
- <g
- id="g6465"
- transform="translate(-5.4999941,0.5000421)">
- <text
- transform="scale(1.2959225,0.7716511)"
- id="text3352"
- y="1103.9474"
- x="64.02317"
- style="font-size:17.77661896px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1103.9474"
- x="64.02317"
- id="tspan3354"
- sodipodi:role="line">1</tspan></text>
- <text
- transform="scale(1.2662447,0.7897368)"
- id="text3356"
- y="1116.6533"
- x="66.272911"
- style="font-size:17.06097984px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1116.6533"
- x="66.272911"
- id="tspan3358"
- sodipodi:role="line">2</tspan></text>
- <text
- transform="scale(1.2553041,0.7966197)"
- id="text3360"
- y="1144.4293"
- x="66.846764"
- style="font-size:16.59692001px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1144.4293"
- x="66.846764"
- id="tspan3362"
- sodipodi:role="line">3</tspan></text>
- <text
- transform="scale(1.1714276,0.8536592)"
- id="text3364"
- y="1103.3234"
- x="72.203247"
- style="font-size:16.06888008px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1103.3234"
- x="72.203247"
- id="tspan3366"
- sodipodi:role="line">4</tspan></text>
- </g>
<rect
style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.2"
id="rect3368"
@@ -1216,4 +1168,103 @@
id="tspan6501"
sodipodi:role="line">D</tspan></text>
</g>
+ <g
+ transform="translate(150.49999,-0.5000605)"
+ id="g4074"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:export-filename="D:\projects\jboss\drools\documentation\manual\en\Chapter-Solver\singleMoveNQueens04.png">
+ <text
+ xml:space="preserve"
+ style="font-size:16.19810677px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="67.903915"
+ y="1044.647"
+ id="text3352"
+ transform="scale(1.2251409,0.8162327)"><tspan
+ sodipodi:role="line"
+ id="tspan3354"
+ x="67.903915"
+ y="1044.647">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.77658844px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="63.251419"
+ y="1144.1229"
+ id="text3356"
+ transform="scale(1.2959246,0.7716499)"><tspan
+ sodipodi:role="line"
+ id="tspan3358"
+ x="63.251419"
+ y="1144.1229">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.06092262px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="65.482925"
+ y="1155.9114"
+ id="text3360"
+ transform="scale(1.2662496,0.7897337)"><tspan
+ sodipodi:role="line"
+ id="tspan3362"
+ x="65.482925"
+ y="1155.9114">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16.76036072px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="66.700623"
+ y="1172.045"
+ id="text3364"
+ transform="scale(1.2430621,0.804465)"><tspan
+ sodipodi:role="line"
+ id="tspan3366"
+ x="66.700623"
+ y="1172.045">3</tspan></text>
+ </g>
+ <g
+ transform="translate(0.5000063,-0.6979568)"
+ id="g4916">
+ <text
+ xml:space="preserve"
+ style="font-size:16.19810677px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="67.903915"
+ y="1044.647"
+ id="text4918"
+ transform="scale(1.2251409,0.8162327)"><tspan
+ sodipodi:role="line"
+ id="tspan4920"
+ x="67.903915"
+ y="1044.647">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.77658844px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="63.251419"
+ y="1144.1229"
+ id="text4922"
+ transform="scale(1.2959246,0.7716499)"><tspan
+ sodipodi:role="line"
+ id="tspan4924"
+ x="63.251419"
+ y="1144.1229">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.06092262px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="65.482925"
+ y="1155.9114"
+ id="text4926"
+ transform="scale(1.2662496,0.7897337)"><tspan
+ sodipodi:role="line"
+ id="tspan4928"
+ x="65.482925"
+ y="1155.9114">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16.76036072px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="66.700623"
+ y="1172.045"
+ id="text4930"
+ transform="scale(1.2430621,0.804465)"><tspan
+ sodipodi:role="line"
+ id="tspan4932"
+ x="66.700623"
+ y="1172.045">3</tspan></text>
+ </g>
</svg>
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/solvedNQueens04.png
===================================================================
(Binary files differ)
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/solvedNQueens04.svg
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/solvedNQueens04.svg 2007-09-22 16:53:16 UTC (rev 15291)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/solvedNQueens04.svg 2007-09-22 20:51:57 UTC (rev 15292)
@@ -53,7 +53,7 @@
inkscape:cx="156.83926"
inkscape:cy="150.51812"
inkscape:window-x="0"
- inkscape:window-y="29"
+ inkscape:window-y="52"
inkscape:current-layer="svg2"
inkscape:grid-points="true"
inkscape:object-nodes="true"
@@ -607,50 +607,6 @@
x="181.89893"
id="tspan3350"
sodipodi:role="line">D</tspan></text>
- <text
- transform="scale(1.2959225,0.7716511)"
- id="text3352"
- y="1104.5953"
- x="63.637344"
- style="font-size:17.77661896px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1104.5953"
- x="63.637344"
- id="tspan3354"
- sodipodi:role="line">1</tspan></text>
- <text
- transform="scale(1.2662447,0.7897368)"
- id="text3356"
- y="1117.2864"
- x="65.878044"
- style="font-size:17.06097984px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1117.2864"
- x="65.878044"
- id="tspan3358"
- sodipodi:role="line">2</tspan></text>
- <text
- transform="scale(1.2553041,0.7966197)"
- id="text3360"
- y="1145.057"
- x="66.448456"
- style="font-size:16.59692001px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1145.057"
- x="66.448456"
- id="tspan3362"
- sodipodi:role="line">3</tspan></text>
- <text
- transform="scale(1.1714276,0.8536592)"
- id="text3364"
- y="1103.9091"
- x="71.776421"
- style="font-size:16.06888008px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1103.9091"
- x="71.776421"
- id="tspan3366"
- sodipodi:role="line">4</tspan></text>
<rect
y="812.36218"
x="80"
@@ -659,4 +615,52 @@
id="rect3368"
style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.2" />
</g>
+ <g
+ transform="translate(0.5000063,-0.6979568)"
+ id="g4074">
+ <text
+ xml:space="preserve"
+ style="font-size:16.19810677px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="67.903915"
+ y="1044.647"
+ id="text4516"
+ transform="scale(1.2251409,0.8162327)"><tspan
+ sodipodi:role="line"
+ id="tspan4518"
+ x="67.903915"
+ y="1044.647">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.77658844px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="63.251419"
+ y="1144.1229"
+ id="text4520"
+ transform="scale(1.2959246,0.7716499)"><tspan
+ sodipodi:role="line"
+ id="tspan4522"
+ x="63.251419"
+ y="1144.1229">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.06092262px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="65.482925"
+ y="1155.9114"
+ id="text4524"
+ transform="scale(1.2662496,0.7897337)"><tspan
+ sodipodi:role="line"
+ id="tspan4526"
+ x="65.482925"
+ y="1155.9114">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16.76036072px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="66.700623"
+ y="1172.045"
+ id="text4528"
+ transform="scale(1.2430621,0.804465)"><tspan
+ sodipodi:role="line"
+ id="tspan4530"
+ x="66.700623"
+ y="1172.045">3</tspan></text>
+ </g>
</svg>
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/unsolvedNQueens04.png
===================================================================
(Binary files differ)
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/unsolvedNQueens04.svg
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/unsolvedNQueens04.svg 2007-09-22 16:53:16 UTC (rev 15291)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Solver/unsolvedNQueens04.svg 2007-09-22 20:51:57 UTC (rev 15292)
@@ -54,7 +54,7 @@
inkscape:cy="160.84136"
inkscape:window-x="-4"
inkscape:window-y="-4"
- inkscape:current-layer="svg2"
+ inkscape:current-layer="g5308"
inkscape:grid-points="true"
inkscape:object-nodes="true"
inkscape:guide-points="true"
@@ -607,50 +607,53 @@
x="181.89893"
id="tspan3350"
sodipodi:role="line">D</tspan></text>
- <text
- transform="scale(1.2959225,0.7716511)"
- id="text3352"
- y="1104.5953"
- x="63.637344"
- style="font-size:17.77661896px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1104.5953"
- x="63.637344"
- id="tspan3354"
- sodipodi:role="line">1</tspan></text>
- <text
- transform="scale(1.2662447,0.7897368)"
- id="text3356"
- y="1117.2864"
- x="65.878044"
- style="font-size:17.06097984px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1117.2864"
- x="65.878044"
- id="tspan3358"
- sodipodi:role="line">2</tspan></text>
- <text
- transform="scale(1.2553041,0.7966197)"
- id="text3360"
- y="1145.057"
- x="66.448456"
- style="font-size:16.59692001px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1145.057"
- x="66.448456"
- id="tspan3362"
- sodipodi:role="line">3</tspan></text>
- <text
- transform="scale(1.1714276,0.8536592)"
- id="text3364"
- y="1103.9091"
- x="71.776421"
- style="font-size:16.06888008px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="1103.9091"
- x="71.776421"
- id="tspan3366"
- sodipodi:role="line">4</tspan></text>
+ <g
+ id="g4074">
+ <text
+ xml:space="preserve"
+ style="font-size:16.19810677px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="67.903915"
+ y="1044.647"
+ id="text3352"
+ transform="scale(1.2251409,0.8162327)"><tspan
+ sodipodi:role="line"
+ id="tspan3354"
+ x="67.903915"
+ y="1044.647">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.77658844px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="63.251419"
+ y="1144.1229"
+ id="text3356"
+ transform="scale(1.2959246,0.7716499)"><tspan
+ sodipodi:role="line"
+ id="tspan3358"
+ x="63.251419"
+ y="1144.1229">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.06092262px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="65.482925"
+ y="1155.9114"
+ id="text3360"
+ transform="scale(1.2662496,0.7897337)"><tspan
+ sodipodi:role="line"
+ id="tspan3362"
+ x="65.482925"
+ y="1155.9114">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16.76036072px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="66.700623"
+ y="1172.045"
+ id="text3364"
+ transform="scale(1.2430621,0.804465)"><tspan
+ sodipodi:role="line"
+ id="tspan3366"
+ x="66.700623"
+ y="1172.045">3</tspan></text>
+ </g>
<rect
y="812.36218"
x="80"
More information about the jboss-svn-commits
mailing list