ChocoSolver est une bibliothèque Java open-source dédiée à la résolution de problèmes de satisfaction de contraintes (CSP) et d’optimisation (COP). Elle est utilisée dans les domaines d’applications de CSP et COP tels que la planification, l’ordonnancement, la configuration de produits,…
Exemple repris du tutoriel de ChocoSolver sur le problème des N reines (sur un échiquier de NxN, placer N reines de telle manière à ce qu’aucune reine ne puisse en attaquer une autre).
Cet exemple illustre différents types de contraintes arithmétiques.
int n = 8;
Model model = new Model(n + "-queens problem");
IntVar[] vars = new IntVar[n];
for(int q = 0; q < n; q++){
vars[q] = model.intVar("Q_"+q, 1, n);
}
for(int i = 0; i < n-1; i++){
for(int j = i + 1; j < n; j++){
model.arithm(vars[i], "!=",vars[j]).post();
model.arithm(vars[i], "!=", vars[j], "-", j - i).post();
model.arithm(vars[i], "!=", vars[j], "+", j - i).post();
}
}
Solution solution = model.getSolver().findSolution();
if(solution != null){
System.out.println(solution.toString());
}
créer un modèle de problème avec Model model = new Model(n + "-queens problem");
IntVar[] vars = new IntVar[n]; représentant les positions des reines sur l’échiquier. vars[q] = model.intVar("Q_"+q, 1, n);.Ici, aucune stratégie de recherche n’est spécifiée, donc le solveur utilisera sa stratégie par défaut.
Dans le tutoriel, plusieurs améliorations sont proposées.
Déclaration de variables :
IntVar[] vars = model.intVarArray("Q", n, 1, n, true);
true demande à ce les variables soient énumérées et crées de suitefalse (par défaut) demande à ce que les variables soient créées au fur et à mesure du besointrue lorsque le nombre de variables est faible et false dans le cas contraire.Déclaration de contraintes :
vars[i].ne(vars[j]).post();vars[i].ne(vars[j].sub(j - i)).post();vars[i].ne(vars[j].add(j - i)).post();
ne est une abréviation de “not equal” (différent de)vars[i].ne(vars[j]).extension().post();vars[i].ne(vars[j].sub(j - i)).extension().post();vars[i].ne(vars[j].add(j - i)).extension().post();Par défaut, le solveur de Choco utilise :
Le solveur peut être paramétré de différentes façons.
Stratégies de recherche :
Par défaut, le solveur utilise une stratégie de recherche par défaut.
Cependant, il est possible de définir des stratégies personnalisées pour influencer l’ordre dans lequel les variables sont sélectionnées et le mode de sélection des valeurs à leur assigner.
Voici quelques exemples de stratégies de recherche que l’on peut utiliser via la classe Search :
Solver s = model.getSolver();
s.setSearch(Search.intVarSearch(
// selects the variable of smallest domain size
new FirstFail(model),
// selects the smallest domain value (lower bound)
new IntDomainMin(),
// apply equality (var = val)
DecisionOperatorFactory.makeIntEq(),
// variables to branch on
vars
FirstFail : sélectionne la variable avec le plus petit domaineAntiFirstFail : sélectionne la variable avec le plus large domaineCyclic : sélectionne les variables selon un ordre lexicographiqueInputOrder : sélectionne les variables dans l’ordre de déclarationRandom : sélectionne une variable au hasardSmallest : sélectionne la variable avec la plus petite valeur dans son domaine……
IntDomainMin : sélectionne la plus petite valeur du domaineIntDomainMax : sélectionne la plus grande valeur du domaineIntDomainMiddle : sélectionne la valeur médiane du domaineIntDomainRandom : sélectionne une valeur au hasard dans le domaineIntDomainBest : sélectionne la valeur qui minimise une fonction objectifIntDomainWorst : sélectionne la valeur qui maximise une fonction objectifUn autre exemple très classique : le carré magique ..
Dans un carré magique de $n x n$, on place les entiers de 1 à n^2 de telle manière que la somme des entiers de chaque ligne, chaque colonne et chaque diagonale soit égale à la même valeur, appelée constante magique. Cette constante peut être calculée avec la formule : $M = n(n^2 + 1) / 2$.
Prenez le code de carré magique et tester différentes stratégies de sélection de variables et de valeurs sur des carrés de tailles différentes.
Encore trop long ? Forcez l’affectation d’une variable (par exemple la première) pour réduire l’espace de recherche.