Professional Documents
Culture Documents
FINAL REPORT
COURSE: INVENTORTY MANAGEMENT
Vendor managed inventory for environments with stochastic
product usage
Instructor: Nguyen Van Hop
Teacher assistant: Pham Tuan Anh
CONTRIBUTION
Trương Ngọc Lê Khanh IELSIU17037 100
Nguyễn Trịnh Thảo Huyền IEIEIU17023 100
Trần Thị Hoàn Châu IELSIU18251 100
Hồ Anh Phú Đôn IELSIU17005 100
7. CONCLUSION ............................................................................................................ 32
8. REFERENCE.............................................................................................................. 32
1. ABSTRACT
Based on an integer programming model built in Vera Hemmelmayr’s research of the
delivery routes planning for the blood products supply to hospital by a blood bank, we try
to run it in Cplex with given information and self-figured data. This is a sampling-based
approaches which helps with organizing cost-effectively the delivery of blood products to
hospitals. An extensive computational study shows the efficacy of the two approaches
and highlights the impact of product usage uncertainty on the resulting delivery plans.
2. INTRODUCTION
2.1 Problem Summary
In the paper, the researchers consider the specific problem of vendor managed
inventory resupply policy for the delivery of blood products to hospitals in Eastern
Austria by the Austrian Red Cross (ARC). The main idea is that the ARC needs to
develop two-week plans for practical purposes, as it allows advanced notification of
volunteers and guarantees the availability of appropriate delivery vehicles. In
Hemmelmayr et al., an initial assessment of the ARC's benefits of shifting to vendor-
managed inventory supply is addressed (in press). This initial evaluation was
conducted assuming the hospitals' documented and deterministic usage of blood
products. For an initial evaluation, this is appropriate, but it is of course, not absolutely
true. Blood product needs can be estimated reasonably accurate for planned surgeries,
but it is far harder to predict blood product needed for emergency cases. Therefore, in
this paper, in the presence of stochastic product utilization, it focuses on analyzing
vendor-managed inventory resupply policies.
Another problem is, if product usage is stochastic, a cost-effective plan that is
guaranteed to be feasible for every possible realization of product usage in a 2-week
period can no longer be created. Therefore, during the 2-week period, it is appropriate
to implement various recourse policies for managing product shortfalls as stated in the
paper. However, in this project, we will not be discussing about the recourse policy.
2.2 Solution Summary
Two solution approaches are implemented in Hemmelmayr et al. (in press), an
integer programming approach and a Variable Neighborhood Search (VNS) approach.
The researchers expand both methods so that stochastic product usage can be handled,
using external sampling in both cases to turn the two-stage stochastic optimization
question into a problem of deterministic optimization.
There are various trade-offs that have to be considered when deciding on the most
appropriate recourse action. The recourse actions are presented in increasing order of
operational complexity. It is rather simple to adjust the quantities before the vehicles
leave the distribution center for their daily delivery routes. It is much more complicated
to introduce emergency deliveries into the planned daily delivery routes. The expected
delivery costs for the 2-week period vary depending on the sophistication of the recourse
action.
In the remainder of the paper, we examine if and how the solution approaches introduced
in Hemmelmayr et al. (in press) can be adapted to handle these recourse actions and
perform a computational study to see the impact on the 2-week delivery plans.
5. SOLUTION APPROACHES
5.1 Integer programming (IP) model
• What is Integer Programming?
An integer programming problem is a mathematical optimization or feasibility
program in which some or all of the variables are restricted to be integers. In many
settings the term refers to integer linear programming (ILP), in which the objective
function and the constraints (other than the integer constraints) are linear.
• What is the use of IP in this problem?
The blood bank wants to minimize delivery costs. Any delivery policy must ensure
that the customer does not have a product shortage, but at the same time damaged
product must be keep to a minimum but per clients (hospitals, clinics, medical
institutions) need the daily supply of blood preservatives with different quantity. So
IP is applied to make fixed route allow a significant number of routes to be
considered and thus can provide the right flexibility to significantly reduce costs
delivery and supplied enough products for customers.
• How to apply IP in this specific problem? (general view of the direction)
Provided the fixed routes for the areas, we use an integer programming model to
predict the real routes during the 14-day planning period. The integer programming
model optimally determines which hospitals to visit on any given day based on the
demand trends and capacity constraints at the individual hospitals, so that none of the
hospitals experience a stock-out, wastage is held to a minimum, and distribution costs
are reduced.
The entire routing of problems referred to as sequencing, scheduling, and routing are
inherently integer programs. For the routing component, the integer programming
model relies on short cutting a pre-determined fixed route in both, deterministic and
stochastic, cases. Experimentation has shown that this provides adequate flexibility
for constructing daily delivery routes.
• Specific notes:
There will be two sets of variables in the integer program: variables that represent
decisions related to the 2-week delivery plan that are similar to the R realizations, and
variables that represent recourse actions that are particular to each of the R
realizations. With the number of realizations in the sample, the size of the integer
program thus increases quickly. Consequently, a computationally viable alternative is
not likely to be offered by the integer programming method. Hence, in this project,
we will be using small sample sizes (R=10) to primarily run the model.
Under the assumption that the hospitals are indexed from 1 to n according to the order
in which they are visited on the fixed route, the formulation is:
The objective minimizes total travel distance during the planning period.
Constraints (1) ensure inventory balance from period to period.
Constraints (2) ensure that the inventory at the end of the planning period is greater or
equal to the inventory at the beginning of the planning period. Without such a constraint
no deliveries would be made towards the end of the planning period. Furthermore, we
consider our problem as a periodic problem which is repeated every T time units.
Constraints (3) ensure that inventory never exceeds the storage capacity.
Constraints (4) ensure that inventory does not spoil.
Constraints (5) state that the initial inventory is given.
Constraints (6) ensure that there are no product shortages.
Constraints (7) and (8) ensure that delivery quantities are nonnegative and that deliveries
can only be made when a hospital is visited.
Constraints (9) capture short cutting of the fixed route.
Constraints (10) limit route duration.
Constraints (11) state that the distribution center is visited every day.
execute PRE_SETUP{
cplex.epgap=0.1;
cplex.tilim=60*60
}
//Objective function
minimize sum(t in Time, i in Center, j in Center)w[i][j]*X[i][j][t];
//Constraints
subject to{
Constraint1:
forall(i in Hosp, t in Time){
I[i][t + 1] == I[i][t] - U[i][t] + d[i][t];
}
Constraint2:
forall(i in Hosp){
I[i][numbDay + 1] >= I[i][1];
}
Constraint3:
forall(i in Hosp, t in Time){
I[i][t]<=C[i];
}
Constraint4:
forall(i in Hosp, t in Time){
I[i][t] <= sum(s in t .. t + k2-1)U[i][s];
}
Constraint5:
forall(i in Hosp){
I[i][1]==q[i];
}
Constraint6:
forall(i in Hosp, t in Timeplus){
I[i][t]>=0;
}
Constraint7:
forall(i in Hosp, t in Time){
d[i][t]<=C[i]*y[i][t];
}
Constraint8:
forall(i in Hosp, t in Time){
d[i][t]>=0;
}
Constraint9:
forall(i in Center, j in Center, t in Time: i != numbHosp + 1 && j != 0 && i < j + 1){
X[i][j][t] >= y[i][t] + y[j][t] - 1 - sum(k in i + 1 .. j - 1)y[k][t];
}
Constraint10:
forall(t in Time){
sum(i in Center, j in Center)w[i][j]*X[i][j][t] + sum(i in Hosp)y[i][t]*s[i] <= D;
}
Constraint11:
forall( t in Time){
y[0][t] == 1;
y[numbHosp+1][t] == 1; //(11)
}
}
execute WRITE_RESULT{
var ofile=new IloOplOutputFile("Result_IPmodel.txt");
ofile.writeln("The objective function value: ",cplex.getObjValue());
for (var t in Time)for(var i in Center){
if(y[i][t]==1){
ofile.writeln("The inventory for all hospital at the beginning of day ");
ofile.writeln(" [",I,"] ")
}
}
ofile.writeln("------------------------------------------------------------------------");
ofile.close();
}
5.2 Recourse action
5.2.1 First recourse action – delivery quantity adjustment
The first recourse action changes the delivery quantities of
planned deliveries. This implies that there is a delivery quantity
for each realization r and therefore the variable representing the t
delivery quantity is changed to 𝒅𝒕𝒊𝒓 . Constraints (9)–(12) remain unchanged, but
constraints (1)–(8) are replaced by:
Constraint (13)-(20) adds r into formula to plan delivery quantity for a hospital is
increased or decreased based on product usage up on that day.
Note that constraints (16), which limit spoilage at hospitals, use the pre-computed
spoilage capacity Si.
1. File .mod
/*********************************************
* OPL 12.6.2.0 Model
* Author: Thao Huyen
* Creation Date: 05-12-2020 at 15:25:59
********************************************/
//index
int numbHosp=...;
int numbDay=...;
int numbRe=...;
int numbCenter=...;
range Hosp = 1 ..numbHosp; //5
range Center = 0 .. numbHosp + 1; //6
range Time = 1..numbDay; // 15
range Timeplus = 1..numbDay+1; //16
range Realiz = 1..numbRe; //5
range TempRange = 1..(numbRe*numbCenter); //34
float TempMatrix[TempRange][Timeplus] = ...;
float A[i in Realiz][j in Center][l in Timeplus] = TempMatrix[(i-
1)*(numbCenter)+j+1][l];
//Decision variable
dvar float+ dd[Hosp][Realiz][Timeplus];
dvar boolean y[Center][Time];
dvar float IR[Hosp][Realiz][Timeplus];
dvar boolean X[Center][Center][Time];
//Parameter
float w[Center][Center]=...;
float s[Center]=...;
float C[Hosp]=...;
float D=...;
float q[Hosp]=...;
float S[Hosp]=...;
//Objective function
dexpr float TC = sum(t in Time, i in Center, j in Center)w[i][j]*X[i][j][t];
minimize TC;
//Constraints
subject to{
forall(i in Realiz, j in Center, l in Timeplus){
A[i][j][l] == TempMatrix[(i-1)*(numbCenter)+j+1][l] ;
}
Constraint1:
forall(t in Time, i in Hosp, r in Realiz){
IR[i][r][t + 1] == IR[i][r][t] - A[i][r][t] + dd[i][r][t];
//(13)
}
Constraint2:
forall(i in Hosp, r in Realiz){
IR[i][r][numbDay + 1] >= IR[i][r][1];
//(14)
}
Constraint3:
forall(i in Hosp, t in Time, r in Realiz){
IR[i][r][t] <= C[i]; //(15)
}
Constraint4:
forall(i in Hosp, t in Time, r in Realiz){
IR[i][r][t] <= S[i]; //(16)
}
Constraint5:
forall(i in Hosp,r in Realiz){
IR[i][r][1] == q[i]; //(17)
}
Constraint6:
forall(i in Hosp, t in Timeplus, r in Realiz){
IR[i][r][t] >= 0; //(18)
}
Constraint7:
forall(i in Hosp, t in Time, r in Realiz){
dd[i][r][t] <= C[i]*y[r][t]; //(19)
}
Constraint8:
forall(i in Hosp, t in Time, r in Realiz){
dd[i][r][t] >= 0; //(20)
}
Constraint9:
forall(i in Center, j in Center, t in Time: i != numbHosp + 1 &&
j != 0 && i < j + 1){
X[i][j][t] >= y[i][t] + y[j][t] - 1 - sum(k in i + 1 .. j -
1)y[k][t]; //9
}
Constraint10:
forall(t in Time){
sum(i in Center, j in Center)w[i][j]*X[i][j][t] + sum(i in
Hosp)y[i][t]*s[i] <= D; //10
}
Constraint11:
forall( t in Time){
y[0][t] == 1;
y[numbHosp+1][t] == 1; //(11)
}
}
execute WRITE_RESULT{
var ofile=new IloOplOutputFile("Result_IPmodel_RA1.txt");
ofile.writeln("The objective function value: ",cplex.getObjValue());
for (var t in Time)for(var i in Center)for(var j in Center){
if(y[i][t]==1,X[i][j][t]==1){
ofile.writeln("The quantity of blood in inventory at hospital i at the
beginning of the day t ");
ofile.writeln("[",dd,"]");
}
}
ofile.writeln("--------------------------------------------------------------
----------");
ofile.close();
}
2. File .dat
/*********************************************
* OPL 12.6.2.0 Data
* Author: Thao Huyen
* Creation Date: 05-12-2020 at 15:25:59
*********************************************/
SheetConnection MyData("IPmodel_data_RA.xlsx");
numbHosp from SheetRead(MyData,"numbHosp");
numbDay from SheetRead(MyData,"numbDay");
numbRe from SheetRead(MyData,"numbRe");
numbCenter from SheetRead(MyData,"numbCenter");
w from SheetRead(MyData,"Traveltime");
s from SheetRead(MyData,"Servicetime");
TempMatrix from SheetRead(MyData,"UsageR50");
C from SheetRead(MyData,"Capacity50");
D from SheetRead(MyData,"Maxroute");
S from SheetRead(MyData,"Maxspoilage");
q from SheetRead(MyData,"InitialInven50");
5.2.2 Second recourse action – out-and-back emergency deliveries
The second recourse action introduces out-and-back emergency deliveries to
hospitals that are about to experience a shortage. Therefore, for each realization
new variables need to be introduced to capture emergency deliveries. More
specifically, the delivery quantity 𝒅˜𝒕𝒊𝒓 , associated with an emergency delivery to
hospital i on day t in realization r, and the indicator 𝒚˜𝒕𝒊𝒓 , tracking whether or not
hospital i receives an emergency delivery in realization s on day t.
The objective function minimizes the planned delivery costs plus the expected
cost of emergency deliveries, which is approximated as the average cost of out-
and-back emergency deliveries, where we average over the realizations. Note that
the cost 𝑡ĩ of an out-and-back emergency delivery to hospital i is simply 𝑡0𝑖 + 𝑡𝑖0 .
Therefore, we have:
Constraint (21) meaning inventory balance from period to period due to the
changed of realization r to cover the emergency deliveries.
Constraints (22) and (23) ensure that delivery quantities r are nonnegative and
that deliveries can only be made when a hospital is visited with emergency case.
Constraint (24) is 0-1 variable indicates if or not hospital i receives an emergency
delivery on day t and in realization r
Constraint1:
forall(i in Hosp, t in Time, r in Realiz){
IR[i][r][t + 1] == IR[i][r][t] - A[i][r][t] +
dd[i][r][t] + ddd[i][r][t]; //(21)-(1)
}
Constraint2:
forall(i in Hosp, r in Realiz){
IR[i][r][numbDay + 1] >= IR[i][r][1];
//(14)
}
Constraint3:
forall(i in Hosp, t in Timeplus, r in Realiz){
IR[i][r][t] <= C[i]; //(15)
}
Constraint4:
forall(i in Hosp, t in Timeplus, r in Realiz){
IR[i][r][t] <= S[i]; //(16)
}
Constraint5:
forall(i in Hosp,r in Realiz){
IR[i][r][1] == q[i]; //(17)
}
Constraint6:
forall(i in Hosp, t in Timeplus, r in Realiz){
IR[i][r][t] >= 0; //(18)
}
Constraint7:
forall(i in Hosp, t in Time, r in Realiz){
dd[i][r][t] <= C[i]*y[r][t]; //(19)
}
Constraint8:
forall(i in Hosp, t in Time, r in Realiz){
dd[i][r][t] >= 0; //(20)
}
Constraint9:
forall(i in Center, j in Center, t in Time: i != numbHosp +
1 && j != 0 && i < j + 1){
X[i][j][t] >= y[i][t] + y[j][t] - 1 - sum(k in i + 1
.. j - 1)y[k][t]; //9
}
Constraint10:
forall(t in Time){
sum(i in Center, j in Center)w[i][j]*X[i][j][t] +
sum(i in Hosp)y[i][t]*s[i] <= D; //10
}
Constraint11:
forall( t in Time){
y[0][t] == 1;
y[numbHosp+1][t] == 1; //(11)
}
Constraint12:
forall(i in Hosp, t in Time, r in Realiz){
ddd[i][r][t] <= C[i] * Y[i][r][t]; //(22)
}
Constraint13:
forall(i in Hosp, t in Time, r in Realiz){
ddd[i][r][t] >= 0; //(23)
}
}
execute WRITE_RESULT{
var ofile=new IloOplOutputFile("Result_IPmodel_RA2.txt");
ofile.writeln("The objective function value: ",cplex.getObjValue());
for (var t in Time)for(var i in Center)for(var j in Center)for(var r in
Realiz){
if(y[i][t] == 1,X[i][j][t] == 1,Y[i][r][t] == 1){
ofile.writeln("The quantity of blood delivered to hospital i on day t
in realization r ");
ofile.writeln("[",dd,"]");
ofile.writeln("The quantity of blood in inventory at hospital i at the
beginning of the day t ");
ofile.writeln("[",IR,"]");
ofile.writeln("The quantity of blood delivered by an emergency delivery
to hospital i on day t in realization r ");
ofile.writeln("[",ddd,"]")
}
}
ofile.writeln("--------------------------------------------------------------
----------");
ofile.close();
}
2. File .dat
/*********************************************
* OPL 12.6.2.0 Data
* Author: Thao Huyen
* Creation Date: 05-12-2020 at 17:11:08
*********************************************/
SheetConnection MyData("IPmodel_data_RA2.xlsx");
numbHosp from SheetRead(MyData,"numbHosp");
numbDay from SheetRead(MyData,"numbDay");
numbRe from SheetRead(MyData,"numbRe");
numbCenter from SheetRead(MyData,"numbCenter");
w from SheetRead(MyData,"Traveltime");
tt from SheetRead(MyData,"tt");
s from SheetRead(MyData,"Servicetime");
TempMatrix from SheetRead(MyData,"UsageR");
C from SheetRead(MyData,"Capacity");
D from SheetRead(MyData,"Maxroute");
S from SheetRead(MyData,"Maxspoilage");
q from SheetRead(MyData,"InitialInven");
5.2.3 Third recourse action
The target function minimizes the cost of delivery and the estimated cost of
emergency delivery roughly as well as the average cost of the delivery routes where
we average the deliveries, i.e.
Constraints (26) state that the distribution center is visited every day and state that
the depot is included in every emergency route.
Constraints (27) limit route duration (tour length for emergency routes)
Constraint (28): 0–1 variable indicating whether or not the delivery vehicle travels
from hospital i to hospital j on day t in realization r (where 0 and n þ 1 denote the
Red Cross distribution center)
1. File .mod
/*********************************************
* OPL 12.6.2.0 Model
* Author: Thao Huyen
* Creation Date: 05-12-2020 at 21:44:23
*********************************************/
//index
int numbHosp=...;
int numbDay=...;
int numbRe=...;
int numbCenter=...;
range Hosp = 1 ..numbHosp; //5
range Center = 0 .. numbHosp + 1; //6
range Time = 1..numbDay; // 15
range Timeplus = 1..numbDay+1; //16
range Realiz = 1..numbRe; //5
range TempRange = 1..(numbRe*numbCenter); //34
float TempMatrix[TempRange][Timeplus] = ...;
float A[i in Realiz][j in Center][l in Timeplus] = TempMatrix[(i-
1)*(numbCenter)+j+1][l];
//Decision variable
dvar float+ dd[Hosp][Realiz][Time];
dvar float+ ddd[Hosp][Realiz][Time];
dvar boolean y[Center][Time];
dvar boolean Y[Center][Realiz][Time];
dvar float+ IR[Hosp][Realiz][Timeplus];
dvar boolean X[Center][Center][Time];
dvar boolean x[Center][Center][Realiz][Time];
//Parameter
float w[Center][Center]=...;
float s[Center]=...;
float C[Hosp]=...;
float D=...;
float q[Hosp]=...;
float S[Hosp]=...;
//Objective function
minimize sum(t in Time, i in Center, j in
Center)w[i][j]*X[i][j][t]+(1/numbRe)*sum(r in Realiz, t in Time, i in Center,
j in Center)w[i][j]*x[i][j][r][t];
//Constraints
subject to{
forall(i in Realiz, j in Center, l in Timeplus){
A[i][j][l] == TempMatrix[(i-1)*(numbCenter)+j+1][l]
;
}
Constraint1:
forall(i in Hosp, t in Time, r in Realiz){
IR[i][r][t + 1] == IR[i][r][t] - A[i][r][t] +
dd[i][r][t] + ddd[i][r][t]; //(21)-(1)
}
Constraint2:
forall(i in Hosp, r in Realiz){
IR[i][r][numbDay + 1] >= IR[i][r][1];
//(14)
}
Constraint3:
forall(i in Hosp, t in Timeplus, r in Realiz){
IR[i][r][t] <= C[i]; //(15)
}
Constraint4:
forall(i in Hosp, t in Timeplus, r in Realiz){
IR[i][r][t] <= S[i]; //(16)
}
Constraint5:
forall(i in Hosp,r in Realiz){
IR[i][r][1] == q[i]; //(17)
}
Constraint6:
forall(i in Hosp, t in Timeplus, r in Realiz){
IR[i][r][t] >= 0; //(18)
}
Constraint7:
forall(i in Hosp, t in Time, r in Realiz){
dd[i][r][t] <= C[i]*y[r][t]; //(19)
}
Constraint8:
forall(i in Hosp, t in Time, r in Realiz){
dd[i][r][t] >= 0; //(20)
}
Constraint9:
forall(i in Center, j in Center, t in Time: i != numbHosp +
1 && j != 0 && i < j + 1){
X[i][j][t] >= y[i][t] + y[j][t] - 1 - sum(k in i + 1
.. j - 1)y[k][t]; //9
}
Constraint10:
forall(t in Time){
sum(i in Center, j in Center)w[i][j]*X[i][j][t] +
sum(i in Center)y[i][t]*s[i] <= D; //10
}
Constraint11:
forall( t in Time){
y[0][t] == 1;
y[numbHosp+1][t] == 1; //(11)
}
Constraint12:
forall(i in Hosp, t in Time, r in Realiz){
ddd[i][r][t] <= C[i] * Y[i][r][t]; //(22)
}
Constraint13:
forall(i in Hosp, t in Time, r in Realiz){
ddd[i][r][t] >= 0; //(23)
}
//RA-additional constraints
Constraint14:
forall(i in Center, j in Center, t in Time, r in Realiz){
x[i][j][r][t] >= Y[i][r][t] + Y[i][r][t] - 1 -
sum(k in i+1..j-1)Y[k][r][t]; //(25)
}
Constraint15:
forall(t in Time, r in Realiz){
Y[0][r][t] == Y[numbHosp+1][r][t] == 1;
//(26)
}
Constraint16:
forall(t in Time, r in Realiz){
sum(i in Center, j in Center)w[i][j]*x[i][j][r][t]
+ sum(i in Hosp)Y[i][r][t]*s[i] <= D; //(27)
}
}
execute WRITE_RESULT{
var ofile=new IloOplOutputFile("Result_IPmodel_RA3.txt");
ofile.writeln("The objective function value: ",cplex.getObjValue());
for (var t in Time)for(var i in Center)for(var j in Center)for(var r in
Realiz){
if(y[i][t] == 1,X[i][j][t] == 1,Y[i][r][t] == 1,x[i][j][r][t]==1){
ofile.writeln("The quantity of blood delivered to hospital i on day t
in realization r ");
ofile.writeln("[",dd,"]");
ofile.writeln("The quantity of blood in inventory at hospital i at the
beginning of the day t ");
ofile.writeln("[",IR,"]");
ofile.writeln("The quantity of blood delivered by an emergency delivery
to hospital i on day t in realization r ");
ofile.writeln("[",ddd,"]")
}
}
2. File .dat
/*********************************************
* OPL 12.6.2.0 Data
* Author: Thao Huyen
* Creation Date: 05-12-2020 at 21:44:23
*********************************************/
SheetConnection MyData("IPmodel_data_RA3.xlsx");
numbHosp from SheetRead(MyData,"numbHosp");
numbDay from SheetRead(MyData,"numbDay");
numbRe from SheetRead(MyData,"numbRe");
numbCenter from SheetRead(MyData,"numbCenter");
w from SheetRead(MyData,"Traveltime");
s from SheetRead(MyData,"Servicetime");
TempMatrix from SheetRead(MyData,"UsageR");
C from SheetRead(MyData,"Capacity");
D from SheetRead(MyData,"Maxroute");
S from SheetRead(MyData,"Maxspoilage");
q from SheetRead(MyData,"InitialInven");
5.2.4 Fourth recourse action
Emergency deliveries are integrated into the regularly scheduled supply routes by
the fourth recourse intervention. The optimization problem minimizes the average
estimated routing cost for all realizations, i.e.,
Constraint 29 ensures regular visits and emergency visits at the same time.
Constrain 30 ensuresthe hospital does not receive a periodic delivery and an
emergency delivery on a particular day in a specific realization.
Constrain 31 ensures our computational experiments we have imposed a lmit on
the tour length.
In the end, constraints (9)-(12),(14)-(24) and(28) are also necessary. Note that
emergency deliveries are no more expensive than regular deliveries due to our
modeling options, i.e. the short cut of a fixed route, which reduces the challenge
of the simple strategy.
1. File .mod
/*********************************************
* OPL 12.6.2.0 Model
* Author: Thao Huyen
* Creation Date: 06-12-2020 at 10:04:04
*********************************************/
//index
int numbHosp=...;
int numbDay=...;
int numbRe=...;
int numbCenter=...;
range Hosp = 1 ..numbHosp; //5
range Center = 0 .. numbHosp + 1; //6
range Time = 1..numbDay; // 15
range Timeplus = 1..numbDay+1; //16
range Realiz = 1..numbRe; //5
range TempRange = 1..(numbRe*numbCenter); //34
float TempMatrix[TempRange][Timeplus] = ...;
float A[i in Realiz][j in Center][l in Timeplus] = TempMatrix[(i-
1)*(numbCenter)+j+1][l];
//Decision variables
dvar float+ dd[Hosp][Realiz][Time];
dvar float+ ddd[Hosp][Realiz][Time];
dvar boolean y[Center][Time];
dvar boolean Y[Center][Realiz][Time];
dvar float+ IR[Hosp][Realiz][Timeplus];
dvar boolean X[Center][Center][Time];
dvar boolean x[Center][Center][Realiz][Time];
//Parameter
float w[Center][Center]=...;
float s[Center]=...;
float C[Hosp]=...;
float D=...;
float q[Hosp]=...;
float S[Hosp]=...;
//Objective function
minimize (1/numbRe)*sum(r in Realiz, t in Time, i in Center, j in
Center)w[i][j]*x[i][j][r][t];
//Constraints
subject to{
forall(i in Realiz, j in Center, l in Timeplus){
A[i][j][l] == TempMatrix[(i-1)*(numbCenter)+j+1][l]
;
}
Constraint1:
forall(i in Hosp, t in Time, r in Realiz){
IR[i][r][t + 1] == IR[i][r][t] - A[i][r][t] +
dd[i][r][t] + ddd[i][r][t]; //(21)-(1)
}
Constraint2:
forall(i in Hosp, r in Realiz){
IR[i][r][numbDay + 1] >= IR[i][r][1];
//(14)
}
Constraint3:
forall(i in Hosp, t in Timeplus, r in Realiz){
IR[i][r][t] <= C[i]; //(15)
}
Constraint4:
forall(i in Hosp, t in Timeplus, r in Realiz){
IR[i][r][t] <= S[i]; //(16)
}
Constraint5:
forall(i in Hosp,r in Realiz){
IR[i][r][1] == q[i]; //(17)
}
Constraint6:
forall(i in Hosp, t in Timeplus, r in Realiz){
IR[i][r][t] >= 0; //(18)
}
Constraint7:
forall(i in Hosp, t in Time, r in Realiz){
dd[i][r][t] <= C[i]*y[r][t]; //(19)
}
Constraint8:
forall(i in Hosp, t in Time, r in Realiz){
dd[i][r][t] >= 0; //(20)
}
Constraint9:
forall(i in Center, j in Center, t in Time: i != numbHosp +
1 && j != 0 && i < j + 1){
X[i][j][t] >= y[i][t] + y[j][t] - 1 - sum(k in i + 1
.. j - 1)y[k][t]; //9
}
Constraint10:
forall(t in Time){
sum(i in Center, j in Center)w[i][j]*X[i][j][t] +
sum(i in Center)y[i][t]*s[i] <= D; //10
}
Constraint11:
forall( t in Time){
y[0][t] == 1;
y[numbHosp+1][t] == 1; //(11)
}
Constraint12:
forall(i in Hosp, t in Time, r in Realiz){
ddd[i][r][t] <= C[i] * Y[i][r][t]; //(22)
}
Constraint13:
forall(i in Hosp, t in Time, r in Realiz){
ddd[i][r][t] >= 0; //(23)
}
//RA-additional constraints
Constraint14:
forall(i in Center, j in Center, t in Time, r in Realiz){
x[i][j][r][t] >= (Y[i][r][t]+y[i][t]) +
(Y[j][r][t]+y[j][t]) - 1 - sum(k in i+1..j-1)(Y[k][r][t] + y[k][t]);
//(29)
}
Constraint15:
forall(i in Center, t in Time, r in Realiz){
Y[i][r][t] + y[i][t] <= 1; //(30)
}
Constraint16:
forall(t in Time, r in Realiz){
sum(i in Center, j in Center)w[i][j]*x[i][j][r][t]
+ sum(i in Hosp)(y[i][t] + Y[i][r][t])*s[i] <= D;
//(31)
}
}
execute WRITE_RESULT{
var ofile=new IloOplOutputFile("Result_IPmodel_RA4.txt");
ofile.writeln("The objective function value: ",cplex.getObjValue());
for (var t in Time)for(var i in Center)for(var j in Center)for(var r in
Realiz){
if(y[i][t] == 1,X[i][j][t] == 1,Y[i][r][t] == 1,x[i][j][r][t]==1){
ofile.writeln("The quantity of blood delivered to hospital i on day t
in realization r ");
ofile.writeln("[",dd,"]");
ofile.writeln("The quantity of blood in inventory at hospital i at the
beginning of the day t ");
ofile.writeln("[",IR,"]");
ofile.writeln("The quantity of blood delivered by an emergency delivery
to hospital i on day t in realization r ");
ofile.writeln("[",ddd,"]")
}
}
ofile.writeln("--------------------------------------------------------------
----------");
ofile.close();
}
2. File .dat
/*********************************************
* OPL 12.6.2.0 Data
* Author: Thao Huyen
* Creation Date: 06-12-2020 at 10:04:04
*********************************************/
SheetConnection MyData("IPmodel_data_RA4.xlsx");
numbHosp from SheetRead(MyData,"numbHosp");
numbDay from SheetRead(MyData,"numbDay");
numbRe from SheetRead(MyData,"numbRe");
numbCenter from SheetRead(MyData,"numbCenter");
w from SheetRead(MyData,"Traveltime");
s from SheetRead(MyData,"Servicetime");
TempMatrix from SheetRead(MyData,"UsageR");
C from SheetRead(MyData,"Capacity");
D from SheetRead(MyData,"Maxroute");
S from SheetRead(MyData,"Maxspoilage");
q from SheetRead(MyData,"InitialInven");
6. IMPLENTATION AND TEST (IP)
6.1 Computational Study
The IP algorithm was implemented in Cplex Studio version 12.1.0. The integer programs
were solved on a 3.2 GHz Pentium 4 processor running the Windows 10 operating
system and using Cplex Optimizer Studio 12.1.0.
Furthermore, we consider three different levels of storage capacity at the hospitals:
specifically, 50%, 75% and 100% of the actual storage capacity. Finally, a spoilage
period of 2 days which we chose to run the model sufficiently
To evaluate a 2-week plan, we perform a simple simulation. A product usage realization
for the 2-week period is generated for each hospital using the appropriate distribution.
The 2-week plan is then used to supply product to the hospitals performing recourse
actions as needed. This process is repeated around 20 times. The following statistics are
collected for the 2-week period on Internet: average emergency delivery costs (and thus
average total costs), average number of hospital visits per day, and average number of
emergency hospital. When evaluating a 2-week plan using recourse action 1, stock-outs
may occur so in that setting we also keep track of the number of stock-outs.
The sample size has a dramatic effect on the size of the integer programs that need to be
solved. It has been clear from the start that only relatively small sample sizes can be used
with the integer programming approach; in the order 15. On the other hand, for the last
two recourse actions, the expected emergency delivery costs incurred for a hospital for a
particular visit-day combination depend on the visit-day combinations of the other
hospitals and have to be computed from scratch after every change in a visit-day
combination (regardless of the hospital for which the change occurs). This balances the
need to do a large number of iterations and the need to have a reasonable sample size
when final decisions are being made. In our implementation we start with a sample size
of 15 during the course of the algorithm.
The average run time for the IP using a sample size of 15 is 2 minutes, for recourse action
1 is 3.43s, for recourse action 2 it is 3.17s, for recourse action 3 it is 5.22s, and for
recourse action 4 is 25.36s.
Number of Hospital 5
Number of day 15
Maximum route duration (hour) 50
Length of spoilage period 2
Product
i/t
Usage 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 224 659 876 681 506 202 602 922 329 495 346 862 162 613 385 536
2 270 985 957 395 132 522 322 749 554 777 908 873 637 639 687 536
3 103 252 485 613 229 995 633 696 386 411 255 223 384 772 945 361
4 798 110 471 132 156 592 878 127 318 611 322 265 987 593 888 864
5 866 521 396 518 551 441 770 167 814 445 236 920 662 450 973 296
6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Table 1. Product usage of hospital i on day t
However, the hospitals are not served every day and the hospitals are not always
served together, i.e., the delivery route may differ from day to day.
Initial Inventory
1 5000
2 7500
3 10000
4 7000
5 8500
Table 3. Storage capacity at each rate and Initial inventory of each hospital
Figure 1. Inventory
We assume that the safety stock policy at every hospital is to ensure that at least ti
days of inventory is available at the beginning of the day, that blood product spoil in
2 days, and that the inventory at every hospital at the end of the planning period has
to be at least as large as the initial inventory at the beginning of the planning period.
From the experiment, we can see that the initial and final inventory at the hospitals
are equal of half or less than the storage capacity.
Initial Final 100% 75% 50%
Inventory Inventory Capacity Capacity Capacity
1 5000 1 441 330.75
2 7500 2 0 495.75 330.5
3 10000 3 498 373.5 249
4 7000 4 557 417.75 278.5
5 8500 5 441 330.75 220.5
Table 4. Final inventory of each capacity of each hospital
Figure 2. Quantity
Due to the difference in daily usage, the number of deliveries required to serve a
hospital during the planning period differs. When we allow the use of entire storage
capacity at a hospital and we assume a spoilage period of 2 days, the number of
deliveries during the planning period range from 1 to 6.
With the short spoilage period, the integer programming gives us the quantity of the
delivery schedules as above:
- The first 15 columns present for number of days during planning period
- The last column presents for the solution of the objective function
- 5 rows present for the quantity of blood the hospitals receive each day
( It is equal to 0 when there is no delivery on that day)
Furthermore, we have also considered three different levels of storage capacity at the
hospitals; specially 50%, 75% and 100% of the actual storage capacity as key
problem parameter to assess the sensitivity.
The results have shown that the case for 75% storage capacity can be used for blood
products when it gives the best solution time (the smallest one) of the integer
program.
6.2.2 Recourse Actions
Table 5. Comparing 4 recourse actions to each other for each capacity based on
objective function value
In general:
- We did both with the size of R is 5 (r=1…5)
- We did both times 2 weeks ( especially 15 days)
- The more capacity the hospitals have, the more objective function value they
have
- RA 1 got the least Objective function value and RA 2 got the most Objective
function value
- The differences get larger when the capacity is tighter (Because emergency
delivery costs are likely to play a bigger role in the total cost )
- The difference of RA2 among these 3 RAs is significant.(Because it has the
planned delivery costs plus s the out-and-back emergency delivery cost which
is very expensive)
In details:
RA1 RA2 RA3 RA4
Main idea changes the Capturing Applying Applying
delivery emergency emergency emergency
quantities of deliveries in delivery route, deliveries into
planned order to which is a single the regularly
deliveries experience a emergency planned
following the shortage delivery route delivery routes.
changing of R visiting all
hospitals that are
about to run out
of product on a
particular day.
Total cost Total cost of Changed Changed slightly Changed
of capacity capacity 100 is slightly slightly
levels twice as much
as that of 50
influence No. Because it the most less expensive less expensive
of the doesn’t use expensive (emergency (emergency
recourse emergency (emergency deliveries to deliveries to
actions deliveries to hospitals are hospitals are
hospitals are coordinated) coordinated)
handled
independently)
IP RAs
R (Realization) Not use +We did with
the size of R is 5
(r=1…5
All in all, the IP works fine at low capacity levels, but tends to significantly
underestimate the cost of emergency delivery for higher capacity levels. It is also clear
that a higher percentage of the overall costs for low levels of capacity are attributed to
emergency delivery costs. The lower the storage space in hospitals, the more
expensive it would be to ensure the supply of goods using only regular deliveries.
Many deliveries would happen to protect against unforeseen high consumption of the
commodity. On the other hand, it is possible to be risky to have emergency deliveries
despite its high cost. In most cases, the cost-effective base policy will be used, but if
product usage happens to be considerably greater than usual, a more costly alternative
for emergency distribution is required to accommodate it. We also observe the effect
of the actions of the solution on themselves. Recourse response 2 is the most costly,
because hospital emergency deliveries are treated separately, while recourse actions 3
and 4 are less costly, because hospital emergency deliveries are organized. As a result,
with recourse actions 3 and 4, more " risks " are taken, and a greater part of the gross
delivery costs are attributed to the cost of emergency delivery. It also appears like the
strategies created by the IP are more traditional, in the sense that the cost of
emergency supply is responsible for a lower portion of the overall delivery costs.
We determine more detailed statistics regards to the actual deliveries. Table show the
average number of regular (i.e., planned) hospital visits per day and the average
number of emergency hospital visits per day for IP for each hospital capacity for each
recourse action.
It can be seen that the when the recourse action is more involved and cost-effective,
more emergency deliveries are performed whereas fewer regular emergencies are
being carried out. This is statistically clearer the lower the capacity level of the
hospital is. It is understandable given the fact that the less capacity, the more
challenging it is to guarantee product availability, hence the increase in emergency
deliveries. Additionally, if the cost of emergency deliveries are considered cost-
efficient, they would like to use even more.
7. CONCLUSION
To sum up, this was formulation to plan delivery routes for the supply of blood products
to hospitals by a blood bank. This formula is sampling-based and allows specifically for
the inconsistency of the use of blood products in hospitals. A number of emergency
delivery solutions are introduced to control delivery costs while guaranteeing product
supply at the hospital. We have run a computational study in order to analyze how
efficient the model is as well as the influence of stochastic product usage upon delivery
planning.
The idea of it has been carried out, proving an efficient and beneficial way of adding
recourse actions to stochastic demand of blood to hospitals. It definitely helps responding
to demand in a cost-effective way and being able to compare between methods of adding
emergency deliveries. Moreover, since this is all automation, it will help a lot with the
planning of stochastic goods in time, accuracy, and cost.
8. REFERENCE
Vera Hemmelmayr , Karl F. Doerner , Richard F. Hartl , Martin W.P. Savelsbergh (13
March 2018), Delivery strategies for blood products supplies. Retrieved from
https://www.researchgate.net/profile/Martin_Savelsbergh/publication/227068423_Delive
ry_strategies_for_blood_products_supplies/links/02e7e52a575f08a41d000000/Delivery-
strategies-for-blood-products-supplies.pdf