• [^] # Re: Programmation par contraintes

    Posté par . En réponse au message Générer un tableau à partir de contraintes. Évalué à 3.

    En relisant ton message, je vois que tu cherches "un logiciel", et pas vraiment un langage. Bon, donc je suis limite off-topic, mais en fait non, pas vraiment : on n'a finalement pas besoin d'un logiciel bien paufiné quand on a un bon interpréteur Prolog sous la main... Voilà ton problème en Prolog Eclispe (le seul que j'ai sous la main). Le gros du code servirait pour n'importe quel autre problème du même type, donc c'est fait une fois pour toutes, et seul le prédicat "contraintes(M)" est spécifique à ton cas :
    % chargement du solveur
    :- lib(fd).
    % tableau 2D -> ligne (liste)
    ligne(M,I,L) :-
    	dim(M,[_,Y]),
    	length(L,Y),
    	(for(J,1,Y), foreach(A,L), param(M,I) do
    		A is M[I,J]).
    % tableau 2D -> colonne (liste)
    colonne(M,J,C) :-
    	dim(M,[X,_]),
    	length(C,X),
    	(for(I,1,X), foreach(A,C), param(M,J) do
    		A is M[I,J]).
    % contrainte sur la somme des éléments d'une liste
    sigma(L,S) :-
    	(foreach(X,L), fromto(0,A,B,S) do
    		B #= A + X).
    % liste de toutes les variables d'un tableau 2D
    variables(M,V) :-
    	dim(M,[X,_]),
    	(for(I,1,X), fromto([],V1,V2,V), param(M) do
    		ligne(M,I,L), append(V1,L,V2)).
    % impose un domaine sur toutes les variables
    domaine(M,D) :-
    	variables(M,V), V::D.
    % les contraintes particuulières
    contraintes(M) :- 
    	% le tableau est de dimension 3x5
    	dim(M,[3,5]),
    	% avec des valeurs entières dans [1,9]
    	domaine(M,[1..9]),
    	% AB vaut 3
    	AB is M[1,2], AB #= 3,
    	% BE vaut 5
    	BE is M[2,5], BE #= 5,
    	% CD ne vaut pas 2
    	CD is M[3,4], CD #\= 2,
    	% la somme de la ligne A est 19...
    	ligne(M,1,LigA),
    	sigma(LigA,19),
    	% ...et elle ne comporte pas de 5
    	(foreach(X,LigA) do X #\= 5),
    	% la somme de la colonne A est 10
    	colonne(M,1,ColA),
    	sigma(ColA,10),
    	% les valeurs d'une même ligne sont distinctes
    	(for(I,1,3), param(M) do
    		ligne(M,I,L),
    		alldifferent(L)).
    probleme(M) :-
    	% on impose des contraintes
    	contraintes(M),
    	% et on énumère les valeurs possibles des variables
    	variables(M,V),
    	labeling(V).
    
    Pour obtenir les solution, je demande "probleme(M)" à Prolog, et il me répond :
    ?- probleme(M).
    M = []([](1, 3, 2, 4, 9), [](1, 2, 3, 4, 5), [](8, 1, 2, 3, 4))
    Yes (0.00s cpu, solution 1, maybe more)
    M = []([](1, 3, 2, 4, 9), [](1, 2, 3, 4, 5), [](8, 1, 2, 3, 5))
    Yes (0.01s cpu, solution 2, maybe more)
    (et j'arrête là, mais il y a évidemment beaucoup d'autres solutions)