title: "AllIntervalSeries" author: "Fissore Davide" date: "2022-05-30" caption-justification: centering ...
This folder contains some implementation to solve the All-Series Interval problem with Choco solver in Java. The jar file is named "LaunchMe.avi".
Input : an integer n
Output : find all vectors$s = (s_1, s_2, \dots, s_n)$ such that :
$s$ is a permutation of$Z_n = 0,1,\dots,n-1$ andthere exists a vector
$dist$ such that$dist = (|s_2 - s_1|, |s_3 - s_2|, \dots, |s_n - s_{n-1}|)$ is a permutation of$Z_n = 1, 2, \dots, n-1$ .A vector
$s$ satisfying these conditions is called an all-interval series of size$n$ .
When looking at solutions, we have a table like this :
n | # solutions | remark |
---|---|---|
3 | 4 | |
4 | 4 | |
5 | 8 | |
6 | 24 | |
7 | 32 | |
8 | 40 | |
9 | 120 | |
10 | 296 | |
11 | 648 | |
12 | 1328 | |
13 | 3200 |
And we can see that every solution is a multiple of 4. This let me think that there should exists at least two big symmetries that, once applied, can find only a quarter of the total number of solutions. (It is useless to calculate a solution
The simpler symmetry that I could spot was the symmetry that I will call
In order to avoid
I have passed a lot of time to figure out how to find the second symmetry to half again the number of solution. But the only way I was able to find it was by looking at the solutions of the problem for
For
-
$s_1 = [4, 0, 3, 1, 2]$ and$d_1 = [4, 3, 2, 1]$ -
$s_2 = [1, 2, 4, 0, 3]$ and$d_2 = [1, 2, 4, 3]$
-
$s_3 = [0, 4, 1, 3, 2]$ and$d_3 = [4, 3, 2, 1]$ -
$s_4 = [3, 2, 0, 4, 1]$ and$d_4 = [1, 2, 4, 3]$
-
$s_5 = [2, 1, 3, 0, 4]$ and$d_5 = [1, 2, 3, 4]$ -
$s_6 = [3, 0, 4, 2, 1]$ and$d_6 = [3, 4, 2, 1]$
-
$s_7 = [1, 4, 0, 2, 3]$ and$d_7 = [3, 4, 2, 1]$ -
$s_8 = [2, 3, 1, 4, 0]$ and$d_8 = [1, 2, 3, 4]$
From this list, we see that for every solution
Let
$s_2 = [1, 2, 4, 0, 3]$ $s_8 = [2, 3, 1, 4, 0]$
Where the other one can be found as follows :
$s_6 = [3, 0, 4, 2, 1] = R^{180}(s_2)$ $s_3 = [0, 4, 1, 3, 2] = R^{180}(s_8)$
$s_1 = [4, 0, 3, 1, 2] = S_h(s_2)$ $s_7 = [1, 4, 0, 2, 3] = S_h(s_8)$
$s_5 = [2, 1, 3, 0, 4] = R^{180}(S_h(s_2))$ $s_4 = [3, 2, 0, 4, 1] = R^{180}(S_h(s_8))$
In the java project, I have created an abstract class representing my Solvers. This class has some utility functions allowing to print statistics in CSV format and to print the solutions found line by line (This is the trick I used to find the two symmetries of the problem).
Moreover, in this abstract class I define the two vectors of IntVar
Where :
- s = an array of length n (every
$s_i \in s$ has domain$[0..n-1]$ ) - dist = a vector of length
$n-1$ (every$dist_i \in dist$ has domain$[1..n-1]$ )
With :
- AllDiff(s)
- AllDiff(dist)
Note : each solver, since it extends the AbstractSolver, owns the variables
$s$ and$dist$
I have created
Note : Solver with name A-... are solvers with arithm constraint and T-... are those using tables.
The Classic Solver class creates a really simple solver which implements the constraints of the problem introducing them one by one.
The added variables are :
- v = a vector of length
$n-1$ (every$v_i \in v$ has domain$[-n..n]$ )
The added constraints are :
$\forall i \in [0..n-2], v_i = s_i - s_{i+1}$ $\forall i \in [0..n-2], dist_i = |v_i|$
Remark :
- The constraint AllDiff on
$v$ is not necessary, since it is implicitly verified by the two other two AllDiffs on$s$ and$dist$ - This solver finds all solutions
The added variables are :
- triples = a vector of length is
$n-1$ of triples - tuples = a Tuples which will indicates the relationship between every triple of the vector triples.
The triples are encoded as follows :
The tuples is created as follows :
Note : it is not necessary to test that
$i \neq j$ since$i < j$ and$i, j$ and$j, i$ are added in tuples.
Note : This solver finds all solutions
As said in Section #the-r180-symmetry, an improvement of the problem can be to avoid computing some solution by imposing a strict order on two variables of the solution
FL (resp. FS) is a solver imposing
It extends the classic solver and :
-
The arithm version adds the constraint
$s_1 < s_n$ (resp. $s_2) -
The table version is parametrized with a universal value (
$-1$ in my case) which represents any value in the domain.
The tuples added to the table$T$ are vectors$V$ of length$n$ created in a for loop where :-
$V_0 < V_{n-1}$ (resp.$V_0 < V_1$ ) -
$\forall i \in [1..n-2], V_i = -1$ (resp.$\forall i \in [2..n-1], V_i = -1$ )
This tuples are added in a table which has a relationship with the vector
$s$ .$$model.table(s, T, "CT+").post();$$ Note : If we have a tuple of the type
$[1,-1,-1,2]$ and the domain of each variable in$s$ is$d = [0..2]$ , it means that the accepted vectors in$s$ are on the form$[1,0,0,2]$ ,$[1,0,1,2]$ ,$[1,0,2,2]$ ,$[1,1,0,2]$ and so on. -
This symmetry is not at all evident to conceive and in fact I passed several hours/days to find an implementation that however has not really good performance.
As said, this solver reduces the number of solution trying to find
$diff = |s_0 - s_{n-1}|$ $pos = {pos(i) \text{ for } i \in dist \mid i = diff}$ -
$pos \geq dist.length / 2$ (to break the symmetry)
Note: if
$n$ is even and$pos = \frac{n}{2}$ then$s[{\frac{n}{2}}] < s[{\frac{n}{2}+1}]$ .
Ad the end, similarly to the
The implementation of this rule is really similar to the implementation for the
To remove both the
To find the best strategy to apply on the problem, I have tested a lot of different combination of predefined tools proposed by the choco library. At the end I have found a fast Strategy that I have put in a dedicated class.
This strategy uses the First Fail method, trying first where you are most likely to fail. The values of the variable are then taken with the principle IntDomainMax since it is most likely to fail starting with big values especially if we want that
The jar file can be launched with the java -jar [path-to-jar]/[the-jar-file]. If no optional parameter is passed, then it will evaluate every solver implementation for
Some optional parameters are accepted :
-
$-h$ to get the help manual -
$-mX$ to set the minimum value of$n$ equals to$X$ where$X$ is a positive integer bigger than 2. For example$-m5$ will launch the solvers from$n = 5$ to the max value -
$-MX$ set the maximum value of$n$ , so$-M8$ will launch the algorithms from the min value until$n = 8$ -
$-nX$ to launch the jar on a fixed$n$ . In this case the min and the max bounds are not considered. Therefore, java -jar LaunchMe.avi -n5 -M8 -m3 will only launch the algo for$n = 5$ -
$-p$ to print the found solution line by line - --no-strat to remove the searchStrategy
- finally you can select to launch only specific algorithms with the
$-a$ option. Let :- 1 = A-Classic solver
- 2 = A-FirstLast solver
- 3 = A-FirstSecond solver
- 4 = A-Sh solver
- 5 = A-Double solver
- A = T-Classic solver
- B = T-FirstLast solver
- C = T-FirstSecond solver
- D = T-Sh solver
-
E = T-Double solver
For example$-a34A$ will execute the jar over the algorithms$3, 4$ and$A$ .
-
java -jar LaunchMe.avi -n5 -p -a36 will launch the
$3^{rd}$ and the$6^{th}$ solvers, for$n=5$ printing at the end the solutions; -
java -jar LaunchMe.avi -m4 -M13 will launch the solver for
$n$ varying from$4$ to$13$ ; -
java -jar LaunchMe.avi -m7 --no-strat will launch the solver for
$n$ varying from$7$ to$13$ without the strategy applied (of course not applying the strategy creates slower solvers); - java -jar LaunchMe.avi -h prints the help menu
- java -jar LaunchMe.avi same as java -jar LaunchMe.avi -m3 -M13
The source files can be compiled with the mvn install command and the jar file should be created inside the target folder, however, an already compiled jar should be found on the name "LaunchMe.avi" *[The avi extension as suggested by the prof, aims to bypass the google mail jar blocker].
Note: the jar to be launched if you compile with maven should be
Prog-par-Contr1-1.0-SNAPSHOT-jar-with-dependencies.jar
After having executed my algo, I was able to compare the solvers performance in terms of the amount of time needed, the number of backtracks and the number of solutions found (the results that I consider more interesting).
As expected, the classic solvers find the same number of results. In particular, for a given
It is also evident that FL, FS and Sh find only half of the solutions so we gain a factor 2 in the exponential
Finally, the
Note: We can see that in any case the number of solution grows exponentially with reference to
$n$ .
Note : FL, FS, and Sh curves are overlapped. Moreover every A-X solver curve is overlapped to the corresponding T-X solver.
For
Solver | # Sol | Comp w/CS |
---|---|---|
Classic | 3200 | |
FirstSecond | 1600 | |
FirstLast | 1600 | |
SH | 1600 | |
Double | 800 |
The solutions not found in
$FL$ and$FS$ can be obtained by reversing every solution found.
The solutions of Double are a quarter of the total number. The not found solutions can be obtained as explained in a previous section.
Resolution Time A-Solvers w/o Strat | Resolution Time T-Solvers w/o Strat |
---|---|
The time needed to find solutions is exponential in function of
From the plot, we can see that the Classic solver is the most time expensive implementation among the four both if we use tables or simple arithm constraints.
The introduction of the
An intriguing curve is the T-FirstLast which faster then the T-Double even if it finds two times the of its solutions.
If we compare the two graphics together, we see that the Solvers with tables are faster that those with simple arithm constraints : T-Classic, which is the slower solver of T-... type is faster then the fastest solver of A-... type.
If we introduce the strategy, we see that all the solvers become faster.
Resolution Time A-Solvers w/Strat | Resolution Time T-Solvers w/Strat |
---|---|
Moreover we see that now some solver of A-... type become faster for example than the T-Classic solver.
For
A-Solver | Time w/o Strat | Time w/Strat | Ratio |
---|---|---|---|
A-Classic | 73.42 | 17.61 | |
A-FirstSecond | 59.09 | 12.54 | |
A-FirstLast | 55.66 | 39.53 | |
A-Sh | 49.62 | 13.58 | |
A-Double | 44.69 | 6.8 |
T-Solver | Time w/o Strat | Time w/Strat | Ratio |
---|---|---|---|
T-Classic | 30.84 | 8.02 | |
T-FirstSecond | 18.28 | 4.31 | |
T-FirstLast | 5.82 | 11.14 | |
T-Sh | 16.07 | 6.25 | |
T-Double | 7.52 | 3.38 |
From these two tables, we can see that the introduction of the Strategy (called
BackTracks A-Solvers w/o Strat | BackTracks T-Solvers w/o Strat |
---|---|
BackTracks A-Solvers w/Strat | BackTracks T-Solvers w/Strat |
---|---|
These last plots allow us to see that the backtrack curves are coherent to the total time asked. In fact the more backtrack we do, the more the time asked to find all the solution will increase.
For
A-Solver | BTrack w/o Start | BTrack w/Strat | Ratio |
---|---|---|---|
A-Classic | 2.131.107 | 465.113 | |
A-FirstSecond | 1.204.337 | 232.143 | |
A-FirstLast | 1.463.515 | 578.197 | |
A-Sh | 979.473 | 348.687 | |
A-Double | 862.497 | 175.289 |
T-Solver | BTrack w/o Start | BTrack w/Strat | Ratio |
---|---|---|---|
T-Classic | 1.029.517 | 458.961 | |
T-FirstSecond | 575.447 | 232.701 | |
T-FirstLast | 190.289 | 550.829 | |
T-Sh | 487.133 | 342.961 | |
T-Double | 189.313 | 172.457 |
As for the tables of the previous section, we can see that the FirstLast solvers is not really advantaged by the introduction of Strategy
I have plotted other statistics that I will not analyze and whose plots are available in the ./statistics/ folder.
These other statistics concern for example the number of fail (which is in general half of the number of its corresponding backtrack) and the number of constraint and variable of the Solvers.
I am a lot satisfied to have been able to find the two symmetries (
Finally, with this project, I have been able to really understand the main concepts of this course : we should remove the symmetries and a good search strategy is really important to further improve the solver. But, above all, we always have to really understand the problem before coding it, then, little by little, we have to build our program starting from the really base case. Moreover, what I found useful, was the study of little instances of the problem (the case of