2018-02-14 16:43:28 +01:00
|
|
|
/* Number of people */
|
|
|
|
param P_count, integer, > 0;
|
|
|
|
|
|
|
|
/* Number of jobs */
|
|
|
|
param J_count, integer, > 0;
|
|
|
|
|
|
|
|
/* Number of days */
|
|
|
|
param D_count, integer, > 0;
|
|
|
|
|
|
|
|
param WL, integer, > 0;
|
|
|
|
param WH, integer, > 0;
|
2019-02-18 12:27:48 +01:00
|
|
|
param ML, integer, > 0;
|
2018-02-14 16:43:28 +01:00
|
|
|
|
|
|
|
set P := 1..P_count;
|
|
|
|
set J := 1..J_count;
|
|
|
|
set D := 1..D_count;
|
|
|
|
|
2019-02-18 11:36:35 +01:00
|
|
|
/* aanwezigheid x workload for that day */
|
|
|
|
param Costs{p in P}, integer, >= 0;
|
|
|
|
|
2018-02-14 16:43:28 +01:00
|
|
|
/* Person p likes to solve jobs j */
|
|
|
|
param L{p in P, j in J} default 0, binary;
|
|
|
|
|
|
|
|
/* Person p hates to solve jobs j */
|
|
|
|
param H{p in P, j in J} default 0, binary;
|
|
|
|
|
|
|
|
/* Person p is capable to perform job j */
|
|
|
|
param C{p in P, j in J} default 1, binary;
|
|
|
|
|
|
|
|
/* How many jobs need to be done on what day */
|
|
|
|
param R{d in D, j in J}, integer, >= 0;
|
|
|
|
|
|
|
|
/* hardcoded */
|
|
|
|
param Q{p in P, j in J, d in D}, default 0, binary;
|
|
|
|
|
|
|
|
/* workload */
|
|
|
|
param Wl{j in J}, integer, >= 0;
|
|
|
|
|
|
|
|
param max_load{p in P, d in D}, default 1, integer;
|
|
|
|
|
|
|
|
/* Person p is allocated to do job j on day d */
|
|
|
|
var A{p in P, j in J, d in D}, binary;
|
|
|
|
|
|
|
|
var error{p in P}, integer, >= 0;
|
|
|
|
|
|
|
|
s.t. hardcode{p in P, j in J, d in D}: A[p,j,d] >= Q[p,j,d];
|
|
|
|
|
|
|
|
/* A person only has one task per day, at most */
|
|
|
|
s.t. max_load_person{p in P, d in D}: sum{j in J} A[p,j,d] <= max_load[p,d];
|
|
|
|
|
2024-01-06 20:19:46 +01:00
|
|
|
/* A person has at least 1 task */
|
|
|
|
s.t. min_load_person{p in P}: sum{j in J, d in D} A[p,j,d] >= 1;
|
2018-02-14 16:43:28 +01:00
|
|
|
|
|
|
|
/* A person does not perform the same job on all days */
|
2022-11-09 18:06:10 +01:00
|
|
|
s.t. duplicate_jobs{p in P, j in J}: sum{d in D} A[p,j,d] <= D_count-1;
|
2018-02-14 16:43:28 +01:00
|
|
|
|
2019-02-18 12:27:48 +01:00
|
|
|
s.t. max_load_person_total{p in P}: (sum{d in D, j in J} A[p,j,d] * Wl[j]) <= ML;
|
|
|
|
|
2018-02-14 16:43:28 +01:00
|
|
|
/* Each task is allocated */
|
|
|
|
s.t. all_allocated{j in J, d in D}: sum{p in P} A[p,j,d] == R[d, j];
|
|
|
|
|
|
|
|
/* A person only performs what (s)he is capable of */
|
|
|
|
s.t. capability_person{p in P, j in J, d in D}: A[p,j,d] <= C[p,j];
|
|
|
|
|
2019-02-18 11:36:35 +01:00
|
|
|
s.t. error_lt{p in P}: error[p] >= ((sum{j in J, d in D} A[p,j,d] * Wl[j]) - Costs[p]);
|
|
|
|
s.t. error_gt{p in P}: error[p] >= Costs[p] - (sum{j in J, d in D} A[p,j,d] * Wl[j]);
|
2018-02-14 16:43:28 +01:00
|
|
|
|
|
|
|
/* Maximize enjoyment */
|
|
|
|
# minimize error_diff: sum{p in P} error[p];
|
|
|
|
maximize enjoyment: (sum{p in P, d in D, j in J} A[p,j,d] * (L[p, j] * WL - H[p, j] * WH)) - sum{p in P} error[p];
|
|
|
|
solve;
|
|
|
|
|
|
|
|
printf "Sum %d\n", (sum{p in P, d in D, j in J} A[p,j,d] * (L[p, j] * WL - H[p, j] * WH));
|
|
|
|
printf "p d j W l\n";
|
|
|
|
printf ">>>>\n";
|
|
|
|
printf{p in P, d in D, j in J : A[p,j,d] > 0} "%d %d %d %d %d\n", p, d, j, A[p,j,d] * (L[p, j] * WL - H[p, j] * WH), Wl[j];
|
|
|
|
printf "<<<<\n";
|
|
|
|
printf "workloads\n";
|
|
|
|
printf "p l\n";
|
2019-02-18 11:36:35 +01:00
|
|
|
printf{p in P} "%d %d\n", p, abs((sum{j in J, d in D : A[p,j,d] > 0} Wl[j]) - Costs[p]);
|
|
|
|
printf "workload_dev: %d\n", sum{p in P} abs((sum{j in J, d in D : A[p,j,d] > 0} Wl[j]) - Costs[p])^2;
|
2018-02-14 16:43:28 +01:00
|
|
|
|
|
|
|
|
2020-02-17 18:30:12 +01:00
|
|
|
end;
|