OPC – Utilisation de AbsCon et Sat4j

Transcription

OPC – Utilisation de AbsCon et Sat4j
OPC – Utilisation de AbsCon et Sat4j
Résumé
Le but de ce TP est d’illustrer l’importance de la modélisation avec un solveur CSP, et de mettre
en évidence certaines forces et faiblesses de différentes approches développées dans le laboratoire,
au sein des plates-formes AbsCon et Sat4j. La modélisation des problèmes se fera en Java, grâce à
AbsCon. Les problèmes seront ensuite exportés au format XCSP 2.1 pour être lisibles par une vaste
palette de solveurs. Pour information, et pour vous convaincre de l’importance de la programmation
par contraintes dans l’industrie, une Java Specification Request existe depuis mars 2012 pour la
programmation par contrainte : la JSR 331.
1
1.1
Utiliser AbsCon et Sat4j
Utiliser AbsCon
Pour tester AbsCon, téléchargez le fichier abscon.jar depuis http://www.cril.fr/˜lecoutre
– onglet Enseignement. Ensuite, dans un terminal, tapez :
java -jar abscon.jar
En retour, vous obtenez des informations sur le paramétrage possible du solveur. Pour le moment,
essayons simplement le solveur sur une instance prédéfinie de nom queens-8.xml au format XCSP
(que vous récupérez sur la page citée plus haut). Cela donne
java -jar abscon.jar queens-8.xml
Pour obtenir toutes les solutions, tapez :
java -jar abscon.jar queens-8.xml -s=all
Pour obtenir toutes les solutions de manière non verbeuse, tapez :
java -jar abscon.jar queens-8.xml -s=all -v=0
1.2
Utiliser Sat4j
Pour tester Sat4j, téléchargez le fichier sat4j-cps.jar depuis http://sat4j.ow2.org/.
Sat4j lit les instances au format XCSP et le transforme en problème SAT. Il ne s’agit donc pas d’un
prouveur CSP qui utilise les techniques présentées en OPC (filtrage, contraintes globales, etc).
Pour obtenir une solution du CSP, taper
java -jar sat4j-csp.jar queens-8.xml
Pour compter le nom de solutions, et afficher la dernière, taper :
java -Dall=true -jar sat4j-csp.jar queens-8.xml
Pour voir toutes les solutions, taper :
java -Dverbose=true -Dall=true -jar sat4j-csp.jar queens-8.xml
1
Le mode verbeux permet aussi de suivre la transformation des instances CSP en SAT : on pourra
noter sur certaines instances que le solveur passe plus de temps à traduire le problème en SAT qu’à
le résoudre ensuite.
Il est possible sur certains exemples de ne pas avoir assez de mémoire. Dans ce cas, il faudra
changer les paramètres de la JVM d’Oracle :
java -Xms2g -Xmx2g -Dverbose=true -Dall=true -jar sat4j-csp.jar queens-8.xml
2
Modéliser avec AbsCon
Pour modéliser un problème avec AbsCon, le plus simple est de procéder comme suit avec Eclipse.
1. Utiliser un ordinateur équipé avec Java SE 7 et Eclipse
2. Lancer et paramétrer Eclipse
— Si c’est la première fois qu’Eclipse est exécuté, accepter le répertoire de travail par défaut
proposé, et ensuite “Go to Workbench”
— Créer un projet Java de nom abscon :
— File - New - Java Project
— Taper le nom du projet (ici, abscon), puis choisir Next
— Dans l’onglet Libraires, choisir “add External Jars” , puis sélectionner abscon.jar
3. Créer une classe Java de nom Test.java dans le répertoire src du projet comme suit :
import static ios.inputs.Expr.*;
import problem.*;
public class Test extends Problem {
private Variable x, y;
@Override
protected void specifyVariables() {
x = addVariable("x", range(1, 3));
y = addVariable("y", range(1, 3));
}
// nom, valeurMin, valeurMax
// nom, valeurMin, valeurMax
@Override
protected void specifyConstraints() {
addConstraint(eq(x, y)); // x = y
}
}
4. Exécuter le solveur
— dans un terminal, en vous plaçant dans le répertoire bin du projet, et en copiant le fichier
abscon.jar dans ce même répertoire, vous pouvez taper :
java -jar abscon.jar Test
— dans un terminal, depuis n’importe quel répertoire, vous pouvez taper :
java -cp ˜/workspace/abscon/bin:abscon.jar abscon.Resolution Test
— depuis Eclipse,
Menu Run
Sous-menu Run configurations...
Onglet Main
Project: abscon
Main class: abscon.Resolution
Onglet Arguments
Program arguments: Test -s=all
VM arguments:
2
puis Run
Remarque 1 Pour simplifier, par la suite, on écrira toujours
java -jar abscon.jar ...
quelle que soit la méthode utilisée pour lancer le solveur (telle que décrite ci-dessus).
3
Le problème des reines
1. Le code ci-dessous est à placer dans un fichier de nom Queens.java.
import static ios.inputs.Expr.*;
import problem.Problem;
public class Queens extends Problem {
private int nbQueens, model; // parameters
private Variable[] queens; // variables
@Override
protected void specifyParameters() {
nbQueens = addParameterInt("Nb queens", 2); // message, minValue
model = addParameterInt("Model (1 to 3)", range(1, 3)); // message, minValue, maxValue
}
@Override
protected void specifyVariables() {
queens = addVariableArray1D("Q", range(0, nbQueens - 1), nbQueens);
}
private void model1() {
for (int i = 0; i < nbQueens; i++)
for (int j = i + 1; j < nbQueens; j++)
addConstraint(ne(queens[i], queens[j]));
for (int i = 0; i < nbQueens; i++)
for (int j = i + 1; j < nbQueens; j++) {
int rowDistance = Math.abs(i - j);
String colDistance = dist(queens[i], queens[j]);
addConstraint(ne(colDistance, rowDistance));
}
}
@Override
protected void specifyConstraints() {
switch (model) {
case 1:
model1();
break;
}
}
}
Il est important de noter que pour définir des contraintes en intension, on peut construire des
expressions/formules booléennes (prédicats) à l’aide de constantes (entières et booléennes) et
des fonctions (opérateurs) décrits par la table 1.
2. Lancer le solveur en mode interactif (il demandera la valeur des paramètres) avec :
java -jar abscon.jar Queens
Sinon on peut directement les donner en ligne de commande
java -jar abscon.jar Queens 8 1
3. Pour obtenir un affichage plus lisible des solutions, redéfinissez la méthode prettySolutionDisplay
comme par exemple :
3
Operation
Arity
Syntax
Arithmetic (operands are integers)
Opposite
1
neg(x)
Absolute Value
1
abs(x)
Addition
2
add(x,y)
Substraction
2
sub(x,y)
multiplication
2
mul(x,y)
Integer Division
2
div(x,y)
Remainder
2
mod(x,y)
Power
2
pow(x,y)
Minimum
2
min(x,y)
Maximum
2
max(x,y)
Semantics
-x
|x|
x+y
x-y
x*y
x div y
x mod y
xy
min(x,y)
max(x,y)
Relational (operands are integers)
Equal to
2
eq(x,y)
Different from
2
ne(x,y)
Greater than or equal
2
ge(x,y)
Greater than
2
gt(x,y)
Less than or equal
2
le(x,y)
Less than
2
lt(x,y)
x
x
x
x
x
x
Logic (operands are Booleans)
Logical not
1
Logical and
2
Logical or
2
Logical xor
2
Logical equivalence (iff)
2
not(x)
and(x,y)
or(x,y)
xor(x,y)
iff(x,y)
¬x
x∧y
x∨y
x⊕y
x⇔y
Control
Alternative
if(x,y,z)
value of y if x is true,
otherwise value of z
3
=
6=
≥
>
≤
<
y
y
y
y
y
y
Table 1 – Opérateurs utilisés pour construire des prédicats
@Override
public void specifySolutionDisplay() {
for (int i = 0; i < nbQueens; i++) {
for (int j = 0; j < nbQueens; j++)
System.out.print(queens[i].dom.getUniqueValue()==j?"Q":"-");
System.out.println();
}
}
4. Noter le temps et le nombre de noeuds nécessaire pour trouver toutes les solutions de l’instance
des 12 reines (avec le modèle 1) :
java -jar abscon.jar Queens 12 1 -s=all -v=0
5. Intégrer une nouvelle formulation des contraintes (model = 2) où les deux jeux de contraintes
sont fusionnés (i.e. les contraintes de même portée sont fusionnées). Tester le nouveau modèle
et comparer le temps de résolution ainsi que le nombre de noeuds explorés (pour toutes les
solutions de l’instance des 12 reines).
6. Pour le modèle 3, ajouter simplement une contrainte globale redondante (utilisez la méthode
addConstraintAllDifferent au modèle précédent.
7. Comparer les 3 modèles en terme de temps d’exécution et du nombre de noeuds explorés lorsque
les 14 200 solutions au problème des 12 reines sont recherchées.
4
8. Il existe un format de représentation générique pour les réseaux de contraintes permettant
de s’affranchir du codage d’un problème par programmation. Ce format basé sur XML et
appelé XCSP 1 décrit précisément les différents composants d’un réseau de contraintes. Il est
possible sous AbsCon de sauvegarder un réseau défini par programmation sous ce format. Il
suffit d’utiliser une commande telle que :
java -jar abscon.jar Queens 12 2 -xo=2 -export
Vous obtenez en retour l’affichage de la représentation XCSP du problème sur la sortie standard.
Bien sur, vous pouvez la rediriger dans un un nouveau fichier (extension xml obligatoire) comme
suit :
java -jar abscon.jar Queens 12 2 -xo=2 -export > Queens-12-2.xml
Pour lancer la résolution avec AbsCon à partir de ce nouveau fichier, vous n’avez qu’à utiliser
une commande telle que :
java -jar abscon.jar Queens-12-2.xml
L’intérêt ici est que ce format est reconnu par différents solveurs.
Générer un fichier xml du problème des 12 reines pour chaque modèle.
9. Comparer les 3 modèles en terme de temps d’exécution et de nombre de conflits pour le prouveur
Sat4j.
4
Le problème Sudoku
Intégrer le code suivant pour le problème du Sudoku (défini ici pour une grille vierge) :
public class Sudoku extends Problem {
protected int order;
protected Variable[][] matrix;
@Override
protected void specifyParameters() {
order = addParameterInt("order (9 = classical Sudoku)", 2);
}
@Override
protected void specifyVariables() {
matrix = addVariableArray2D(range(1, order), order, order);
}
@Override
protected void specifyConstraints() {
for (int i = 0; i < order; i++)
addConstraintAllDifferent(matrix[i]); // rows
for (int i = 0; i < order; i++)
addConstraintAllDifferent(Variable.columnOf(matrix, i)); // columns
int base = (int) Math.sqrt(order);
for (int i = 0; i < order; i += base)
for (int j = 0; j < order; j += base)
addConstraintAllDifferent(Variable.pieceOf(matrix, i, base, j, base)); // blocks
}
@Override
public void specifySolutionDisplay() {
for (int i = 0; i < order; i++)
for (int j = 0; j < order; j++)
Kit.pr(variables[i * order + j].dom.getUniqueVal() + (j == order - 1 ? "\n" : " "));
}
}
1. Voir http://arxiv.org/pdf/0902.2362v1
5
1. Construire une nouvelle classe Sudoku3 pour modéliser l’instance Sudoku suivante :
4
5 3 9
1
4
7
6
8
8
6
1
2
9
2
6
5
6
5
3 1
7
2
4 1 8
7
6
7
3
On pourra utiliser un tableau comme suit :
private int[][] hints = { {
{ 1, 7, 6 }, { 2, 2, 1
2 }, { 3, 5, 9 }, { 3,
5, 5, 3 }, { 5, 6, 1 },
}, { 7, 4, 3 }, { 7, 6,
column,value)
0, 1, 4 }, {
}, { 2, 5, 2
8, 6 }, { 4,
{ 5, 8, 7 },
4 }, { 7, 7,
1, 0, 5 }, {
}, { 2, 7, 5
2, 6 }, { 4,
{ 6, 1, 8 },
1 }, { 8, 7,
1, 1, 3 }, { 1, 2, 9 }, {
}, { 3, 0, 4 }, { 3, 2, 7
6, 5 }, { 5, 0, 8 }, { 5,
{ 6, 4, 7 }, { 6, 6, 2 },
7 } }; // triplets of the
1, 5, 1 },
}, { 3, 3,
3, 6 }, {
{ 7, 1, 6
form (row,
2. La résoudre avec la commande :
java -jar abscon.jar Sudoku3
Noter le nombre (et le type) de contraintes du problème ainsi que le nombre de valeurs détruites
au préprocessing.
3. La résoudre avec la commande :
java -jar abscon.jar Sudoku3 -ugb=no
Noter le nombre (et le type) de contraintes du problème ainsi que le nombre de valeurs détruites
au préprocessing. Pourquoi est-ce différent ?
4. Utiliser Sat4j pour résoudre ce problème. Noter le nombre et le type de contraintes.
5. Sat4j peut aussi utiliser des contraintes de cardinalité pour coder la contrainte allDiff.
java -DallDiffCards=true -jar sat4j-csp.jar sudoku3.xml
Noter le nombre et le type de contraintes générées.
6. Ajouter 8 dans la case en position (7, 8). Quelle est la conséquence ?
5
Séries de tous les intervalles
Étant données les 12 hauteurs de notes (c, c#, d, ...), représentées par les nombres 0,1,...,11, il
faut trouver une série dans laquelle chaque hauteur apparaı̂t exactement une fois et dans laquelle les
intervalles musicaux entre les notes voisines couvrent l’ensemble complet des intervalles du mineur
second (1 demi-ton) au majeur septième (11 demi-tons). Cela signifie donc que pour chaque intervalle,
il existe un couple de hauteurs voisines entre lesquelles l’intervalle apparaı̂t.
Le problème de trouver une telle série peut être généralisé comme suit. Étant donné un entier
positif n, trouver une séquence s = (s0 , ..., sn−1 ) telle que :
1. s corresponde à une permutation de {0, 1, ..., n − 1}
2. la séquence (des intervalles successifs) v = (|s1 − s0 |, |s2 − s1 |, ...|sn−1 − sn−2 |) corresponde à
une permutation de {1, 2, ..., n − 1}
6
Figure 1 – Elliott Carter base ses séries sur les listes générées par Bauer-Mendelberg et Ferentz, et
les utilise comme sonorité “tonique” (voir Wikipedia).
Une séquence s satisfaisant ces conditions est appelé une série de tous les intervalles de taille n. Par
exemple, pour n = 8, une solution est :
s = (1,7,0,5,4,2,6,3)
puisque cette séquence correspond bien à une permutation de {0, 1, ..., 7} et que :
v = (6,7,5,1,2,4,3)
correspond bien à une permutation de {1, ..., 7}.
Donner le modèle de ce problème sous AbsCon.
6
Les Carrés magiques
Un carré magique d’ordre n est un arrangement de n2 nombres dans un carré tel que la somme
des valeurs sur chaque ligne, chaque colonne et chaque diagonale (principale) est égale à une même
constante. Un carré magique normal contient les entiers de 1 à n2 . Par exemple, voici une solution
pour n = 4.
1. Donner le modèle de ce problème sous AbsCon Pour cela,
— penser à intégrer un paramètre de type int pour définir l’ordre du carré (à l’aide de la
méthode addIntParameter)
— penser à calculer à l’aide d’une formule (simple) la valeur à atteindre lorsqu’on somme
chaque ligne, colonne, et diagonale.
7
— poster les contraintes de somme en appelant la méthode addConstraintSum
2. Comme pour le problème des reines, rendez plus lisibles les solutions en redéfinissant la méthode
specifySolutionDisplay
3. Lancer la résolution pour quelques instances (ordres) du carré magique avec et sans le paramètre
-ugc=no
4. Lancer la résolution pour quelques instances (ordres) du carré magique avec et sans le paramètre
-rc=10
7
Le tour des cavaliers
Le problème du tour du cavalier est de trouver une séquence de mouvements de cavalier (un cavalier
peut bouger de 2 cases verticalement et d’une case horizontalement, ou de 2 cases horizontalement et
d’une case verticalement) sur un plateau de n sur n cases. Il est nécessaire que :
— chaque case soit visitée une et une seule fois
— le dernier mouvement permet de revenir sur la case de départ
La figure suivante montrer une solution de tour pour n = 8, avec un tour commençant dans le coin
supérieur gauche.
Créer une classe permettant de modéliser ce problème. Le résoudre à l’aide d’AbsCon et de Sat4j.
0
19
30
27
24
21
34
37
31
28
1
20
33
36
25
22
18
63
32
29
26
23
38
35
41
2
17
62
39
4
13
54
16
61
40
3
14
55
50
11
45
42
15
8
5
12
53
56
60
7
44
47
58
51
10
49
43
46
59
6
9
48
57
52
8

Documents pareils