<< Page principale
Minizinc se définit comme un langage de modélisation de contraintes Libre et Open-Source.
Les contraintes sont ensuite traduites en un langage bas niveau nommé FlatZinc qui permet une interface avec des solveurs tel Gecode.
L'intérêt de Minizinc et qu'il permet de définir des CSP et des CSP avec optimisation et de les résoudre en faisant appel à un solveur. Il existe une interface avec Python qui permet d'appeler Minizinc et de récupérer les solutions.
La documentation de Minizinc est disponible à partir de cette page.
Le reste de cette page consiste en une introduction très succinte de Minizinc.
Je ne suis pas parvenu à installer minizinc avec Anaconda, j'ai donc utilisé le python disponible par défaut sous Linux Ubuntu 20.04.2 :
richer@zentopia:\$ conda deactivate
richer@zentopia:\$ pip3 install minizinc
richer@zentopia:\$ sudo snap install minizinc --classic
La première ligne désactive Anaconda (il n'est donc pas nécessaire de la saisir si vous n'avez pas installé Anaconda) afin d'utiliser le Python par défaut (version 3.8.5).
Il est possible d'utiliser Minizinc sous forme d'une interface graphique :
Pour cela, il faut se rendre sur la page Software et télécharger le programme 64 bit Windows Installer ou 64 bit Linux AppImage.
Si vous avez réalisé l'installation avec snap (Ubuntu), il faut lancer minizinc_ide .
Pour communiquer avec Python, il faut :
Voici un exemple simple qui reprend les étapes précédentes :
On obtient en résultat la variable solutions qui est le résultat renvoyé par le solveur. Puis on affiche chaque couple (x,y) de chaque solution :
richer@zentopia:\$ python3 minizinc_python.py
[Solution(x=3, y=0, _output_item='', _checker=''), Solution(x=3, y=1, _output_item='', _checker=''), Solution(x=3, y=2, _output_item='', _checker=''), Solution(x=3, y=3, _output_item='', _checker=''), Solution(x=4, y=0, _output_item='', _checker=''), Solution(x=4, y=1, _output_item='', _checker='')]
3 0
3 1
3 2
3 3
4 0
4 1
On pourra se référer au MiniZinc Handbook pour de plus amples informations.
Les paramètres (ou constantes) sont déclarés comme suit et on doit leur attribuer une valeur:
On peut déclarer des entiers (int), des réels (float), des booléens (bool) et des chaînes de caractères (string).
Les variables (appelées variables de décision) n'ont pas de valeur initiale. C'est le solveur qui se chargera de leur attribuer une valeur :
Les contraintes sont introduites par le mot clé constraint :
Les contraintes de type alldifferent expriment le fait qu'un ensemble de variables prennent des valeurs différentes, ou autrement dit, que deux variables ne peuvent avoir la même valeur :
Le mot clé forall permet de réaliser l'enumération sur une variable de boucle :
Dans le cas du voyageur de commerce, il faut exprimer le fait que l'on passe d'une ville à l'autre en définissant un tableau $d$ (en plus du tableau $x$ qui indique l'ordre de passage) sur lequel on exprime les distances parcourues :
La contrainte circuit(x) force les éléments de $x$ à définir un circuit où $x [ i ] = j$ signifie que $j$ est le successeur de $i$.
La déclaration de la résolution utilise souvent solve satisfy, mais dans d'autres cas comme celui du voyageur de commerce ou du sac à dos, il faut minimiser ou maximiser une quantité.
Il peut aussi être intéressant de contrôler la recherche (cf N Reines). C'est ce que permet de faire int_search et autres bool_search, float_search , seq_search :
Le contrôle qu' autorise int_search( <variables>, <varchoice>, <constrainchoice> )
permet de définir les variables à prendre en considération, la stratégie de choix de variables et la stratégie de choix de contraintes sur les variables. On pourra consulter cette page pour voir l'ensemble des possibilités offertes. Voici quelques exemples :
Exercice 4.1
En se basant sur la représentation du problème SEND + MORE = MONEY, résoudre les problèmes suivants :
Vous trouverez d'autres exemples sur cette page.