Reputation: 9
I'm solving a hospital staff scheduling problem in Cplex and I'm new for Cplex.
But Cplex cannot configure answers of decision variables.
I think maybe it's about my model design problem.
It's a long model.
Very appreciate if I can get help.
++Model
--Sets:
{string} E=...; // set of experience levels (Senior , Rookie)
{string} I=...; // set of all physicians
{string} Is=...; //set of physicians with experience level S
{string} Ir=...;//set of physicians with experience level R
{string} K=...; //type of shifts (o & t)
{string} A1=...; //set of shift o work (Day, evening, night)
{string} A2=...; //set of shift t work (Day, evening, night 1, night 2)
--Parameters
int D=...;
range Day=1..D;//range of planning horizon
int Co[Is]=...; //hiring cost for physician i with senior experience level
int Ct[Ir]=...; //hiring cost for physician i with rookie experience level
int Pku=...; //max. days for physician to perform shift o
int Pkd=...; //min. days for physician to perform shift o
int Pkuh=...;//max. days for physician to perform shift t
int Pkdh=...;//min. days for physician to perform shift t
int s=...; //max. consecutive working days
int dosd=...; //shift o day work demand for "senior"physician
int dose=...; //shift o evening work demand for "senior"physician
int dosn=...; //shift o night work demand for "senior"physician
int dord=...; //shift o day work demand for "rookie"physician
int dore=...; //shift o evening work demand for "rookie"physician
int dorn=...; //shift o night work demand for "rookie"physician
int dtsd=...; //shift t day work demand for "senior"physician
int dtse=...; //shift t evening work demand for "senior"physician
int dtsn1=...; //shift t night1 work demand for "senior"physician
int dtsn2=...; //shift t night2 work demand for "senior"physician
int dtrd=...; //shift t day work demand for "rookie"physician
int dtre=...; //shift t evening work demand for "rookie"physician
int dtrn1=...; //shift t night1 work demand for "rookie"physician
int dtrn2=...; //shift t night2 work demand for "rookie"physician
--Binary decicion variable
dvar int x1[I][Day][A1] in 0..1; //1, if senior+ shift o+ one of the work
dvar int x2[I][Day][A2] in 0..1; //1, if senior+ shift t+ one of the work
dvar int y1[I][Day][A1] in 0..1; //1, if rookie+ shift o+ one of the work
dvar int y2[I][Day][A2] in 0..1; //1, if rookie+ shift t+ one of the work
--Expression of Desicion Variables
dexpr float cost =sum(i in Is, d in Day, a in A1)Co[i]*x1[i][d][a]
+ sum(i in Is, d in Day, a in A2)Co[i]*x2[i][d][a]
+ sum(i in Ir, d in Day, a in A1)Ct[i]*y1[i][d][a]
+ sum(i in Ir, d in Day, a in A2)Ct[i]*y2[i][d][a] ;
--Objective function
minimize cost;
--Constraints
subject to
{
forall(d in Day, Day in A1)
{
sum(i in Is) x1[i, d ,"Day"] == dosd; //Daily demand:Senior+shift o+day work
}
forall(d in Day, Evening in A1)
{
sum(i in Is ) x1[i, d, "Evening"] == dose; //Daily demand:Senior+shift o+evening work
}
forall(d in Day, Night in A1)
{
sum(i in Is ) x1[i, d, "Night"] == dosn; //Daily demand:Senior+shift o+night work
}
forall(d in Day, Day in A2)
{
sum(i in Is) x2[i, d, "Day"] == dtsd; //Daily demand:Senior+ shift t +day work
}
forall(d in Day, Evening in A2)
{
sum(i in Is) x2[i, d, "Evening"] == dtse; //Daily demand:Senior+shift t+evening work
}
forall(d in Day, Night1 in A2)
{
sum(i in Is) x2[i, d, "Night1"] == dtsn1; //Daily demand:Senior+shift t+night1 work
}
forall(d in Day, Night2 in A2)
{
sum(i in Is) x2[i, d, "Night2"] == dtsn2; //Daily demand:Senior+shift t+night2 work
}
forall(d in Day, Day in A1)
{
sum(i in Ir) y1[i, d, "Day"] == dord; //Daily demand:Rookie+shift o+day work
}
forall(d in Day, Evening in A1)
{
sum(i in Ir) y1[i, d, "Evening"] == dore; //Daily demand:Rookie+shift o+evening work
}
forall(d in Day, Night in A1)
{
sum(i in Ir) y1[i, d, "Night"] == dorn; //Daily demand:Rookie+shift o+night work
}
forall(d in Day, Day in A2)
{
sum(i in Ir) y2[i, d, "Day"] == dtrd; //Daily demand:Rookie+shift t+day work
}
forall(d in Day, Evening in A2)
{
sum(i in Ir) y2[i, d, "Evening"] == dtre; //Daily demand:Rookie+shift t+evening work
}
forall(d in Day, Night1 in A2)
{
sum(i in Ir) y2[i, d, "Night1"] == dtrn1; //Daily demand:Rookier+shift t+night1 work
}
forall(d in Day, Night2 in A2)
{
sum(i in Ir) y2[i, d, "Night2"] == dtrn2; //Daily demand:Rookie+shift t+night2 work
}
forall(i in Is, d in Day:d<D, Evening in A1)
{
x1[i, d, "Evening"]+ x1[i,(d+1), "Day"]<=1; //(Senior)For shift type o,if previous day is evening
work, can't have day work the following day'
}
forall(i in Is, d in Day:d<D, Evening in A2)
{
x2[i, d, "Evening"]+ x2[i,(d+1), "Day"]<=1; //(Senior)For shift type t,if previous day is evening
work, can't have day work the following day'
}
forall(i in Ir, d in Day:d<D, Evening in A1)
{
y1[i, d, "Evening"]+ y1[i,(d+1), "Day"]<=1; //(Rookie)For shift type o,if previous day is evening
work, can't have day work the following day'
}
forall(i in Ir, d in Day:d<D, Evening in A2)
{
y2[i, d, "Evening"]+ y2[i,(d+1), "Day"]<=1; //(Rookie)For shift type t,if previous day is evening
work, can't have day work the following day'
}
forall(i in Is, d in Day:d<D, Night in A1)
{
x1[i, d,"Night"]+ x1[i,(d+1),"Day"]<=1; //(Senior)For shift type o,if previous day is night work,
can't have day work the following day'
}
forall(i in Is, d in Day:d<D, Night1 in A2)
{
x2[i, d,"Night1"]+ x2[i,(d+1),"Day"]<=1; //(Senior)For shift type t,if previous day is night1 work,
can't have day work the following day'
}
forall(i in Is, d in Day:d<D, Night2 in A2)
{
x2[i, d,"Night2"]+ x2[i,(d+1),"Day"]<=1; //(Senior)For shift type t,if previous day is night2 work,
can't have day work the following day'
}
forall(i in Ir, d in Day:d<D, Night in A1)
{
y1[i, d,"Night"]+ y1[i,(d+1),"Day"]<=1; //(Rookie)For shift type o,if previous day is night work,
can't have day work the following day'
}
forall(i in Ir, d in Day:d<D, Night1 in A2)
{
y2[i, d,"Night1"]+ y2[i,(d+1),"Day"]<=1; //(Rookie)For shift type t,if previous day is night1 work,
can't have day work the following day'
}
forall(i in Ir, d in Day:d<D, Night2 in A2)
{
y2[i, d,"Night2"]+ y2[i,(d+1),"Day"]<=1; //(Rookie)For shift type t,if previous day is night2 work,
can't have day work the following day'
}
forall (i in Is, d in Day)
{
sum(a in A1)x1[i,d,a] + sum(a in A2)x2[i,d,a] <=1; //(Senior)each day can only have one work with
one shift
}
forall (i in Ir, d in Day)
{
sum(a in A1)y1[i,d,a] + sum(a in A2)y2[i,d,a] <=1; //(Rookie)each day can only have one work with
one shift
}
forall(i in Is, a in A1)
{
sum(d in Day)x1[i,d,a] <=Pku; //(Senior) can’t have shift type o that more than upper bound. (in
days)
}
forall(i in Ir, a in A1)
{
sum(d in Day)y1[i,d,a] <=Pku; //(Rookie) can’t have shift type o that more than upper bound. (in
days)
}
forall(i in Is, a in A1)
{
sum(d in Day)x1[i,d,a]>=Pkd; //(Senior) can’t have shift type o that less than lower bound. (in
days)
}
forall(i in Ir, a in A1)
{
sum(d in Day)y1[i,d,a]>=Pkd; //(Rookie) can’t have shift type o that less than lower bound. (in
days)
}
forall(i in Is, a in A2)
{
sum(d in Day)x2[i,d,a]<=Pkuh; //(Senior) can’t have shift type t that more than upper bound. (in
days)
}
forall(i in Ir, a in A2)
{
sum(d in Day)y2[i,d,a]<=Pkuh; //(Rookie) can’t have shift type t that more than upper bound. (in
days)
}
forall(i in Is, a in A2)
{
sum(d in Day)x2[i,d,a]>=Pkdh; //(Senior) can’t have shift type t that less than lower bound. (in
days)
}
forall(i in Ir, a in A2)
{
sum(d in Day)y2[i,d,a]>=Pkdh; //(Rookie) can’t have shift type t that less than lower bound. (in
days)
}
forall(i in Is)
{
sum(d in Day:d<=(D-s), a in A1)x1[i,d,a]+sum(d in Day:d<=(D-s), a in A2)x2[i,d,a]<=s; //(Senior)
can’t have consecutive working days (regardless of shift type) that more than upper bound. (in days)
}
forall(i in Ir)
{
sum(d in Day:d<=(D-s), a in A1)y1[i,d,a]+sum(d in Day:d<=(D-s), a in A2)y2[i,d,a]<=s; //(Rookie)
can’t have consecutive working days (regardless of shift type) that more than upper bound. (in days)
}
++Data
E={"Senior","Rookie"};
I={"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","W","X","Y","Z"};
Is={"A","B","C","D","E","F","G","H"};
Ir={"I","J","K","L","M","N","O","P","Q","R","S","T","W","X","Y","Z"};
K={"o","t"};
A1={"Day","Evening","Night"};
A2={"Day","Evening","Night1","Night2"};
D=7;
Co=[1200,1150,1100,1050,1000,950,900,850];
Ct=[800,750,750,750,700,700,700,700,700,700,650,650,650,650,650,650];
Pku=10;
Pkd=5;
Pkuh=8;
Pkdh=4;
s=5;
Upvotes: 0
Views: 352
Reputation: 10037
Your model is probably not feasible. If you label your constraints then CPLEX will give you some relaxation and conflicts that will help you understand why. My suggestion is to label all your constraints.
For instance you can change
forall(d in Day, Day in A1)
{
sum(i in Is) x1[i, d ,"Day"] == dosd; //Daily demand:Senior+shift o+day work
}
into
forall(d in Day, Day in A1)
ct1:sum(i in Is) x1[i, d ,"Day"] == dosd; //Daily demand:Senior+shift o+day work
Upvotes: 1