<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Combination of VRP and Scheduling problem based on Home Healthcare Problem in Mathematical Optimization, Discrete-Event Simulation, and OR</title>
    <link>https://communities.sas.com/t5/Mathematical-Optimization/Combination-of-VRP-and-Scheduling-problem-based-on-Home/m-p/944544#M4232</link>
    <description>&lt;P&gt;Can you pls explain if the situation is as follows;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;there are two types of staff models&lt;OL&gt;&lt;LI&gt;One paid for the hours worked and how they reach the site do not matter&amp;nbsp;&lt;/LI&gt;&lt;LI&gt;One is paid for the hours worked (more efficient than model 1) and the travelling time from the previous working location where a VRP should be applied.&lt;/LI&gt;&lt;/OL&gt;&lt;/LI&gt;&lt;LI&gt;the final solution should be a mix of both models&lt;/LI&gt;&lt;LI&gt;there is no data on the total number of staff available&lt;/LI&gt;&lt;LI&gt;Our objective is to maximise the profit&amp;nbsp;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;How would the code change??&lt;/P&gt;</description>
    <pubDate>Thu, 19 Sep 2024 03:20:35 GMT</pubDate>
    <dc:creator>Kalistha</dc:creator>
    <dc:date>2024-09-19T03:20:35Z</dc:date>
    <item>
      <title>Combination of VRP and Scheduling problem based on Home Healthcare Problem</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Combination-of-VRP-and-Scheduling-problem-based-on-Home/m-p/943978#M4217</link>
      <description>&lt;P&gt;Hi community,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I am modelling an OR problem based on&amp;nbsp;&lt;SPAN&gt;home healthcare scheduling problem, which is combining VRP with schedule problem.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;For context, I am just trying with small hypothetical data.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Staff Availability&lt;/STRONG&gt;:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Each staff member can work up to 40 hours per week.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;STRONG&gt;Customer Requirements&lt;/STRONG&gt;:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;Customer 1&lt;/STRONG&gt;: Needs 3 visits/days per week, each visit/day takes 2 hours.&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Customer 2&lt;/STRONG&gt;: Needs 2 visits/days per week, each visit takes 1.5 hours.&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Customer 3&lt;/STRONG&gt;: Needs 1 visit/day per week, each visit takes 2 hours.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;STRONG&gt;Distance between customers&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Distance Matrix&lt;/STRONG&gt;:&lt;/P&gt;&lt;P&gt;From/To 1 2 3 4 5&lt;/P&gt;&lt;TABLE&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;TD&gt;10&lt;/TD&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;15&lt;/TD&gt;&lt;TD&gt;25&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;2&lt;/TD&gt;&lt;TD&gt;10&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;TD&gt;15&lt;/TD&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;30&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;15&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;TD&gt;30&lt;/TD&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;4&lt;/TD&gt;&lt;TD&gt;15&lt;/TD&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;30&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;TD&gt;25&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;5&lt;/TD&gt;&lt;TD&gt;25&lt;/TD&gt;&lt;TD&gt;30&lt;/TD&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;25&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I want to make this an open VRP where the staff can start at any customer and end at any customer. So I will add a dummy customer with distance to and from other customers = 0 and all other data visits_per_week visit_duration is 0.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The aim is to minimise total travel distance while all customers are visited. I am aiming to get output something like sets of route for each staff and total distance travelled.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;The code is generating lots of syntax errors around sets and read data. &lt;/STRONG&gt;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;data distance;
   input from to distance;
   datalines;

0 1 0
0 2 0
0 3 0
0 4 0
0 5 0
1 2 10
1 3 20
1 4 15
1 5 25
2 3 15
2 4 20
2 5 30
3 4 30
3 5 20
4 5 25
;
run;

data customer;
   input customer_id visits_per_week visit_duration;
   datalines;
0 0 0 
1 3 2
2 2 1.5
3 1 2
;
run;

data staff;
   input staff_id available_hours;
   datalines;
1 40
2 40
3 40
;
run;

proc optmodel;
   /* Define sets */
   set &amp;lt;num&amp;gt; C; /* Customers */
   set &amp;lt;num&amp;gt; S; /* Staff members */
   set &amp;lt;num&amp;gt; D; /* Days of the week */
   set &amp;lt;num&amp;gt; LOCATIONS; /* Including customers and the dummy customer (depot) */

   /* Define parameters */
   num distance {LOCATIONS, LOCATIONS}; /* 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 {S}; /* Available working hours per week for each staff */
   
   /* Define variables */
   var x {S, LOCATIONS, LOCATIONS} binary; /* 1 if staff s travels from location i to location j */
   var y {S, C, D} binary; /* 1 if staff s visits customer c on day d */
   var total_travel_time {S} &amp;gt;= 0; /* Total travel time for each staff member */
   var u {LOCATIONS} &amp;gt;= 0; /* Auxiliary variables for subtour elimination */

   /* Read data */
   read data distance into [from, to] distance;
   read data customer into [customer_id] visits_per_week visit_duration;
   read data staff into [staff_id] available_hours;

   /* Add dummy customer */
   /* Assuming the dummy customer is indexed as 0 */
   LOCATIONS = C + {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 */
   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 */

   /* Objective: Minimize total travel time */
   minimize TravelTime: sum {s in S, i in LOCATIONS, j in LOCATIONS} distance[i, j] * x[s, i, j];

   /* Constraints */
   /* Staff working hours constraint */
   con staff_hours {s in S}:
      sum {d in D, c in C} visit_duration[c] * y[s, c, d] &amp;lt;= available_hours[s];

   /* Customer visit requirements */
   con customer_visits {c in C}:
      sum {s in S, d in D} 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];

   con Arrival_con {i in LOCATIONS}:
      FlowIn[i] = 1;

   con Departure_con {j in LOCATIONS}:
      FlowOut[j] = 1;

   /* Subtour elimination constraints */
   con Subtour_elimination_con {i in LOCATIONS, j in LOCATIONS: i ne j}:
      u[i] - u[j] + n * x[s, i, j] &amp;lt;= n - 1;

   con u_restrict1_con {i in LOCATIONS: i ne 0}: /* Assume '0' is the dummy customer */
      u[i] &amp;gt;= 1;

   con u_restrict2_con {i in LOCATIONS: i ne 0}:
      u[i] &amp;lt;= n - 1;

   /* Ensure total travel time for each staff member */
   con travel_distance {s in S}:
      total_travel_distance[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;
quit;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I am following the logic of this example code I have.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;data food_data;
	INFILE DATALINES DLM=' ';
	length Name $ 14 Type $ 14 Colour $ 14  ;
	input Name  Type Colour  Price     ;
	datalines;
Apple  Fruit Red 0.65
Orange Fruit Orange 0.70 
Mandarin Fruit  Orange 0.75
Cheese  Dairy Yellow 0.65 
Milk Dairy White 7
Yogurt Dairy White 0.75 
;
run;

data time_data;
	INFILE DATALINES DLM=' ';
	length  TimeName $14 ;
	input Time TimeName    Budget;
		datalines;
	1 Breakfast 5
	2 MorningTea 5
	3 Lunch 4
	4 AfternoonTea 4
	5 Dinner 3
	;
	run;

proc optmodel;
	 

    /* Populating sets from a dataset */
	set &amp;lt;num&amp;gt; TIME ; 
	set &amp;lt;str&amp;gt; FOOD ;
	set &amp;lt;str&amp;gt; DAIRY ;
	set &amp;lt;str&amp;gt; FRUIT ;
	set &amp;lt;str&amp;gt; COLOUR;
	str foodType {FOOD};
	num foodPrice {FOOD};
	str foodColour {FOOD};
	num budget {TIME};
	str TimeName {TIME};
	
	read data food_data into 
			FOOD=[Name] 
			foodType=Type 
			foodPrice=price
			foodColour = Colour;

	/* Create sets from variables */
	COLOUR = (setof{i in FOOD} foodColour [i]);
	DAIRY =(setof{i in FOOD: foodType[i]='Dairy'} i);
	FRUIT =(setof{i in FOOD: foodType[i]='Fruit'} i);
	
	read data time_data into 
			TIME = [time]
			TimeName
			budget;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Any expert could you kindly help? Thank you very much in advance.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 15 Sep 2024 11:23:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Combination-of-VRP-and-Scheduling-problem-based-on-Home/m-p/943978#M4217</guid>
      <dc:creator>norachanisara</dc:creator>
      <dc:date>2024-09-15T11:23:36Z</dc:date>
    </item>
    <item>
      <title>Re: Combination of VRP and Scheduling problem based on Home Healthcare Problem</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Combination-of-VRP-and-Scheduling-problem-based-on-Home/m-p/944115#M4219</link>
      <description>&lt;P&gt;Note for example that you cannot have&lt;/P&gt;
&lt;PRE&gt;c in C&lt;/PRE&gt;
&lt;P&gt;because c and C are treated the same.&amp;nbsp; So I renamed C, S, and D.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You must also populate sets before you can use them.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The subtour elimination constraints should exclude the depot as j.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The following code avoids the syntax errors:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc optmodel;
   /* Define sets */
*   set &amp;lt;num&amp;gt; C; /* Customers */
*   set &amp;lt;num&amp;gt; S; /* Staff members */
*   set &amp;lt;num&amp;gt; D; /* Days of the week */
   set &amp;lt;num&amp;gt; CUSTOMERS; /* Customers */
   set &amp;lt;num&amp;gt; STAFF; /* Staff members */
   set &amp;lt;num&amp;gt; DAYS; /* Days of the week */
   set &amp;lt;num&amp;gt; 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} &amp;gt;= 0; /* Total travel time for each staff member */
   var u {LOCATIONS} &amp;gt;= 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] &amp;lt;= 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] &amp;lt;= n - 1;

   con u_restrict1_con {i in LOCATIONS: i ne 0}: /* Assume '0' is the dummy customer */
      u[i] &amp;gt;= 1;

   con u_restrict2_con {i in LOCATIONS: i ne 0}:
      u[i] &amp;lt;= 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;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The resulting optimal solution has objective value 0.&amp;nbsp; You still need other constraints, such as flow balance for each s and i.&amp;nbsp; But hopefully the above code helps you proceed further.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 16 Sep 2024 16:53:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Combination-of-VRP-and-Scheduling-problem-based-on-Home/m-p/944115#M4219</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2024-09-16T16:53:53Z</dc:date>
    </item>
    <item>
      <title>Re: Combination of VRP and Scheduling problem based on Home Healthcare Problem</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Combination-of-VRP-and-Scheduling-problem-based-on-Home/m-p/944544#M4232</link>
      <description>&lt;P&gt;Can you pls explain if the situation is as follows;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;there are two types of staff models&lt;OL&gt;&lt;LI&gt;One paid for the hours worked and how they reach the site do not matter&amp;nbsp;&lt;/LI&gt;&lt;LI&gt;One is paid for the hours worked (more efficient than model 1) and the travelling time from the previous working location where a VRP should be applied.&lt;/LI&gt;&lt;/OL&gt;&lt;/LI&gt;&lt;LI&gt;the final solution should be a mix of both models&lt;/LI&gt;&lt;LI&gt;there is no data on the total number of staff available&lt;/LI&gt;&lt;LI&gt;Our objective is to maximise the profit&amp;nbsp;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;How would the code change??&lt;/P&gt;</description>
      <pubDate>Thu, 19 Sep 2024 03:20:35 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Combination-of-VRP-and-Scheduling-problem-based-on-Home/m-p/944544#M4232</guid>
      <dc:creator>Kalistha</dc:creator>
      <dc:date>2024-09-19T03:20:35Z</dc:date>
    </item>
  </channel>
</rss>

