diff --git a/documentation/changes_list.txt b/documentation/changes_list.txt index 30fda5b329..d235897d50 100644 --- a/documentation/changes_list.txt +++ b/documentation/changes_list.txt @@ -1,4 +1,24 @@ +v.0.1.5: (2012-04-30 12:46:04) +------------------------------ +* Major changes in the scripts to generate the doc: + - the scripts have been completely rewritten and the directories + completely rearranged. +* Minor enhancements to the manual: + - html version: several graphic enhancements. + - preface: comments from Hakan (Thanks again and again! ;-) ) + - chap2: + + table with cryptarithmetic puzzle improved in both version. + + figures "at a glance" done anew. + + comments from Hakan. +* FAQ: + - several graphic enhancements. +* Tutorials: + - few corrections in the C++ code. +* Lab sessions: + - chap2: questions posted. + + v.0.1.4: (2012-04-23 22:55:42) ------------------------------ * Major changes in the scripts to generate the doc: diff --git a/documentation/documentation_hub.html b/documentation/documentation_hub.html index 95f66e42fe..425e64f714 100644 --- a/documentation/documentation_hub.html +++ b/documentation/documentation_hub.html @@ -72,17 +72,24 @@ Thank you very much.
Here is a little summary:
-v.0.1.4: (2012-04-23 22:55:42)
+v.0.1.5: (2012-04-30 12:46:04)
------------------------------
* Major changes in the scripts to generate the doc:
- the scripts have been completely rewritten and the directories
completely rearranged.
* Minor enhancements to the manual:
- chap3:
- - a lots of small improvements from Hakan (Thanks again!).
- - some images resized in html version.
+ - html version: several graphic enhancements.
+ - preface: comments from Hakan (Thanks again and again! ;-) )
+ - chap2:
+ + table with cryptarithmetic puzzle improved in both version.
+ + figures "at a glance" done anew.
+ + comments from Hakan.
+* FAQ:
+ - several graphic enhancements.
* Tutorials:
- few corrections in the C++ code.
+* Lab sessions:
+ - chap2: questions posted.
@@ -97,9 +104,9 @@ Thank you very much.
This document is by no means a tutorial on Operations Research nor on Contraint Programming. It is also NOT a reference manual (refer to the documentation hub to find the reference manual). -There are way too many methods, parameters, functions, . . . to explain them all in details. Once +There are way too many methods, parameters, functions, etc. to explain them all in details. Once you understand the concepts and methods explained in this manual, you shouldn’t have any trouble scanning the reference manual and find the right method, parameter, function, . . . or code them yourselves!
@@ -177,7 +177,8 @@ them yourselves! questions about the non-CP part of the library, don’t hesitate to ask them on the mailing list. See the section How to reach us? below.This document will not describe how to use the library (and the syntactic sugar introduced when -possible) with Python, Java nor C#. This could possibly change in the future.
+possible) with Python, Java nor C#. This could possibly change in the future. The tutorial examples +(see below) exist also in Python, Java and C# though.That said, the manual is kept short so that you can read it in its entirety. The first part (Basics) is an introduction on how to use the CP solver to solve small problems. For real problems, you need to customize your search and this is explained in the second part (Customization). If you are -interested in the routing part of the library, the third part if for you (Routing). Finally, some utilities +interested in the routing part of the library, the third part is for you (Routing). Finally, some utilities and tricks are explained in the appendices.
Prerequisites:
Files:
You can find the code in the directory documentation/tutorials/C++/chap2.
diff --git a/documentation/user_manual/manual/first_steps/anatomy.html b/documentation/user_manual/manual/first_steps/anatomy.html index 6d793e920d..fea0a09fea 100644 --- a/documentation/user_manual/manual/first_steps/anatomy.html +++ b/documentation/user_manual/manual/first_steps/anatomy.html @@ -63,8 +63,8 @@ the cryptarithmetic puzzle in C++. In the next chapters, we will cover some of t in more details.
-
+
+
The header logging.h is needed for some logging facilities and some assert-like macros. The header constraint_solver.h is the main entry point -to the CP solver and must be includedfootnote{Directly or indirectly when it is included in another header you include.} whenever you intend to use it.
+to the CP solver and must be included[1] whenever you intend to use it. +| [1] | Directly or indirectly when it is included in another header you include. |
MakeBaseLine2, MakeBaseLine3 and MakeBaseLine4 are helper functions to create the model.
We detail these functions later in Constraints but for the moment, let’s concentrate on CPIsFun() where all the magic happens.
-It is called from the main[1] +
It is called from the main[2] function:
int main(int argc, char **argv) {
operations_research::CPIsFun();
@@ -106,7 +112,7 @@ function:
| [1] | The main function does not lie inside the namespace + |
| [2] | The main function does not lie inside the namespace operations_research, hence the use of the operations_research identifier to call the function CPIsFun(). |
| [2] | It is possible to bypass the undefined behaviour but you don’t know what the solver needs to do, so keep your hands off of the object pointers! ;-) |
| [3] | It is possible to bypass the undefined behaviour but you don’t know what the solver needs to do, so keep your hands off of the object pointers! ;-) |
Beside integer variables, the solver provides factory methods to create @@ -184,13 +190,14 @@ Aborted
In Asserting, we cover assert-like macros in more details.
To create a integer linear constraint, we need to know how to multiply an integer variable +
To create an integer linear constraint, we need to know how to multiply an integer variable with an integer constant and how to add two integer variables. We have seen that the solver creates a variable and only provides a pointer to that variable. The solver also provides factory methods to multiply an integer coefficient by an IntVar given by a pointer:
IntVar* const var1 = solver.MakeIntVar(0, 1, "Var1");
+// var2 = var1 * 36
IntVar* const var2 = solver.MakeProd(var1,36)->Var();
To add two IntVar given by their respective pointers, the solver provides again a factory method:
-IntVar* const var3 = solver.MakeSum(var1,var2)->Var();
+//var3 = var1 + var2
+IntVar* const var3 = solver.MakeSum(var1,var2)->Var();
diff --git a/documentation/user_manual/manual/first_steps/cryptarithmetic.html b/documentation/user_manual/manual/first_steps/cryptarithmetic.html
index 843e2426fa..d6a722db38 100644
--- a/documentation/user_manual/manual/first_steps/cryptarithmetic.html
+++ b/documentation/user_manual/manual/first_steps/cryptarithmetic.html
@@ -110,7 +110,7 @@ have different values in a feasible solution. Second, it is implicit that the fi
digit of a number can not be 0. Letters C, I, F and T can thus
not represent 0. Third, there are 10 letters, so we need at least 10
different digits. The traditional decimal base is sufficient but let’s be more general
-and allow for a bigger base. We will use a constant kBase. This last constraint is not a CP constraint.
+and allow for a bigger base. We will use a constant kBase. The fact that we need at least 10 digits is not really a CP constraint.
After all, the base is not a variable but a given integer that is chosen once
and for all for the whole program[2].
@@ -127,17 +127,20 @@ puzzle has less than xFor each letter, we have a decision variable (we keep the same letters to name the variables).
Given a base b, digits range from 0 to b-1.
Remember that variables corresponding to C, I, F and T should be different
-from 0. Thus C, I, F and T have
as domain and P, S, U, N, R and E
-have
as domain. Another possibility is to keep the same domain
for all
-variables and force C, I, F and T to be different from 0 by adding inequalities. However, restraining the domain to
is more efficient.
+from 0. Thus C, I, F and T have
as domain and P, S, U, N, R and E
+have
as domain. Another possibility is to keep the same domain
for all
+variables and force C, I, F and T to be different from 0 by adding inequalities. However, restraining the domain to
is more efficient.
To model the sum constraint in any base b, we add the linear equation:
-
+
The global constraint AllDifferent springs to mind to model that variables must all have different values:
AllDifferent(C,P,I,S,F,U,N,T,R,E)
diff --git a/documentation/user_manual/manual/first_steps/monitors.html b/documentation/user_manual/manual/first_steps/monitors.html
index b372fb3d80..1dd2797be5 100644
--- a/documentation/user_manual/manual/first_steps/monitors.html
+++ b/documentation/user_manual/manual/first_steps/monitors.html
@@ -200,8 +200,8 @@ also additional information. You can also act on some of the variables for insta
LOG(INFO) << "Number of solutions: " << number_solutions << std::endl;
for (int index = 0; index < number_solutions; ++index) {
- Assignment* const solution = all_solutions->solution(index);
- LOG(INFO) << "Solution found:";
+ Assignment* const solution = all_solutions->solution(index);
+ LOG(INFO) << "Solution found:";
LOG(INFO) << "v1=" << solution->Value(v1);
}
diff --git a/documentation/user_manual/manual/objectives.html b/documentation/user_manual/manual/objectives.html
index 0aff19fa94..69ac8579ad 100644
--- a/documentation/user_manual/manual/objectives.html
+++ b/documentation/user_manual/manual/objectives.html
@@ -89,11 +89,11 @@ In fact, you can completely skip them if you wish. The basic ideas behind these
You can find the code in the directory documentation/tutorials/C++/chap3.
The files inside this directory are:
-- golomb1.cc: A first implementation. We show how to tell the solver to optimize an objective function. We use the
differences as variables.
+- golomb1.cc: A first implementation. We show how to tell the solver to optimize an objective function. We use the
differences as variables.
- golomb2.cc: Same file as golomb1.cc but with some global statistics about the search added so we can see how well or bad
a model behave.
- golomb3.cc: A second implementation. This time, we only use the marks as variables and introduce the quaternary inequality constraints.
-- golomb4.cc: We improve the second implementation by reintroducing the
differences variables.
+- golomb4.cc: We improve the second implementation by reintroducing the
differences variables.
- golomb5.cc: In this third implementation, we replace the inequality constraints by the more powerful globlal AllDifferent constraint.
- golomb6.cc: The last implementation is a tightening of the model used in the third implementation. We add better upper and lower bounds and break a symmetry in the search tree.
diff --git a/documentation/user_manual/manual/objectives/content_model.html b/documentation/user_manual/manual/objectives/content_model.html
index 414f6bd221..22b6139bcc 100644
--- a/documentation/user_manual/manual/objectives/content_model.html
+++ b/documentation/user_manual/manual/objectives/content_model.html
@@ -64,7 +64,7 @@
Most of the mathematical classes in or-tools inherit from the BaseObject class. Its only
public method is a virtual DebugString(). If you are curious or just in doubt about
the object you just constructed, DebugString() is for you.
-Let’s have a closer look at the constraints that model the inner structure of the Golomb ruler of order
:
+Let’s have a closer look at the constraints that model the inner structure of the Golomb ruler of order
:
const int n = 5;
...
for (int i = 2; i <= n - 1; ++i) {
@@ -136,7 +136,7 @@ the object you just constructed,
(2..48))
-The cast to transform the sum
into an IntVar.
+The cast to transform the sum
into an IntVar.
And then:
...: Y_4(1..24) == Var<(Y_1(1..24) + Y_0(1..24))>(2..48)
...: Y_5(1..24) == Var<(Y_2(1..24) + Y_1(1..24))>(2..48)
diff --git a/documentation/user_manual/manual/objectives/data_search.html b/documentation/user_manual/manual/objectives/data_search.html
index e592d320b3..cfbc50f021 100644
--- a/documentation/user_manual/manual/objectives/data_search.html
+++ b/documentation/user_manual/manual/objectives/data_search.html
@@ -80,7 +80,7 @@ library offers a basic but portable timer. This timer starts to measure the time
As its name implies, the time measured is the wall time, i.e. ... TO BE COMPLETED.
-For instance, on my computer, the program in golomb1.cc for
takes
+For instance, on my computer, the program in golomb1.cc for
takes
Time: 4,773 seconds
diff --git a/documentation/user_manual/manual/objectives/first_implementation.html b/documentation/user_manual/manual/objectives/first_implementation.html
index 816a4abda8..049ef8bfa8 100644
--- a/documentation/user_manual/manual/objectives/first_implementation.html
+++ b/documentation/user_manual/manual/objectives/first_implementation.html
@@ -65,18 +65,18 @@
3.3.1. An upper bound
Several upper bounds exist on Golomb rulers.
-For instance, we could take
. Indeed, it can be
+For instance, we could take
. Indeed, it can be
shown that the sequence

-forms a Golomb ruler. As its largest member is
(when
), we have
-an upper bound on the length of a Golomb ruler of order
:
+forms a Golomb ruler. As its largest member is
(when
), we have
+an upper bound on the length of a Golomb ruler of order
:

Most bounds are really bad and this one isn’t an exception. The great mathematician Paul Erdös conjectured that

-This conjecture hasn’t been proved yet but computational evidence has shown that the conjecture holds for
(see [Dimitromanolakis2002]).
+This conjecture hasn’t been proved yet but computational evidence has shown that the conjecture holds for
(see [Dimitromanolakis2002]).
diff --git a/documentation/user_manual/manual/objectives/golomb_first_model.html b/documentation/user_manual/manual/objectives/golomb_first_model.html
index b8f784857f..c77e3199bf 100644
--- a/documentation/user_manual/manual/objectives/golomb_first_model.html
+++ b/documentation/user_manual/manual/objectives/golomb_first_model.html
@@ -73,21 +73,21 @@ illustrates a Golomb ruler of order 4 and all its - distinct - differences.
A non optimal Golomb ruler of order 4.
-The Golomb ruler is
and its length is
. Because
-we are interested in Golomb rulers with minimal length, we can fix the first mark to
.
+The Golomb ruler is
and its length is
. Because
+we are interested in Golomb rulers with minimal length, we can fix the first mark to
.
Figure An optimal Golomb ruler of order 4.
illustrates an optimal Golomb ruler of order 4 and all its - distinct - differences.
An optimal Golomb ruler of order 4.
-Its length,
, is optimal: it is not possible to construct a Golomb ruler with
marks with
-a length smaller than
. We denote this optimal value by
. More generally, for a
-Golomb ruler of order
, we denote by
its optimal value. The Golomb Ruler Problem (GRP) is to find, for a given
-order
, the smallest Golomb ruler with
marks.
+Its length,
, is optimal: it is not possible to construct a Golomb ruler with
marks with
+a length smaller than
. We denote this optimal value by
. More generally, for a
+Golomb ruler of order
, we denote by
its optimal value. The Golomb Ruler Problem (GRP) is to find, for a given
+order
, the smallest Golomb ruler with
marks.
You might be surprised to learn that
-the largest order for which the experts have found an optimal Golomb ruler so far is...
. And it was a huge hunt involving hundreds of people!
-The next table compares the number of days, the number of participants on the Internet and the number of visited nodes in the search tree to find and prove
,
and
[2][3][4].
+the largest order for which the experts have found an optimal Golomb ruler so far is...
. And it was a huge hunt involving hundreds of people!
+The next table compares the number of days, the number of participants on the Internet and the number of visited nodes in the search tree to find and prove
,
and
[2][3][4].
@@ -120,7 +120,7 @@ The next table compares the number of days, the number of participants on the In
-The search for
started on February 24, 2009 and at that time was expected to take... 7 years!
+
The search for
started on February 24, 2009 and at that time was expected to take... 7 years!
Still think it is an easy[1] problem? You too can participate: The OGR Project.
You can find all the known optimal Golomb rulers and more information on Wikipedia.
@@ -168,35 +168,35 @@ of a Golomb ruler. In information theory, Golomb rulers are used for error detec
3.2.2.1. Describe
What is the goal of the Golomb Ruler Problem? To find a minimal Golomb ruler for a given
-order
. Our objective function is the length of the ruler or the largest
+order
. Our objective function is the length of the ruler or the largest
integer in the Golomb ruler sequence.
What are the decision variables (unknowns)? We have at least two choices. We can either view the unknowns
as the marks of the ruler (and retrieve all the differences from these variables) or choose the unknowns to be the differences (and retrieve the marks).
Let’s try this second approach and use the efficient AllDifferent constraint.
-There are
such differences.
+There are
such differences.
What are the constraints? Using the differences as variables, we need to construct a Golomb
ruler, i.e. the structure of the Golomb ruler has to be respected (see next section).
3.2.2.2. Model
For each positive difference, we have a decision variable. We collect them in
-an array
Let’s order the differences so that we know which difference is represented by
.
+an array
Let’s order the differences so that we know which difference is represented by
.
Figure An ordered sequence of differences for the Golomb ruler of order 4.
illustrates an ordered sequence of differences for a Golomb ruler of order 4.
An ordered sequence of differences for the Golomb ruler of order 4.
-We want to minimize the last difference in
i.e.
since the first index of an array is
.
-When the order is
, we want to optimize
which represents the
difference. Instead of writing
, we will also use the more convenient notation
.
+We want to minimize the last difference in
i.e.
since the first index of an array is
.
+When the order is
, we want to optimize
which represents the
difference. Instead of writing
, we will also use the more convenient notation
.
Figure The inner structure of a Golomb ruler of order 5.
illustrates the structure than must be respected for a Golomb ruler of order 5. To impose the inner structure of the Golomb Ruler,
-we force
,
and so on as illustrated in Figure The inner structure of a Golomb ruler of order 5..
+we force
,
and so on as illustrated in Figure The inner structure of a Golomb ruler of order 5..
The inner structure of a Golomb ruler of order 5.
-An easy way to construct these equality constraints is to use an index index going from
to
[5], an
+
An easy way to construct these equality constraints is to use an index index going from
to
[5], an
index i to count the number of terms in a given equality and an index j to indicate the rank of the starting term in each
equality:
int index = n - 2;
@@ -212,7 +212,7 @@ equality:
[5] Or more generally from the index of the first difference that is the sum of two differences in our sequence
-
to the index of the last difference
.
+
to the index of the last difference
.
diff --git a/documentation/user_manual/manual/objectives/second_implementation.html b/documentation/user_manual/manual/objectives/second_implementation.html
index 6e8798c49b..cdea5e1a14 100644
--- a/documentation/user_manual/manual/objectives/second_implementation.html
+++ b/documentation/user_manual/manual/objectives/second_implementation.html
@@ -56,8 +56,8 @@
3.6. A second model and its implementation
-Our first model is really bad. One of the reasons is that we use too many variables:
differences.
-What happens if we only consider the
marks as variables instead of the differences?
+Our first model is really bad. One of the reasons is that we use too many variables:
differences.
+What happens if we only consider the
marks as variables instead of the differences?
3.6.1. Variables
You can find the code in the file tutorials/C++/chap3/golomb3.cc
@@ -70,7 +70,7 @@ In the same vain, we redefine the array
We use an std::vector slightly bigger (by one more element) than absolutely necessary. Because the solver doesn’t allow NULL pointers, we have
-to assign a value to X[0]. The first mark X[1] is 0. We use again
as an upper bound for the marks:
+to assign a value to X[0]. The first mark X[1] is 0. We use again
as an upper bound for the marks:
// Upper bound on G(n), only valid for n <= 65 000
CHECK_LE(n, 65000);
const int64 max = n * n - 1;
@@ -93,15 +93,15 @@ to assign a value to X[0]<
[1] Quaternary constraints is just a fancy way to say that the constraints each involves four variables.
-We don’t need all combinations of
with
and
. For instance, combination
-and combination
would both give the same constraint. One way to avoid such redundancy is to impose an order on unique positive differences[2].
+We don’t need all combinations of
with
and
. For instance, combination
+and combination
would both give the same constraint. One way to avoid such redundancy is to impose an order on unique positive differences[2].
[2] In section Breaking symmetries we’ll use another trick.
-Take again
and define the sequence of differences as in Figure Another ordered sequence of differences for the Golomb ruler of order 4..
+Take again
and define the sequence of differences as in Figure Another ordered sequence of differences for the Golomb ruler of order 4..
Another ordered sequence of differences for the Golomb ruler of order 4.
@@ -119,7 +119,7 @@ and so on as suggested in Figure
How to generate the quaternary constraints, part II.
-We define a helper function that, given a difference
corresponding to an interval
computes the next difference in the sequence:
+We define a helper function that, given a difference
corresponding to an interval
computes the next difference in the sequence:
bool next_interval(const int n, const int i, const int j, int* next_i,
int* next_j) {
CHECK_LT(i, n);
@@ -171,10 +171,10 @@ and so on as suggested in Figure [3]Remember again the remark at the beginning of this chapter about the tricky sums.
-Note that we set the minimum value of the difference to 1, diff1->SetMin(1), to ensure that the differences are positive and
. Note also that the method
+
Note that we set the minimum value of the difference to 1, diff1->SetMin(1), to ensure that the differences are positive and
. Note also that the method
MakeDifference() doesn’t allow us to give a name to the new variable, which is normal as this new variable is the difference of two
existing variables. Its name is simply name1 - name2.
-Let’s compare the first and second implementation. The next table compares some global indicators about the search for
.
+Let’s compare the first and second implementation. The next table compares some global indicators about the search for
.
@@ -236,7 +236,7 @@ existing variables. Its name is simply }
-and compare this improved version with the two others, again to compute
:
+and compare this improved version with the two others, again to compute
:
diff --git a/documentation/user_manual/manual/objectives/summary.html b/documentation/user_manual/manual/objectives/summary.html
index 14461c12cf..8a286df8d9 100644
--- a/documentation/user_manual/manual/objectives/summary.html
+++ b/documentation/user_manual/manual/objectives/summary.html
@@ -56,7 +56,7 @@
3.10. Summary
-Not a good approach. For example with our tightened implementation 3 we need 35.679 seconds to solve
.
+Not a good approach. For example with our tightened implementation 3 we need 35.679 seconds to solve
.
Further reading: see [SmithEtAl]
diff --git a/documentation/user_manual/manual/objectives/third_implementation.html b/documentation/user_manual/manual/objectives/third_implementation.html
index 6e4bc48a3f..b89cabb014 100644
--- a/documentation/user_manual/manual/objectives/third_implementation.html
+++ b/documentation/user_manual/manual/objectives/third_implementation.html
@@ -71,7 +71,7 @@ propagations of the “quaternary constraints”. But these constraints
s.AddConstraint(s.MakeAllDifferent(Y));
-and compare our three implementations, again to compute
:
+and compare our three implementations, again to compute
:
diff --git a/documentation/user_manual/manual/objectives/tighten_model.html b/documentation/user_manual/manual/objectives/tighten_model.html
index fb85613431..46a6dbcdc1 100644
--- a/documentation/user_manual/manual/objectives/tighten_model.html
+++ b/documentation/user_manual/manual/objectives/tighten_model.html
@@ -117,8 +117,8 @@ representing the marks of a Golomb ruler, we implicitly took for granted that [3] Declaring variables in an std::vector doesn’t tell anything about their respective values!
-Thanks to diff1->SetMin(1) and diff2->SetMin(1) and the two for loops, the ordered variables
-have only increasing values, i.e. if
then
. Solutions (1) and (2) are said to be symmetric and avoiding the second one while accepting the first one is called breaking symmetry.
+Thanks to diff1->SetMin(1) and diff2->SetMin(1) and the two for loops, the ordered variables
+have only increasing values, i.e. if
then
. Solutions (1) and (2) are said to be symmetric and avoiding the second one while accepting the first one is called breaking symmetry.
There is a well-known symmetry in the Golomb Ruler Problem that we didn’t break. Whenever you have a Golomb ruler, there exist another Golomb
ruler with the same length that is called the mirror ruler.
Figure Two mirror Golomb rulers of order 4.
@@ -127,7 +127,7 @@ illustrates two mirror Golomb rulers of order 4.
Two mirror Golomb rulers of order 4.
-Golomb ruler
has
as mirror Golomb ruler. Both have exactly the same length and can be considered symmetric solutions. To break this symmetry and allow the search for the first one but not the second one, just add X[2]-X[1] < X[n] - X[n-1]:
+Golomb ruler
has
as mirror Golomb ruler. Both have exactly the same length and can be considered symmetric solutions. To break this symmetry and allow the search for the first one but not the second one, just add X[2]-X[1] < X[n] - X[n-1]:
s.AddConstraint(s.MakeLess(s.MakeDifference(X[2],X[1])->Var(),
s.MakeDifference(X[n],X[n-1])->Var()));
@@ -135,7 +135,7 @@ illustrates two mirror Golomb rulers of order 4.
3.8.2. Better bounds helps
-In all implementations, we used
as an upper bound on
. In the case of the Golomb Ruler Problem, finding good upper bounds is a false problem. Very efficient techniques exist to find optimal or near optimal upper bounds. If we use those bounds, we reduce dramatically the domains of the variables. We can actually use
as an upper bound for
as these bounds can be obtained by projective and affine projections in the plane[4].
+In all implementations, we used
as an upper bound on
. In the case of the Golomb Ruler Problem, finding good upper bounds is a false problem. Very efficient techniques exist to find optimal or near optimal upper bounds. If we use those bounds, we reduce dramatically the domains of the variables. We can actually use
as an upper bound for
as these bounds can be obtained by projective and affine projections in the plane[4].