Programmation par contraintes

Les rationnels

La librarie clpq. Exemples d'emploi :
?- use_module(library(clpq)).
% library(clpq) compiled into clpq 0.08 sec, 977,560 bytes
true.

?- {X1>=0,X2>=0,X2=<3,X1+X2=<6}.
{X2>=0, X2=<3, _G4770= -6+X1+X2, X1+X2=<6, X1>=0}.

?- {X1>=0,X2>=0,X2=<3,X1+X2=<6},sup(X1+2*X2,Max).
Max = 9,
{X2>=0, X2=<3, _G10551= -6+X1+X2, X1+X2=<6, X1>=0}.

?- {X1>=0,X2>=0,X2=<3,X1+X2=<6},inf(X1+2*X2,Min).
Min = 0,
{X2>=0, X2=<3, _G15628= -6+X1+X2, X1+X2=<6, X1>=0}.

?-

Découpe de bois

On dispose de planches de Tamarin de 1 m de long et on a une commande de 36 planchettes de 28 cm et 24 planchettes de 45 cm. On souhaite minimiser les chutes de bois lors de la découpe.
Indications : montrer qu'il y a seulement trois configurations de découpe possibles dans une planche d'un mètre de long, raisonner dans les rationnels puis conclure dans les entiers.

Problème de transport

Il s'agit de déterminer l'approvisionnement en glaces Komik de points de vente à partir d'un ensemble d'usines en minimisant les coûts de transport. Les usines se trouvent à Saint Pierre (D1) et Saint Denis (D2). Les points de vente à approvisionner sont Le Port (A1), Saint Louis (A2) et Saint Joseph (A3). La matrice des coûts de transport est :
	A1	A2	A3
D1	5	1	1
D2	2	6	9
Les stocks et la demande sont :
stocks : 	D1=4	D2=6
demande :	A1=3	A2=5	A3=2
Indications : introduire 6 variables Xij représentant la quantité à transporter entre l'usine i et le point de vente j. Exprimer le coût du transport en fonction des Xij. Exprimer la contrainte sur les stocks : la quantité au départ d'une usine doit être inférieure au stock de cette usine. Exprimer que la demande doit être satisfaite. Résoudre dans les rationnels.

Gestion de production

La structure de production de l'entreprise TouzourPlisFré-TouzourPlisSer, lauréate du label Produit Réunion, est caractérisée par la confection de 3 produits P1, P2 et P3 tels que, pour une période de temps donnée (120 unités de travail au maximum) :
Produits                                                      P1        P2      P3
Volume maximal de la demande                                  20        10      30
Unités de travail nécessaire pour une production unitaire      2         3       2
Bénéfice unitaire                                              1         4       2
Le problème consiste à déterminer le programme de fabrication maximisant les gains de l'entreprise.
Indications : introduire 3 variables xi (le nombre d'articles Pi à fabriquer pendant la semaine), exprimer les trois contraintes et maximiser.

Ordonnancement de tâches

Il s'agit de déterminer un agenda des tâches de construction d'une maison de la société Apamoin pour minimiser le temps de construction. Il y a dix tâches à effectuer, chacune d'elle pouvant nécessiter l'achèvement d'une ou plusieurs autres tâches :
Code	Nom	        Durée	Nécessite
a	maçonnerie      7       _
b	charpente       3       a
c 	toit            1       b
d	sanitaire       8       a
e	façade          2       c,d
f	fenêtres        1       c,d
g	jardin          1       c,d
h 	plafond         3       f
j	peinture        2       h
k	finition        1       e,g,j
Indications : à chaque tâche est associée une variable, par exemple son code, dénotant le début de cette tâche. Traduire les contraintes de précédence avec les durées et minimiser la durée totale du projet (i.e., k+1).

Les domaines finis

:- use_module(library(clpfd)).

ONE + TWO + FIVE = EIGHT

Résoudre :
     ONE
 +   TWO
 +  FIVE
 -------
 = EIGHT
sachant qu'à deux lettres distinctes sont associées deux chiffres distincts et qu'aux lettres O, T, F et E sont associées des chiffres non-nuls.
Indications : s'inspirer de l'exemple SEND + MORE = MONEY défini ici. Observer la réduction du domaine des variables avant l'étiquetage. Il y a six solutions.

Le margouillat

Cinq hommes de nationalités distinctes habitent les cinq maisons d'une ruelle et pratiquent cinq activités professionelles différentes. Chaque personne a une préférence pour un animal et une boisson. Les animaux et les boissons sont tous différents. Les maisons sont peintes avec des couleurs toutes distinctes. De plus :
  1. l'Anglais habite la maison rouge,
  2. l'Espagnol possède un chien,
  3. le Japonais est peintre,
  4. l'Italien boit du thé,
  5. le Norvégien habite la première maison à gauche,
  6. le propriétaire de la maison verte boit du café,
  7. la maison verte se trouve juste à droite de la maison blanche,
  8. le sculpteur élève un serpent,
  9. le diplomate habite la maison jaune,
  10. on consomme beaucoup de lait dans la maison du milieu,
  11. la maison du Norvégien se trouve juste à coté de la maison bleue,
  12. la boisson préférée du violoniste est le jus de fruit,
  13. un des voisins du médecin possède un renard et
  14. un des voisins du diplomate possède un cheval.
Faire un plan détaillé de cette ruelle.
Indications : la solution est unique. Numéroter les maisons de 1 à 5. Définir la liste des nationalités, celles-ci sont toutes distinctes et prennent leurs valeurs dans 1 à 5. Idem pour les professions, les animaux, les boissons et les couleurs de maison. Traduire les contraintes puis étiqueter. NB : pour une gestion contrainte des disjonctions, considérer l'exemple suivant :
?- [X,Y] ins 0..1, (X #= Y+1) #\/ (X #= Y-1), label([X,Y]).

X = 0,
Y = 1 ;

X = 1,
Y = 0
?- 

Emploi du temps

Les organisateurs du congrès Komen totoch le Chik disposent de 3 salles et de 4 demi-journées durant lesquelles se tiendront onze sessions (A,B, …,K). Les sessions
        AJ, JI, IE, CF, FG, DH, BD, KE, BIHG, AGE, BHK, ABCH, DFJ
ne peuvent se tenir simultanément car il y a au moins un participant inscrit à toutes les sessions de ces ensembles. La session E doit avoir lieu avant la session J, et les sessions D et F avant K.
Déterminer un emploi du temps.
Indications : associer à chaque session une variable (A, B, …) à valeur dans {1,2,3,4}. Traduire les contraintes en utilisant entre autres la relation au_plus/3 définie ci-dessous (à inclure dans le fichier où sont développées les solutions de ces exos) puis étiqueter. Il y a 20 solutions.

Les relations nb_occ/3 et au_plus/3

  1. la relation nb_occ(N,[X1,...,Xk],I) exprime que N variables parmi les Xi prennent la valeur I.
    nb_occ(0,[],_).
    nb_occ(N,[X|Xs],I) :- 
    	( X #= I ) #<==> B,
    	N #= M+B,
    	nb_occ(M,Xs,I).
    
    Par exemple :
    ?- L=[X,Y], L ins 0..1, nb_occ(0,[X,Y],1).
    L = [0, 0],
    X = Y, Y = 0 ;
    false.
    
    ?- 
    
  2. la relation au_plus(N,[X1,...,Xk],I) exprime qu'au plus N variables parmi les Xi prennent la valeur I.
    au_plus(N,Xs,I) :-
    	N #>= M, 
    	nb_occ(M,Xs,I).
    
    Par exemple :
    ?- L=[X,Y], L ins 0..1, au_plus(1,L,0), label(L).
    L = [0, 1],
    X = 0,
    Y = 1 ;
    L = [1, 0],
    X = 1,
    Y = 0 ;
    L = [1, 1],
    X = Y, Y = 1 ;
    false.
    
    ?- 

Location d'entrepôts

Les dirigeants de la société Moinlapeur-Midiaou souhaitent prendre une décision au sujet de la location d'entrepôts pour desservir cinq usines. Trois entrepôts sont disponibles : E1 de coût 18, E2 de coût 10, E3 de coût 28. La matrice des coûts de transports est :
 
	U1	U2	U3	U4	U5
E1	5	4	infini	infini	3
E2	7	infini	2	infini	infini
E3	infini	1	5	4	8
Les coûts infinis correspondent bien sûr au passage de la route en corniche. On suppose de plus que chaque usine est desservie par un unique entrepôt. En minimisant le coût total, décider du choix des entrepôts à louer et pour chaque usine de l'entrepôt la desservant.
Indications : introduire trois variables Ei à valeur dans {0,1} telles que Ei=1 ssi on loue Ei et cinq variables Ui à valeur dans {1,2,3} telles que Ui=j ssi l'usine Ui est desservie par Ej. Exprimer les contraintes puis étiqueter en minimisant le coût. Il y a une unique solution de coût minimum 60.

Suit mazik

Soit S la suite d'entiers naturels [s0,s1,…,sn]. S est dite mazik ssi pour tout i, 0≤i≤n, si est le nombre d'apparition du nombre i dans S, i.e., si = card({j| 0≤j≤n et j=i}). Par exemple, [1,2,1,0] et [2,0,2,0] sont deux solutions pour n=3, [2,1,2,0,0] est une solution pour n=4.
  1. Justifier que pour tout 0≤i≤n, si≤n+1. En déduire une définition suit_mazik(N,L) résolvant le problème.
  2. Que penser de la somme des si pour 0≤i≤n ? Inclure cette propriété dans le programme et comparer les temps d'exécution avec la version précédente.
  3. Que penser de la somme i*si pour 0≤i≤n ? Inclure cette propriété dans le programme et comparer les temps d'exécution avec les versions précédentes
  4. Conjecturer la forme des solutions pour tout n. Démontrer ce résulat et en déduire un programme de complexité linéaire en fonction de n.
Indications : la définition n'est pas directement exécutable et l'ajout successif de propriétés fait décroître les temps de calcul ; à ce propos, essayer apropos(time). et help(time).

Golomb

Il s'agit de trouver les valeurs entières correspondant aux graduations d'une règle telles que les différences entre deux graduations soient toutes distinctes et que la longueur de la règle soit minimale (applications : positionnement de radiotélescopes, conceptions d'antennes).
Indications : le problème peut être représenté par un ensemble de n variables gi et de n(n-1)/2 variables représentant les différences gi - gj pour i>j (d'où le n(n-1)/2). On peut poser par convention g0=0 et ajouter les contraintes g0 < g1 < ... < gn-1. Par exemple : Autre solution plus économique en nombre de variables : on utilise n-1 variables de base di=gi+1 -gi. On profite ensuite des propriétés de la distance linéaire pour définir les distances successives (par exemple g3-g1=d2+d1) qui doivent être toutes distinctes. La longueur de la règle, que l'on doit minimiser, est d1+ ... +dn-1.
Fred Mesnard