A set of benchmarks to compare a new prototype MiniZinc implementation
1% N-SITE problem 2% Road Network Maintenance Problem 3% 4% Determine which worksheets to execute on which day so that the road network is not perterbed too much 5% Each worksheet is a contiguous set of daily tasks on roads: specified by a road and number of workers 6% Worksheets have an importance defining how important they are to execute 7% 8% Constraints to satisfy are: 9% Earliest and latest start times of worksheets 10% Not too many workers from each work center on any day 11% For each of a number of given sets of roads never blocking more than a given amount 12% Some worksheets must be executed 13% Precedence rules between pairs of worksheets 14% PARAMETERS 15int: days; % number of dayso 16set of int: DAY = 0..days-1; 17int: roads; % number of roads 18int: centers; % number of centers 19int: worksheets; % number of worksheets 20int: activities; % number of activities 21 22set of int: ROAD = 0..roads-1; 23set of int: ROAD0 = -1..roads-1; 24array[ROAD0,DAY] of int: perterb; % perturbation cost of road on each day 25 26set of int: CENTER = 0..centers-1; % index set for centers 27array [CENTER] of int: c_id; % id of each center 28array [CENTER] of int: available_workers; % number of available workers per center 29 30set of int: WORKSHEET = 0..worksheets-1; % index set for workseets 31array [WORKSHEET] of int: w_id; % id of each worksheet 32array [WORKSHEET] of int: work_center; % id of the work center where used by each worksheet 33array [WORKSHEET] of 0..1: mandatory; % whether each worksheet is mandatory 34array [WORKSHEET] of int: importance; % importance of each worksheet 35array [WORKSHEET] of int: est; % earliest starting time for each worksheet 36array [WORKSHEET] of int: lst; % latest starting time for each worksheet 37array [WORKSHEET] of int: duration; % duration in days of each worksheet 38set of int: ACTIVITY = 0..activities-1; 39array [WORKSHEET,ACTIVITY] of ROAD0: road; % road used by each worksheet on a given day -1 = none 40array [WORKSHEET,ACTIVITY] of int: workers; % number of workers used by each worksheet on a given day 41 42int: blocked_max; % number of maximum blocked rules for this instance 43set of int: BLOCKED = 1..blocked_max; % index set for maximum blocked rules 44array [BLOCKED] of ROAD: blocked_max_amount; % max amount of roads that can be blocked of a given set 45array [BLOCKED] of set of ROAD: blocked_roads; % the set of roads that the max amount refers to 46 47int: precedences; % number of precedence rules for this instance 48set of int: PREC = 1..precedences; % index set for the precedence rules 49array [PREC] of WORKSHEET: preceeds; % the predecessor worksheet in a given rule 50array [PREC] of WORKSHEET: succeeds; % the successor worksheet in a given rule 51 52 53% DECISION VARIABLES 54array [WORKSHEET] of var 0..1: g; % 1 if the worksheet is executed 55 56array [WORKSHEET] of var DAY: d; % start time of worksheet 57array [WORKSHEET] of var DAY: e = array1d(WORKSHEET,[ d[w] + duration[w] | w in WORKSHEET ]); % end time of worksheet 58% Fixing unused variables 59constraint forall(w in WORKSHEET)(g[w] = 0 <-> d[w] = est[w]); 60 61% Fits in schedule 62constraint forall(w in WORKSHEET)(e[w] <= days); 63 64 65% CONSTRAINTS 66% Precedences within Worksheet 67 68% Worksheet Earliest Starting Time 69constraint forall (w in WORKSHEET) (est[w] <= d[w]); 70 71% Worksheet Latest Starting Time 72constraint forall (w in WORKSHEET) (d[w] <= lst[w]); 73 74% Complete WORKSHEET 75 76% Mandatory WORKSHEET 77constraint forall (w in WORKSHEET) (g[w] >= mandatory[w]); 78 79% Precedence Between Worksheets 80% if both worksheets execute then the end of w1 is before the start of w2 81constraint forall (i in PREC) 82 (let { WORKSHEET: w1 = preceeds[i]; 83 WORKSHEET: w2 = succeeds[i]; } in 84 g[w1] * e[w1] <= d[w2] + days * (1 - g[w2])); 85 86 87% Maximal Number of Roads Simultaneously Blocked 88include "global_cardinality_low_up.mzn"; 89constraint forall(b in BLOCKED)( 90 global_cardinality_low_up( 91 [ (d[w] + a + 1)*g[w] %% add one to separate 0 = not executed 92 | w in WORKSHEET, a in 0..duration[w]-1 where road[w,a] in blocked_roads[b]], 93 [ d + 1 | d in DAY], %% looking for day + 1 94 [ 0 | d in DAY], 95 [blocked_max_amount[b] |d in DAY] 96 ) 97); 98 99 100% Work Center Capacity 101include "cumulative.mzn"; 102constraint forall(c in CENTER) 103 ( if length([w | w in WORKSHEET where work_center[w] = c]) > 0 then 104 cumulative([ d[w] + a 105 | w in WORKSHEET where work_center[w] = c, a in 0..duration[w] - 1 ], 106 [ g[w] 107 | w in WORKSHEET where work_center[w] = c, a in 0..duration[w] - 1 ], 108 [ workers[w,a] | w in WORKSHEET where work_center[w] = c, 109 a in 0..duration[w]-1 ], 110 available_workers[c]) 111 else true endif); 112 113% OBJECTIVE 114var 0..worksheets * max(importance): importance_obj = sum (w in WORKSHEET) (g[w]*importance[w]); 115int: perterb_obj_ub = max(array1d(perterb)) * days; 116var 0..perterb_obj_ub: perterb_obj = max(i in DAY)( 117 sum(w in WORKSHEET, a in 0..duration[w]-1)( 118 g[w] * perterb[road[w,a], i] * (i = d[w]+a) 119 ) 120); 121var -ub(perterb_obj)..ub(importance_obj): objective; 122constraint objective = importance_obj - perterb_obj; 123 124array[int] of int: import_first = reverse(arg_sort(importance)); 125 126solve 127 :: int_search( 128 [ if j = 1 then g[import_first[i]] else -d[import_first[i]] endif | i in 1..worksheets, j in 1..2], 129 input_order, indomain_max, complete) 130 maximize objective; 131 132 133output [ 134 "g = array1d(\(WORKSHEET), \(g));\n", 135 "d = array1d(\(WORKSHEET), \(d));\n", 136 "objective = \(objective);\n" 137];