Note for example that you cannot have
c in C
because c and C are treated the same. So I renamed C, S, and D.
You must also populate sets before you can use them.
The subtour elimination constraints should exclude the depot as j.
The following code avoids the syntax errors:
proc optmodel;
/* Define sets */
* set <num> C; /* Customers */
* set <num> S; /* Staff members */
* set <num> D; /* Days of the week */
set <num> CUSTOMERS; /* Customers */
set <num> STAFF; /* Staff members */
set <num> DAYS; /* Days of the week */
set <num> LOCATIONS; /* Including customers and the dummy customer (depot) */
/* Define parameters */
* num distance {LOCATIONS, LOCATIONS}; /* Distance between locations */
num distance {LOCATIONS, LOCATIONS} init 0; /* Distance between locations */
num visits_per_week {LOCATIONS}; /* Number of visits per week for each customer, including dummy */
num visit_duration {LOCATIONS}; /* Duration of each visit for each customer, including dummy */
num available_hours {STAFF}; /* Available working hours per week for each staff */
/* Define variables */
var x {STAFF, LOCATIONS, LOCATIONS} binary; /* 1 if staff s travels from location i to location j */
var y {STAFF, CUSTOMERS, DAYS} binary; /* 1 if staff s visits customer c on day d */
var total_travel_time {STAFF} >= 0; /* Total travel time for each staff member */
var u {LOCATIONS} >= 0; /* Auxiliary variables for subtour elimination */
/* Read data */
/* read data customer into [customer_id] visits_per_week visit_duration;*/
read data customer into LOCATIONS=[customer_id] visits_per_week visit_duration;
/* read data distance into [from, to] distance;*/
read data distance into [from to] distance;
/* read data staff into [staff_id] available_hours;*/
read data staff into STAFF=[staff_id] available_hours;
/* Add dummy customer */
/* Assuming the dummy customer is indexed as 0 */
* LOCATIONS = C + {0}; /* Add dummy customer to the locations */
CUSTOMERS = LOCATIONS;
LOCATIONS = CUSTOMERS union {0}; /* Add dummy customer to the locations */
* distance[0, i] = 0; /* Distance from dummy to other locations is 0 */
* distance[i, 0] = 0; /* Distance from other locations to dummy is 0 */
for {i in LOCATIONS} do;
distance[0, i] = 0; /* Distance from dummy to other locations is 0 */
distance[i, 0] = 0; /* Distance from other locations to dummy is 0 */
end;
visits_per_week[0] = 0; /* Dummy customer has 0 visits per week */
visit_duration[0] = 0; /* Dummy customer has 0 visit duration */
/* Define sets from parameters */
* C = (setof {i in visits_per_week: i ne 0} i); /* Exclude dummy customer */
* S = (setof {i in available_hours} i);
* D = (setof {1, 2, 3, 4, 5}); /* Assuming a fixed number of days */
DAYS = 1..5; /* Assuming a fixed number of days */
/* Objective: Minimize total travel time */
/* minimize TravelTime: sum {s in S, i in LOCATIONS, j in LOCATIONS} distance[i, j] * x[s, i, j];*/
minimize TravelTime = sum {s in STAFF, i in LOCATIONS, j in LOCATIONS} distance[i, j] * x[s, i, j];
/* Constraints */
/* Staff working hours constraint */
con staff_hours {s in STAFF}:
sum {d in DAYS, c in CUSTOMERS} visit_duration[c] * y[s, c, d] <= available_hours[s];
/* Customer visit requirements */
con customer_visits {c in CUSTOMERS}:
sum {s in STAFF, d in DAYS} y[s, c, d] = visits_per_week[c];
/* Flow constraints */
/* impvar FlowOut {i in LOCATIONS} = sum {j in LOCATIONS: i ne j} x[s, i, j];*/
/* impvar FlowIn {j in LOCATIONS} = sum {i in LOCATIONS: i ne j} x[s, i, j];*/
impvar FlowOut {s in STAFF, i in LOCATIONS} = sum {j in LOCATIONS: i ne j} x[s, i, j];
impvar FlowIn {s in STAFF, j in LOCATIONS} = sum {i in LOCATIONS: i ne j} x[s, i, j];
* con Arrival_con {i in LOCATIONS}:
FlowIn[i] = 1;
con Arrival_con {i in LOCATIONS}:
sum {s in STAFF} FlowIn[s,i] = 1;
* con Departure_con {j in LOCATIONS}:
FlowOut[j] = 1;
con Departure_con {j in LOCATIONS}:
sum {s in STAFF} FlowOut[s,j] = 1;
/* Subtour elimination constraints */
num n = card(LOCATIONS);
/* con Subtour_elimination_con {i in LOCATIONS, j in LOCATIONS: i ne j}:*/
con Subtour_elimination_con {s in STAFF, i in LOCATIONS, j in LOCATIONS: i ne j and j ne 0}:
u[i] - u[j] + n * x[s, i, j] <= n - 1;
con u_restrict1_con {i in LOCATIONS: i ne 0}: /* Assume '0' is the dummy customer */
u[i] >= 1;
con u_restrict2_con {i in LOCATIONS: i ne 0}:
u[i] <= n - 1;
/* Ensure total travel time for each staff member */
con travel_distance {s in STAFF}:
/* total_travel_distance[s] = sum {i in LOCATIONS, j in LOCATIONS} distance[i, j] * x[s, i, j];*/
total_travel_time[s] = sum {i in LOCATIONS, j in LOCATIONS} distance[i, j] * x[s, i, j];
/* Solve the problem */
solve;
/* Display results */
/* print x y total_travel_distance;*/
print x y total_travel_time;
quit;
The resulting optimal solution has objective value 0. You still need other constraints, such as flow balance for each s and i. But hopefully the above code helps you proceed further.
... View more