1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
| :- use_module(library('clpfd.pl')).
magasin :-
% 4 produits achetés dans 3 magasins
LP = [[11, 9, 1],
[10, 17, 19],
[ 2, 10, 14],
[30, 15, 20]
],
% Couts des déplacements vers les magasins
LD = [7, 5, 9],
% Couts des déplacements inter magasins
LC = [[0, 5, 7],
[5, 0, 6],
[7, 6, 0]],
magasin(LP, LD, LC, H, Prix),
writeln(H), writeln(Prix).
% LP est une liste P listes de 3 Prix (un par magasin)
magasin(LP, LD, LC, H, Prix) :-
% construction de la liste H des achats
% elle est de la forme
% [ [AM1,AM2,AM3], [BM1,BLM2, BM3]...]
% où les XMi valent 1 si le produit a été acheté dans ce magasin
% ou 0 sinon
length(LP, LenP),
length(H, LenP),
% initialisation du calcul des prix
% PrixM contient le montant des achats dans chaque magasin.
maplist(init, LP, H, PrixM),
% on calcule le prix
sum(PrixM, #=, Prix1),
A #= 0,
% on regarde maintenant les magasins visités
% S contient le nombre d'articles achetés dans chaque magasin
add_list(H, [], A, [], S),
% S1 = [1,1,2],
maplist(recapitule, S, CS),
% on calcule mainteant le prix du trajet
etudie_trajet(CS, LD, LC, CT),
Prix #= Prix1 + CT,
% le labeling se fait avec une liste plate
flatten(H, FH),
labeling([min(Prix)], FH).
% Calcule du nombre d'articles achetés dans un magasin
add_list([], [], N, L, S) :-
reverse([N | L], S).
add_list([], T, N, L, S) :-
A #= 0,
add_list(T, [], A, [N | L], S).
add_list([[H]|T2], T3, N, L, S) :-
V #= N + H,
add_list(T2, T3, V, L, S).
add_list([[H, T0|T1]|T2], T3, N, L, S) :-
V #= N + H,
add_list(T2, [[T0|T1] | T3], V, L, S).
% Pose une condition pour savoir si un produit
% a été acheté dans ce magasin
recapitule(C, CS) :-
C #> 0 #<==> CS.
% Calcul du trajet en fonction des magasins visités
% Rappel A, B, C valent 0 ou 1
% C'est cette partie qui est difficilement généralisable à N magasins
etudie_trajet([A,B,C], [C1,C2,C3], CL, PT) :-
PT #> 0,
CL = [[0, CL1, CL2],[CL1, 0, CL3], _],
A+10*B+100*C #= TT,
( TT #= 1) #<==> A1,
TT #= 10 #<==> A2,
TT #= 100 #<==> A3,
TT #= 11 #<==> A4,
TT #= 101 #<==> A5,
TT #= 110 #<==> A6,
TT #= 111 #<==> A7,
PT #= 2 * (A1 * C1 + A2 * C2 + A3 * C3) +
A4 * (C1+C2+CL1) + A5 * (C1+C3+CL2) + A6 *(C2+C3+CL3) +
A7 * (C1+C2+CL2+CL3).
% fonction d'initialisation de la liste des achats
init(P, H, Prix) :-
length(P, LP),
length(H, LP),
% on achète ou pas
H ins 0..1,
% on n'effectue qu'un seul achat pour ce produit
sum(H, #=, 1),
% On calcule la somme
maplist(calcule, P, H, LPrix),
% on calcule la dépense
sum(LPrix, #=, Prix).
% ici on calcule le prix
% Si le PU = 0, celà veut dire que le
% produit n'est pas dans le magasin
calcule(PU, Q, P) :-
PU #= 0, Q #= 0, P #= 0.
calcule(PU, Q, P) :-
PU #\= 0, P #= PU * Q. |
Partager