1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.

223 lines
5.3 KiB
MiniZinc

% We don't run this as part of the test suite since it takes a while.
% (Changing the search strategy would probably make it faster, but since
% that might mask the bug we are testing for we don't want to do that.)
% Regression test for bug #92: this model caused an abort during evaluation
% on Windows (due to a stack overflow).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This MiniZinc model was created by Hakan Kjellerstrand, hakank@bonetmail.com
% now shamelessly and probably poorly modified by Therese Keane
% Inclusion of tidal windows
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Parameters (integers)
% number of jobs
int: n;
% number of machines
int: m;
% number of spots
int: s;
% number of tasks in each job
int: o;
% max end task time, bit of a fudge doing it this way
int: pmax;
% number of tidal windows
int: twnum;
% minutes per day
int: minsperday = 1440;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Parameters (sets)
% set of jobs
set of int: J = 1..n;
% set of machines
set of int: M = 1..m;
% set of tasks
set of int: O = 1..o;
% set of spots
set of int: S = 1..s;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Parameters (arrays)
% processing time of o on a
array[M, O] of int: p;
% tidal wimdow array
array[1..twnum, 1..2] of int: tw;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Variables (arrays)
% starting time of task o in job j
array[J,O] of var int: x;
% Y[j,a] is 1 if job j is scheduled to be performed with machine a, and 0 if not
array[J,M] of var 0..1: Y;
% W[j,s] is 1 if job j uses spot s and 0 otherwise
array[J,S] of var 0..1: W;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Variables (integers)
% some large constant
var int: K = (sum(a in M, o in O) (p[a,o]))*n;
% so-called makespan
var int: z;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Objective
% the objective is to make z as small as possible
solve :: int_search(
[x[i,j] | i in J, j in O] ++
[Y[i,a] | i in J, a in M] ++
[W[i,b] | i in J, b in S] ++ [K, z],
first_fail,
indomain_min,
complete
) minimize z;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Predicates
% No overlapping
predicate no_overlap(var int:s1, var int:d1, int:s2, int:d2, int:minsday) =
((s1 + d1) mod minsday <= s2 \/ s1 mod minsday >= s2 + d2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Constraints
constraint
% added K as upper limit of z and x
z >= 0
/\
z <= K
/\
forall(i in J, a in O) (
x[i,a] >= 0
/\
x[i,a] <= K
)
/\
% ensure correct ordering of tasks within a job
forall (i in J, j in 2..o, a in M) (
x[i,j] >= (x[i, j-1] + p[a, j-1]) * Y[i,a]
)
/\
% ensure start of next job is after end of previous job
forall(i in 2..n, j in J, a in M where i > j) (
x[i,1] >= (x[j,o] + p[a,o])*Y[j,a]*Y[i,a]
)
/\
% ensure start of job 4 (landing/offload) does not occur during a tidal window
forall(i in J, c in 1..twnum, a in M) (
no_overlap(x[i,4], p[a,4]*Y[i,a], tw[c,1], tw[c,2], minsperday)
)
/\
% only one machine can perform a job
forall(j in 1..n)(sum(a in 1..m) (Y[j,a]) = 1)
/\
% only one spot is used per job
forall(j in 1..n)(sum(b in 1..s) (W[j,b]) = 1)
/\
% ensure jobs don't overlap on each spot
forall(i in 2..n, j in J, a in M, b in S where i > j) (
x[i,1] >= ((x[j,1] + p[a,1])*Y[j,a])*W[j,b]*W[i,b]
)
/\
% which is the maximum of the completion times of all the jobs
forall(j in J, a in M) ( z >= (x[j,o] + p[a,o])*Y[j,a])
;
output [
"Total-Duration: ", show(z), "\n",
"Number-of-Jobs: ", show(n), "\n",
"Number-of-Tasks-per-Job: ", show(o), "\n",
"Number-of-Watercraft/Helos: ", show(m), "\n",
"Number-of-Spots: ", show(s), "\n",
"Number-of-TWs: ", show(twnum), "\n",
"Job/Task-Start-Times: "
] ++
[
if a = 1 then "\n" else " " endif ++
show(x[i,a])
| i in J, a in O
] ++ [ "\nJob-Watercraft/Helo-use: "] ++
[
if a = 1 then "\n" else " " endif ++
show(Y[i,a])
| i in J, a in M
] ++ [ "\nJob-Spot/Dock-use: "] ++
[
if a = 1 then "\n" else " " endif ++
show(W[i,a])
| i in J, a in S
] ++ [ "\nTidal-Windows: "] ++
[
if b = 1 then "\n" else " " endif ++
show(tw[i,b])
| i in 1..twnum, b in 1..2
] ++ [ "\nGiven-Task-Duration-for-Watercraft/Helo: "] ++
[
if i = 1 then "\n" else " " endif ++
show(p[a,i])
| a in M, i in O
] ++ ["\n"]
;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Input data
% n sorties comprising o tasks, m helos/watercraft
n = 18; % number of jobs
m = 2; % number of machines/helos
o = 6; % number of tasks in each job
s = 1; % number of spots, used for task 1 at the moment
% processing time of task o with machine a
% task times represent land/load, takeoff, transit, land/offload, takeoff, transit
p = array2d(M, O, [
24, 5, 60, 24, 5, 50,
20, 8, 60, 20, 8, 50]);
pmax = 50;
% 8, 4, 65, 8, 4, 65,
% Number of tidal windows
twnum = 2;
% start and duration of tidal windows
tw = array2d(1..2, 1..2, [
100, 100,
400, 100]);