rapport final - par Pascal Brunot

publicité
Rapport de programmation par contraintes
Rapport de programmation par contraintes
Implémentation d’un problème d’emploi du temps
Pascal Brunot
Hadrien Cambazard
Page 1 / 4
Rapport de programmation par contraintes
Nous avions retenu dans la première étape, 3 modélisations qui nous
semblaient pertinentes dont nous rappelons ici simplement la teneur pour pouvoir en
discuter. Nous essayerons de présenter notre démarche, les conclusions auxquelles
nous sommes parvenues et les résultats concrets.
Modélisation 1
i  [1, Nc],
salle i : [1..Ns]
creneaui : [1..45]
Modélisation 2
(i, j )  [1,45]  [1, Ns],
coursij : [1..Nc]
Modélisation 3
i  [1, Nc],
coursi : [1..45  Ns]
Par ailleurs, nous avons beaucoup travaillé sur l’aspect de pré-traitement des
données, qui visent à établir la liste des salles possibles par cours de manière à
réduire très rapidement les domaines des variables. Nous disposons pour la
modélisation de tableaux pour accéder rapidement aux différentes informations
utilises (listes des cours par étudiant, liste des étudiants par cours…).
 La modélisation 1 n’est pas satisfaisante vis-à-vis de la contrainte 3 (un seul
cours par salle, à chaque créneau horaire) qui prend la forme d’un allDifferent sur
des expressions uniques associées à chaque couple (créneau, salle). On peut
trouver une solution pour environ une centaine de cours mais pas au delà . Nous
l’avons implémentée en Choco (cf. pbEDT1.cl).
 Les modélisations 1 et 2 sont « symétriques ». Tandis que la première associe
un créneau et une salle à chaque cours, la deuxième place les cours dans chaque
couple (créneau, salle) d’un tableau Ns x Nc (on a donc besoin d’un cours fictif, le
cours 0, ce qui empêche l’utilisation du allDifferent). Néanmoins la modélisation 2
nous semblait plus prometteuse car la contrainte 3 s’exprime simplement à l’aide
d’un occur. Nous avons constaté que cette approche n’était également pas viable, on
ne parvient pas à trouver des solutions même en ne posant que les contraintes 2 et
3. (cf. pbEDT2.cl) La contrainte occur semble plus difficile à mettre en œuvre que le
allDifferent. Pour pouvoir exprimer facilement la contrainte 3 nous nous sommes
tournés vers une modélisation que nous avions identifiée dans « autres
modélisations envisagées » dans notre premier rapport.
 Il est possible dans cette 3ème modélisation de trouver une solution aux
contraintes 2 et 3 instantanément. En effet la contrainte 3 s’exprime comme un
simple allDifferent sur l’ensemble des variables. On peut, pour la contrainte 2,
éliminer du domaine de chaque variable (dans une phase de pré calcul) les valeurs
dans [1..45xNombre de salles] qui correspondent à des salles impossibles pour ce
cours. On obtient immédiatement une solution à ces 2 contraintes, là où la
modélisation 2 ne donnait aucun résultat (cf. pbEDT3 .cl). Le problème est de
pouvoir exprimer la contrainte 1 sur les élèves car on ne dispose plus de l’information
sur les créneaux comme dans la modélisation 1.
La modélisation 3 consiste à « fusionner » les deux variables de la modélisation
1. La première modélisation est très adaptée pour la contrainte n°1 (concernant les
Page 2 / 4
Rapport de programmation par contraintes
cours d’un même élève) et la 3ème modélisation pour la contrainte n°3. Nous avons
donc envisagé de mélanger ces modélisations pour conserver l’information qui
permet d’exprimer ces 2 contraintes. On relie ainsi par des contraintes les variables
des deux modélisations pour les faire correspondre à une même solution. Cette
approche « hybride » (cf. pbEDT3bis.cl) ne donne pas plus de résultats !
Par ailleurs nous n’avons pas réussi à coder cette contrainte 1 en Choco.
(l’utilisation de table bidimensionnelles reste un mystère, nous souhaitions en effet
utiliser getNth(table,i,j) mais nous n’avons jamais pu créer de table qui soit )
 Nous avons alors décider d’implémenter cette modélisation 3 sous JSolver qui
permet notamment l’utilisation des contraintes arithmétiques utilisant l’opérateur de
division entière (ce que ne fait pas Choco) on peut ainsi retrouver le créneau de
chaque cours et poser des allDifferent sur les créneaux des cours suivis par un
même élève (sans passer par une modélisation « hybride » comme envisagée
précédemment, ni introduire aucune variable intermédiaire - cf. EdtProbleme3.java).
C’est finalement en changeant l’heuristique de choix des variables à instancier
que nous avons fini par obtenir une solution ! Ainsi, au lieu d’instancier les variables
dans l’ordre de leur numérotation, nous avons imposé d’instancier la variable de plus
petit domaine d’abord (ce qui n’était pas la méthode par défaut !). Ainsi tout notre
travail précédent sur le traitement des données a pris son intérêt quand nous avons
enfin obtenu une solution.
En ce qui concerne l’optimisation, nous sommes parvenus à implémenter la
contrainte 4 (éviter qu’un étudiant ait un cours au dernier créneau de la journée).
La contrainte 5 a été implémentée et fonctionne sur moins de 10 élèves. Au
delà, il se pose un problème de mémoire. De ce fait nous n’avons pas cherché à
implémenter la contrainte 6.
Voici les résultats obtenus :
Instances
1
2
3
4
5
6
7
8
9
10
Temps
(seconde)
Heuristique
de
recherche
Nombre de
backtracks
Note
(pénalité 1)
Note
globale
21’
50’
177’
27’
25’
13’
595’
47’

74’
(1)
(1)
(1)
(2)
(1)
(1)
(1)
(1)
(1)
(2)
(3)
Page 3 / 4
(1)
4015 15571 109815 4278 4185 1094 229927 12052
/
11772
248
249
204
433
777
743
727
1177 1416 1213
452
416
0
309
/
219
1086
979
/
766
instanciation des variables dont les domaines sont de taille minimum
d’abord (définie en standard dans JSolver)
instanciation des variables sur lesquelles portent sur le plus de
contraintes (pour provoquer des backtracks au plus tôt) et pondéré
par les domaines de taille minimum. (cf. HeuristiquePerso.java)
Choix de la valeur de la variable qui place le cours dans les derniers
créneaux. (cf. HeuristiquePerso2.java). N’apporte rien de
concluant.
Rapport de programmation par contraintes
Remarques sur les champs du tableau :
-
Deux heuristiques de choix sont possibles, on peut orienter le choix
des variables à instancier ((1) et (2)) mais aussi la valeur choisie
dans les domaines (3) (cette heuristique entraîne une diminution de
la note plus qu’autre chose).
-
La note sur la pénalité 1 est la note minimale que nous sommes
parvenue à trouver (en optimisant selon cette contrainte)
-
La note globale est la note évaluée à la découverte d’une solution
(elle n’est pas codée en tant que contraintes et n’est donc pas utilisé
pour orienter la recherche) On relance en revanche la recherche
jusqu'à obtenir une note minimale sur laquelle le temps de
résolution devient « infini ». Nous avons ici simplement cherché à
connaître la note minimale que nous pouvions raisonnablement
atteindre.
Nous avons observé qu’une recherche non guidée vers les meilleures solutions (« au
hasard ») ne permet pas d’améliorer le score des solutions.
Conclusion :
La modélisation 3 nous semble effectivement la meilleure, mais tout dépend
du parcours dans l’arbre (On remarque par exemple que nous ne parvenons pas
résoudre l’instance 1 en utilisant l’heuristique 2). Le problème est donc très
complexe, on ne peut pas se permettre de tout explorer, il faut orienter la recherche
et ceci, éventuellement, pour chaque instance. Ainsi nous ne sommes pas parvenu à
trouver une solution pour l’instance 9.
Voies d’amélioration de notre modèle :
-
-
-
Page 4 / 4
Guider mieux la recherche des solutions en implémentant d’une
manière plus économe en mémoire les contraintes de préférences 2
(qui marche pour les dix premiers élèves environs) et la contrainte
3. Cela pourrait être fait en simplifiant la fonction IloIntExpr
kronecker(IloIntExpr,int).
Trouver les critères (cours différents/étudiants ? cours/salles ? )
capables de nous indiquer une heuristique à utiliser (métaheuristique).
Utiliser une heuristique de choix des valeurs des variables qui
implémenterait une évaluation « partielle » de la solution. Nous
avons manqué de temps pour la réaliser.
Téléchargement