TD Exercice 1
                    
                    Placer 
                      sur un échiquier de taille n, n reines telles quaucune 
                      dentre elles ne soit en prise.
                    Modéliser 
                      le problème et trouver la solution au problème 
                      en utilisant le solveur Choco 2.0. 
                     
                    Solution 
                      Modèle 1 
                    Comment 
                      modéliser le problème avec les contraintes 
                      déjà évoquées ?
                    On 
                      associe à chaque ligne une variable précisant 
                      la position de la reine dans le ligne
                    
                      - Une 
                        variable énumérée par ligne : X1=[[1,n]] 
                        
- Une 
                        reine par ligne (cest évident)
- Une 
                        reine par colonne : 
                        
                      
- Une 
                        reine par diagonale :
                        
                          - allDifferent(X1+1, 
                            X2+2, 
 Xn+n)
- allDifferent(X1-1, 
                            X2-2, 
 Xn-n)
 
Modèle 
                      plus classique en PPC : moins de variables et moins 
                      de contraintes
                    
                    Voici 
                      le code java en Choco 
                      2.0 de ce premier modèle :
                    import 
                      choco.kernel.model.Model;
                      import choco.kernel.model.variables.integer.IntegerVariable;
                      import choco.kernel.solver.Solver;
                      import choco.cp.model.CPModel;
                      import choco.cp.solver.CPSolver;
                      import choco.Choco;
                    public 
                      class NReinesModel1 {
                     public 
                      static final int NB_REINES = 10;
public 
                      static final int NB_REINES = 10;
                     
                       public 
                      static void main(String[] args) {
public 
                      static void main(String[] args) {
                    
 // 
                      0. Création du problème
// 
                      0. Création du problème 
                      
 Model 
                      m = new CPModel();
Model 
                      m = new CPModel();
                     
                      
 // 
                      1. Création des variables
// 
                      1. Création des variables 
                      
 IntegerVariable[] 
                      vars = createVariables(m);
IntegerVariable[] 
                      vars = createVariables(m);
                     
                      
 // 
                      2. Création des contraintes
// 
                      2. Création des contraintes 
                      
 postConstraints 
                      ( m, vars );
postConstraints 
                      ( m, vars );
                     
                      
 // 
                      3. Choix solver et heuristique
// 
                      3. Choix solver et heuristique 
                      
 Solver 
                      s = new CPSolver ();
Solver 
                      s = new CPSolver ();
                      
 s.read(m);
s.read(m);
                      
 setHeuristic(s);
setHeuristic(s);
                     
                      
 // 
                      4. Résolution du problème
// 
                      4. Résolution du problème 
                      
 s.solve();
s.solve();
                     
                      
 // 
                      5. Récupérer la solution
// 
                      5. Récupérer la solution 
                      
 displayResult(s, 
                      vars);
displayResult(s, 
                      vars);
                       }
} 
                     // 
                      1. Création des variables
// 
                      1. Création des variables 
                       private 
                      static IntegerVariable[] createVariables(Model m) {
private 
                      static IntegerVariable[] createVariables(Model m) {
                      
 IntegerVariable[] 
                      vars = new IntegerVariable[NB_REINES];
IntegerVariable[] 
                      vars = new IntegerVariable[NB_REINES];
                      
 for 
                      (int i = 0; i < NB_REINES; i++) {
for 
                      (int i = 0; i < NB_REINES; i++) {
                      

 vars[i] 
                      = Choco.makeIntVar("x" + i, 0, NB_REINES - 1);
vars[i] 
                      = Choco.makeIntVar("x" + i, 0, NB_REINES - 1);
                      
 }
}
                      
 return 
                      vars;
return 
                      vars;
                       }
}
                     
                       // 
                      2. Création des contraintes
// 
                      2. Création des contraintes 
                       private 
                      static void postConstraints(Model m, IntegerVariable[] vars) 
                      {
private 
                      static void postConstraints(Model m, IntegerVariable[] vars) 
                      {
                      
 postConstraints1(m, 
                      vars);
postConstraints1(m, 
                      vars);
                      
 postConstraints2(m, 
                      vars);
postConstraints2(m, 
                      vars);
                       }
}
                      
                     
                       // 
                      2.1. Une reine par colonne
// 
                      2.1. Une reine par colonne
                       private 
                      static void postConstraints1(Model m, IntegerVariable[] 
                      vars) {
private 
                      static void postConstraints1(Model m, IntegerVariable[] 
                      vars) {
                      
 for(int 
                      i = 0; i < NB_REINES; i++) {
for(int 
                      i = 0; i < NB_REINES; i++) {
                      

 for(int 
                      j = i+1; j < NB_REINES; j++) {
for(int 
                      j = i+1; j < NB_REINES; j++) {
                      


 m.addConstraint( 
                      Choco.neq(vars[i], vars[j]) );
m.addConstraint( 
                      Choco.neq(vars[i], vars[j]) );
                      

 }
}
                      
 }
}
                       }
}
                     // 
                      2.2. Une reine par diagonale
// 
                      2.2. Une reine par diagonale
                       private 
                      static void postConstraints2(Model m, IntegerVariable[] 
                      vars) {
private 
                      static void postConstraints2(Model m, IntegerVariable[] 
                      vars) {
                      
 for 
                      (int i = 0; i < NB_REINES; i++) {
for 
                      (int i = 0; i < NB_REINES; i++) {
                      

 for 
                      (int j = i + 1; j < NB_REINES; j++) {
for 
                      (int j = i + 1; j < NB_REINES; j++) {
                      


 int 
                      k = j - i;
int 
                      k = j - i;
                      


 m.addConstraint(Choco.neq(vars[i], 
                      Choco.plus(vars[j], k)));
m.addConstraint(Choco.neq(vars[i], 
                      Choco.plus(vars[j], k)));
                      


 m.addConstraint(Choco.neq(vars[i], 
                      Choco.minus(vars[j], k)));
m.addConstraint(Choco.neq(vars[i], 
                      Choco.minus(vars[j], k)));
                      

 }
}
                      
 }
}
                       }
}
                     
                       // 
                      3. Réglage de l'heuristique de choix de valeurs
// 
                      3. Réglage de l'heuristique de choix de valeurs
                       private 
                      static void setHeuristic(Solver s) {
private 
                      static void setHeuristic(Solver s) {
                      
 s.setValIntIterator(new 
                      DecreasingDomain());
s.setValIntIterator(new 
                      DecreasingDomain());
                       }
}
                     
                       // 
                      5. Affichage des résultats
// 
                      5. Affichage des résultats
                       private 
                      static void displayResult(Solver s, IntegerVariable[] vars) 
                      {
private 
                      static void displayResult(Solver s, IntegerVariable[] vars) 
                      {
                      
 if 
                      (s.getNbSolutions() > 0) {
if 
                      (s.getNbSolutions() > 0) {
                      

 System.out.println("Solution 
                      trouve : ");
System.out.println("Solution 
                      trouve : ");
                      

 for 
                      (int i = 0; i < NB_REINES; i++) {
for 
                      (int i = 0; i < NB_REINES; i++) {
                      


 int 
                      val = s.getVar(vars[i]).getVal();
int 
                      val = s.getVar(vars[i]).getVal();
                      


 for 
                      (int j = 0; j < NB_REINES; j++) {
for 
                      (int j = 0; j < NB_REINES; j++) {
                      



 System.out.print(val 
                      == j ? "R " : ". ");
System.out.print(val 
                      == j ? "R " : ". ");
                      


 }
}
                      


 System.out.println("");
System.out.println("");
                      

 }
}
                      
 } 
                      else {
} 
                      else {
                      

 System.out.println("Pas 
                      de solution trouve !!");
System.out.println("Pas 
                      de solution trouve !!");
                      
 }
}
                       }
}
                     
                    Solution 
                      Modèle 2
                    On 
                      associe à chaque case un booléen (reine présente 
                      ou non)
                    Xij 
                      = { 0,1 } avec 0 pas reine, 1 une reine
                    Une 
                      reine par ligne : 
                      
                      
                    De 
                      même pour les colonnes et les diagonales (partielles 
                      ou non).
                    Modèle 
                      classique à la Programmation Linéaire.
                    
                    Voici 
                      le code java en Choco 
                      2.0 de ce second modèle :
                    import 
                      choco.kernel.model.Model;
                      import choco.kernel.model.variables.integer.IntegerVariable;
                      import choco.kernel.solver.Solver;
                      import choco.cp.model.CPModel;
                      import choco.cp.solver.CPSolver;
                      import choco.cp.solver.search.integer.valiterator.DecreasingDomain;
                      import choco.Choco;
                    import 
                      java.util.List;
                      import java.util.ArrayList;
                    public 
                      class NReineModele2 {
                     public 
                      static final int NB_REINES = 10;
public 
                      static final int NB_REINES = 10;
                     
                       public 
                      static void main(String[] args) {
public 
                      static void main(String[] args) {
                    
 long 
                      time = System.currentTimeMillis();
long 
                      time = System.currentTimeMillis();
                    
 System.out.println("NReine 
                      mod?le 1");
System.out.println("NReine 
                      mod?le 1");
                     
                      
 // 
                      0. Création du problème
// 
                      0. Création du problème 
                      
 Model 
                      m = new CPModel();
Model 
                      m = new CPModel();
                     
                      
 // 
                      1. Création des variables
// 
                      1. Création des variables 
                      
 IntegerVariable[] 
                      vars =
IntegerVariable[] 
                      vars =
                      
 createVariables(m);
createVariables(m);
                     
                      
 // 
                      2. Création des contraintes
// 
                      2. Création des contraintes 
                      
                      
 postConstraints(m, 
                      vars);
postConstraints(m, 
                      vars);
                     
                      
 // 
                      3. Choix solver et heuristique
// 
                      3. Choix solver et heuristique 
                      
                      
 Solver 
                      s = new CPSolver();
Solver 
                      s = new CPSolver();
                      
 s.read(m);
s.read(m);
                      
 setHeuristic(s);
setHeuristic(s);
                     
                      
 // 
                      4. Résolution du problème
// 
                      4. Résolution du problème 
                      
 s.solve();
s.solve();
                     
                      
 // 
                      5. Récupération de la solution
// 
                      5. Récupération de la solution 
                      
 displayResult(s, 
                      vars);
displayResult(s, 
                      vars);
                     
                      
 System.out.println("Time 
                      ellapsed: " + (System.currentTimeMillis() - time) + 
                      "ms.");
System.out.println("Time 
                      ellapsed: " + (System.currentTimeMillis() - time) + 
                      "ms.");
                       }
}
                     
                       // 
                      1. Création des 
                      variables
// 
                      1. Création des 
                      variables
                       private 
                      static IntegerVariable[] createVariables(Model m) {
private 
                      static IntegerVariable[] createVariables(Model m) {
                      
 IntegerVariable[] 
                      vars = new IntegerVariable[NB_REINES * NB_REINES];
IntegerVariable[] 
                      vars = new IntegerVariable[NB_REINES * NB_REINES];
                      
 for 
                      (int i = 0; i < NB_REINES; i++) {
for 
                      (int i = 0; i < NB_REINES; i++) {
                      

 for 
                      (int j = 0; j < NB_REINES; j++) {
for 
                      (int j = 0; j < NB_REINES; j++) {
                      


 vars[index(i, 
                      j)] = Choco.makeIntVar("x" + i + "_" 
                      + j, 0, 1);
vars[index(i, 
                      j)] = Choco.makeIntVar("x" + i + "_" 
                      + j, 0, 1);
                      

 }
}
                      
 }
}
                      
 return 
                      vars;
return 
                      vars;
                       }
}
                     
                       // 
                      2. Création des 
                      contraintes
// 
                      2. Création des 
                      contraintes
                       private 
                      static void postConstraints(Model m, IntegerVariable[] vars) 
                      {
private 
                      static void postConstraints(Model m, IntegerVariable[] vars) 
                      {
                      
 postConstraints1(m, 
                      vars);
postConstraints1(m, 
                      vars);
                      
 postConstraints2(m, 
                      vars);
postConstraints2(m, 
                      vars);
                       }
}
                     
                       // 
                      2.1. Une occurence par ligne et par colonne
// 
                      2.1. Une occurence par ligne et par colonne
                       private 
                      static void postConstraints1(Model m, IntegerVariable[] 
                      vars) {
private 
                      static void postConstraints1(Model m, IntegerVariable[] 
                      vars) {
                      
 IntegerVariable 
                      one = Choco.makeConstantVar("one", 1);
IntegerVariable 
                      one = Choco.makeConstantVar("one", 1);
                      
 for 
                      (int i = 0; i < NB_REINES; i++) {
for 
                      (int i = 0; i < NB_REINES; i++) {
                      

 IntegerVariable[] 
                      col = new IntegerVariable[NB_REINES];
IntegerVariable[] 
                      col = new IntegerVariable[NB_REINES];
                      

 IntegerVariable[] 
                      line = new IntegerVariable[NB_REINES];
IntegerVariable[] 
                      line = new IntegerVariable[NB_REINES];
                      

 for 
                      (int j = 0; j < NB_REINES; j++) {
for 
                      (int j = 0; j < NB_REINES; j++) {
                      


 col[j] 
                      = vars[index(i, j)];
col[j] 
                      = vars[index(i, j)];
                      


 line[j] 
                      = vars[index(j, i)];
line[j] 
                      = vars[index(j, i)];
                      

 }
}
                      

 m.addConstraint(Choco.occurrence(1, 
                      one, col));
m.addConstraint(Choco.occurrence(1, 
                      one, col));
                      

 m.addConstraint(Choco.occurrence(1, 
                      one, line));
m.addConstraint(Choco.occurrence(1, 
                      one, line));
                      
 }
}
                       }
}
                     
                       // 
                      2.2 Une 
                      occurence par diagonale
// 
                      2.2 Une 
                      occurence par diagonale
                       private 
                      static void postConstraints2(Model m, IntegerVariable[] 
                      vars) {
private 
                      static void postConstraints2(Model m, IntegerVariable[] 
                      vars) {
                      
 IntegerVariable 
                      one = Choco.makeConstantVar("one", 1);
IntegerVariable 
                      one = Choco.makeConstantVar("one", 1);
                      
 for 
                      (int diag = 0; diag < 2 * NB_REINES - 1; diag++) {
for 
                      (int diag = 0; diag < 2 * NB_REINES - 1; diag++) {
                      

 List<IntegerVariable> 
                      diag1 = new ArrayList<IntegerVariable>();
List<IntegerVariable> 
                      diag1 = new ArrayList<IntegerVariable>();
                      

 List<IntegerVariable> 
                      diag2 = new ArrayList<IntegerVariable>();
List<IntegerVariable> 
                      diag2 = new ArrayList<IntegerVariable>();
                      

 for 
                      (int i = 0; i < NB_REINES; i++) {
for 
                      (int i = 0; i < NB_REINES; i++) {
                      


 int 
                      index1 = index(i, i + diag - NB_REINES + 1);
int 
                      index1 = index(i, i + diag - NB_REINES + 1);
                      


 int 
                      index2 = index(NB_REINES - i - 1, i + diag - NB_REINES + 
                      1);
int 
                      index2 = index(NB_REINES - i - 1, i + diag - NB_REINES + 
                      1);
                      


 if 
                      (index1 >= 0 && index1 < NB_REINES * NB_REINES) 
                      {
if 
                      (index1 >= 0 && index1 < NB_REINES * NB_REINES) 
                      {
                      



 diag1.add(vars[index1]);
diag1.add(vars[index1]);
                      


 }
}
                      


 if 
                      (index2 >= 0 && index2 < NB_REINES * NB_REINES) 
                      {
if 
                      (index2 >= 0 && index2 < NB_REINES * NB_REINES) 
                      {
                      



 diag2.add(vars[index2]);
diag2.add(vars[index2]);
                      

 }
}
                      
 }
}
                      
 m.addConstraint(Choco.occurrenceMax(1, 
                      one, diag1.toArray(new IntegerVariable[]{})));
m.addConstraint(Choco.occurrenceMax(1, 
                      one, diag1.toArray(new IntegerVariable[]{})));
                      
 m.addConstraint(Choco.occurrenceMax(1, 
                      one, diag2.toArray(new IntegerVariable[]{})));
m.addConstraint(Choco.occurrenceMax(1, 
                      one, diag2.toArray(new IntegerVariable[]{})));
                      
 }
}
                       }
}
                     
                       // 
                      3. Réglage de l'heuristique
// 
                      3. Réglage de l'heuristique
                       private 
                      static void setHeuristic(Solver s) {
private 
                      static void setHeuristic(Solver s) {
                      
 s.setValIntIterator(new 
                      DecreasingDomain());
s.setValIntIterator(new 
                      DecreasingDomain());
                       }
}
                     
                       // 
                      5. Affichage des résultats
// 
                      5. Affichage des résultats
                       private 
                      static int index(int i, int j) {
private 
                      static int index(int i, int j) {
                      
 if 
                      (i < 0 || i >= NB_REINES) return -1;
if 
                      (i < 0 || i >= NB_REINES) return -1;
                      
 if 
                      (j < 0 || j >= NB_REINES) return -1;
if 
                      (j < 0 || j >= NB_REINES) return -1;
                      
 return 
                      i * NB_REINES + j;
return 
                      i * NB_REINES + j;
                       }
}
                     
                       // 
                      5. Affichage des résultats
// 
                      5. Affichage des résultats
                       private 
                      static void displayResult(Solver s, IntegerVariable[] vars) 
                      {
private 
                      static void displayResult(Solver s, IntegerVariable[] vars) 
                      {
                      
 if 
                      (s.getNbSolutions() > 0) {
if 
                      (s.getNbSolutions() > 0) {
                      

 System.out.println("Solution 
                      trouvée : ");
System.out.println("Solution 
                      trouvée : ");
                      

 for 
                      (int i = 0; i < NB_REINES; i++) {
for 
                      (int i = 0; i < NB_REINES; i++) {
                      


 for 
                      (int j = 0; j < NB_REINES; j++) {
for 
                      (int j = 0; j < NB_REINES; j++) {
                      



 System.out.print(s.getVar(vars[index(i, 
                      j)]).getVal() == 1 ? "R " : ". ");
System.out.print(s.getVar(vars[index(i, 
                      j)]).getVal() == 1 ? "R " : ". ");
                      


 }
}
                      


 System.out.println("");
System.out.println("");
                      

 }
}
                      
 }
}
                      
 else 
                      {
else 
                      {
                      

 System.out.println("Pas 
                      de solution trouvée !!");
System.out.println("Pas 
                      de solution trouvée !!");
                      
 }
}
                       }
}
                    
                      }
                      
                    
                       
                     
                     
                      
Voici 
  le plan de cette présentation sur la programmation par contraintes
  - Les 
    notions de base 
    :  
    
  
- Quelques 
    notions avancées : 
- Quelques 
    exemples pour utiliser la P.P.C. : 
    
  
Cette page 
  a été co-réalisée avec Guillaume 
  Rochart, docteur en mathématiques dans mon équipe de 
  recherche au Bouygues 
  e-lab.10/03/2009.
