-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhoraris_extra.mzn
101 lines (74 loc) · 3.94 KB
/
horaris_extra.mzn
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
include "globals.mzn";
int: nPeces; % Nombre de peces a tocar
int: nInstruments; % Nombre d'instruments a tocar
int: nMusics; % Nombre de musics
array[1..nPeces] of int: durada; % Durada de les peces.
array[1..nPeces] of int: d = [durada[i] div 5 | i in 1..nPeces];
array[1..nPeces,1..nInstruments] of int: requereix; % Instruments requerits per cada peça
array[1..nMusics,1..nInstruments] of bool: saptocar; % True si el music sap tocar l'instrument en qüestió
int: pressupost;
array[1..nMusics] of int: salari;
int: nPrecs;
array[1..nPrecs] of 1..nPeces: pred;
array[1..nPrecs] of 1..nPeces: succ;
int: dummyUB = sum(i in 1..nPeces)(d[i]) + count(i in 1..nPeces)(requereix[i,2]>0);
array[1..nPeces,1..nMusics] of var 0..nInstruments: musicsAssignats;
array [1..nPeces] of var 0..dummyUB: s; % Temps d'inici de cada peça
var 0..pressupost: preu = sum([d[i]*salari[j]| j in 1..nMusics, i in 1..nPeces where musicsAssignats[i,j]!=0]); % Pressupost
array[1..nInstruments] of int: poolInstruments = [sum(j in 1..nMusics)(saptocar[j,i])| i in 1..nInstruments]; % Number of each instrument we have.
% Constraint que assegura que es respecta la prioritat
constraint forall(i in 1..nPrecs) (
s[succ[i]] >= s[pred[i]]+d[pred[i]]
);
% La primera cançó ha de començar al principi del festival
constraint min([s[i] | i in 1..nPeces]) = 0;
% Que cada peça tingui els instruments que necessita durant l'execució
constraint forall(i in 1..nPeces, j in 1..nInstruments)(
count([musicsAssignats[i,k]|k in 1..nMusics], j) == requereix[i,j]
);
% Que un music toqui un instrument que li toca.
constraint forall(i in 1..nPeces, j in 1..nMusics)(
if musicsAssignats[i,j]!=0 then saptocar[j,musicsAssignats[i,j]] endif
);
constraint forall(i in 1..nPeces, m in 1..nMusics, j in (i+1)..nPeces)(
% Si dues peces són concurrents, llavors un mateix músic no pot tocar a les dues
if musicsAssignats[i,m] != 0 /\ musicsAssignats[j,m] != 0 then
disjunctive([s[i],s[j]],[d[i],d[j]])
endif
);
% Assegura que per cada instrument en cap moment s'assignin més peces que el toquen que els musics que el saben tocar.
constraint forall(i in 1..nInstruments) (
cumulative(s,d,[requereix[p,i]|p in 1..nPeces],poolInstruments[i])
);
/* PART OPCIONAL */
constraint forall(p in 1..nPeces) (
% Fem els càlculs sempre amb temps % 5
if d[p]>10 /\ requereix[p,2]>0 then
false
endif
);
constraint forall(p in 1..nPeces where requereix[p,2]>0) (% Per cada peça que requereixi instrument 2
% Existeix una peça que requereixen l'instrument 2 que acaba entre la primera i la primera+50
if exists(k in 1..nPeces where s[k]+d[k]>=s[p]+10 /\ s[k]<=s[p]+10)(requereix[k,2]>0) then% s[p]+50 existeix una peça on requereix[k,2]
exists(i in 1..nPeces where requereix[i,2]>0 /\ s[i]+d[i]>s[p] /\ s[i]+d[i]<=s[p]+10)(
% On totes les peces que es toquen en aquell moment no necessiten l'instrument 2
forall(j in 1..nPeces where s[j] <= s[i]+d[i] /\ s[j]+d[j] > s[i]+d[i])( % Que comenci abans d'aquell moment o en aquell i acabi després d'aquell moment
requereix[j,2]=0
)
)
endif
);
%solve minimize max([s[i]+d[i]| i in 1..nPeces])*pressupost + preu;
solve minimize max([s[i]+d[i]| i in 1..nPeces]);
var int: max_value = max([s[i]*5+d[i]*5 | i in 1..nPeces]);
output[
"Hora d’inici del festival: 10h 0min \nHora d'acabada del festival: " ++ show(10 + max_value div 60)++ "h " ++
show(max_value mod 60) ++
"min \nCost de contractació: " ++ show(fix(preu)) ++ "\n"
] ++ [
"Peça " ++ show(p) ++ ":\n" ++
" Inici: " ++ show(fix(10+s[p]*5 div 60)) ++ "h " ++ show(fix(s[p]*5 mod 60)) ++ " min\n" ++
" Final: " ++ show(fix(10+((s[p]*5+d[p]*5) div 60))) ++ "h " ++ show(fix((s[p]*5+d[p]*5) mod 60)) ++ " min\n" ++
concat([" Music " ++ show(m) ++ " toca instrument " ++ show(fix(musicsAssignats[p,m])) ++ "\n" | m in 1..nMusics where fix(musicsAssignats[p,m])!=0]) |
p in 1..nPeces
];