include "global_cardinality.mzn"; int: n; % Number of customers int: m; % Maximum number of vehicles int: capacity; % Capacity of each vehicle array[LOCATION,LOCATION] of int: distance; % Distance between locations array[LOCATION] of int: demand; % Demand of each location array[LOCATION] of int: service; % Duration of service array[LOCATION] of int: ready_time; % Start of time window of each location array[LOCATION] of int: due_time; % End of time window of each location int: DEPOT = n+1; set of int: CUSTOMER = 1..n; set of int: LOCATION = 1..n+1; set of int: VEHICLE = 1..m; set of int: TIME = ready_time[DEPOT]..due_time[DEPOT]; array[CUSTOMER] of var LOCATION: predecessor; % Where are we coming from array[CUSTOMER] of var bool: last; % Is this customer the last one on the route (before the depot) array[LOCATION] of var 0..capacity: load; % How many goods remain after visiting the location array[LOCATION] of var TIME: leaving_time; % What time does the vehicle leave the location var VEHICLE: nVehicles = sum(last); % Cardinality constraint constraint global_cardinality(predecessor, [l | l in LOCATION], [bool2int(not last[c]) | c in CUSTOMER]++[nVehicles]); % Capacity constraints constraint load[DEPOT] = capacity; constraint forall(c in CUSTOMER)(load[c] = load[predecessor[c]] - demand[c]); % Time Window constraints constraint leaving_time[DEPOT] = ready_time[DEPOT]; constraint forall(c in CUSTOMER)(leaving_time[c] = service[c] + max(ready_time[c], leaving_time[predecessor[c]]+distance[predecessor[c],c])); constraint forall(c in CUSTOMER)(leaving_time[c] - service[c] <= due_time[c]); constraint forall(c in CUSTOMER)(leaving_time[c] + distance[c,DEPOT] <= due_time[DEPOT]); var int: total_distance = sum(c in CUSTOMER)(distance[predecessor[c],c] + last[c]*distance[c,DEPOT]); solve::int_search(predecessor, most_constrained, indomain_split, complete) minimize total_distance; output["predecessor = \(predecessor)\n"] ++["last = \(last)\n"] ++["Number of used vehicles = \(nVehicles)\n"] ++["total_distance = \(total_distance)\n"];