public class SchedLocalSearch extends Object
Skill transfer can be enabled (by default) or disabled with
setAllowSkillTransfer(boolean)
.
If skill transfer is used, it can be set with setSkillTransferVariables(int[][][])
.
This local search optimization considers only the service level targets. This local search is not recommended if the call center problem has abandonment constraints.
The simulator is required to estimate these performance measures:
PerformanceMeasureType.SERVICELEVEL
,
PerformanceMeasureType.ABANDONMENTRATIO
,
PerformanceMeasureType.OCCUPANCY
,
PerformanceMeasureType.RATEOFARRIVALS
and
PerformanceMeasureType.SERVEDRATES
.
The user can set the cost per agent by specifying the cost premium for
each extra skill (above 1) using setSkillCost(double)
, or set to
a negative value in order to use the busy cost parameter of the agent group,
obtainable with AgentGroupManager.getBusyCost()
.
Modifier and Type | Class and Description |
---|---|
static class |
SchedLocalSearch.SimEvalResults
The simulation results returned by the method
simEvalStaffing(int[][]) . |
Constructor and Description |
---|
SchedLocalSearch(CallCenterParams ccp,
CallCenterSim sim,
PrintWriter log,
RepSimParams repsp,
RandomStream rand)
Constructs and initializes the local search optimizer.
|
SchedLocalSearch(CallCenterParams ccp,
CallCenterSim sim,
String folder,
RepSimParams repsp,
RandomStream rand)
Constructs and initializes the local search optimizer.
|
Modifier and Type | Method and Description |
---|---|
boolean |
getAllowSkillTransfer()
Determines if the skill transfer mechanism is allowed.
|
double |
getBestObjective()
Returns cost of the best scheduling solution.
|
int[][] |
getBestSchedules()
Returns the best scheduling solution found.
|
double |
getCost(int[][] scheduling)
Returns the cost of the given scheduling solution.
|
int[][][] |
getEffectiveSkillTransfers(int[][] scheduling)
Returns the effective skill transfered agents.
|
int |
getNumSimCall()
Returns the number of simulations done.
|
int[][] |
getSchedules()
Returns the number of agents working in each group and each shift.
|
double |
getSimTimeSec()
Returns the total simulation time in seconds.
|
double |
getSkillCost()
Returns the premium cost for each extra skill (above 1) of each agent.
|
int[][][] |
getSkillTransferVariable()
Returns the skill transfer variables.
|
int[][] |
getStaffing(int[][] scheduling)
Returns the staffing matrix corresponding to the scheduling matrix.
|
int[][] |
getStaffing(int[][] scheduling,
boolean applySkillTransfer)
Returns the staffing matrix corresponding to the scheduling matrix.
|
double |
getTotalTimeSec()
Returns the total execution time in seconds.
|
boolean |
getVerbose()
Returns the verbose value.
|
boolean |
isFeasible(DoubleMatrix2D sl)
Verifies if all the service levels satisfy their targets.
|
boolean |
isFeasible(DoubleMatrix2D sl,
double slack)
Verifies if all the service levels satisfy their targets.
|
void |
localSearch(int[][] startSolution,
int startRep,
int maxRep,
double incrRep,
int maxCPUSec)
Executes the local search.
|
static void |
main(String[] args)
Executes the local search as a stand-alone scheduling optimization program.
|
void |
optimize(int[][] startSolution,
int startRep,
int maxRep,
double incrRep,
int maxCPUSec)
Executes the
localSearch(int[][], int, int, double, int) as a stand-alone method. |
protected void |
printSchedule()
Prints only the current scheduling solution to the log file.
|
protected void |
printSolution()
Prints both the current scheduling and the staffing solutions to the log file.
|
void |
printSolution(boolean printSchedule,
boolean printStaffing)
Prints the solution in the
OUTPUT.txt file created in the folder passed to the
SchedLocalSearch(umontreal.iro.lecuyer.contactcenters.msk.params.CallCenterParams, umontreal.iro.lecuyer.contactcenters.msk.CallCenterSim, java.io.PrintWriter, umontreal.iro.lecuyer.contactcenters.app.params.RepSimParams, umontreal.iro.lecuyer.rng.RandomStream) . |
protected void |
printStaffing()
Prints only the current staffing solution (with skill transfers if used) to the log file.
|
void |
printViolatedSLConstraints(DoubleMatrix2D sl)
Prints the service level constraint violations,
and the service levels with their targets in the output file.
|
void |
printViolatedSLConstraints(DoubleMatrix2D sl,
boolean printAll)
Prints the service level constraint violations to the output file.
|
void |
setAllowSkillTransfer(boolean s)
Enables (
true ) or disables (code false) the skill transfer mechanism. |
void |
setSchedules(int[][] s)
Sets the scheduling solution, determining the number of agents working in each group
and each shift.
|
void |
setSkillCost(double c)
Sets the premium cost for each extra skill (above 1) of each agent.
|
void |
setSkillTransferVariables(int[][][] z)
Sets the skill transfer variables.
|
void |
setVerbose(boolean v)
Sets the verbose parameter.
|
SchedLocalSearch.SimEvalResults |
simEvalStaffing(int[][] y)
Simulates the given staffing solution.
|
public SchedLocalSearch(CallCenterParams ccp, CallCenterSim sim, String folder, RepSimParams repsp, RandomStream rand)
ccp
- the call center parameterssim
- the call center simulatorfolder
- the folder where to write the output file. The name of the output file is LocalSearch.txt
.repsp
- the parameter file of the simulatorrand
- the random stream to be used by the local searchpublic SchedLocalSearch(CallCenterParams ccp, CallCenterSim sim, PrintWriter log, RepSimParams repsp, RandomStream rand)
ccp
- the call center parametersim
- the call center simulatorlog
- the output loggerrepsp
- the parameter file of the simulatorrand
- the random stream to be used by the local searchpublic SchedLocalSearch.SimEvalResults simEvalStaffing(int[][] y)
y
- the staffing matrix where element y[s][p]
represents the
number of agents of group s
working in period p
.public void optimize(int[][] startSolution, int startRep, int maxRep, double incrRep, int maxCPUSec)
localSearch(int[][], int, int, double, int)
as a stand-alone method. If the user wants to
use the local search as part of another algorithm
(like after the cutting-plane algorithm), then he should call directly localSearch(int[][], int, int, double, int)
.startSolution
- the starting scheduling solution. If null
,
then the algorithm will start with the current
scheduling solution (which can be set with setSchedules(int[][])
).startRep
- the starting simulation replication lengthmaxRep
- the maximum number of replications per simulation.
Feasibility of final solution is also estimated with this value.incrRep
- the percentage increase relative to the value of startRep
at each iterationmaxCPUSec
- maximum allocated time in seconds for the entire local searchpublic void localSearch(int[][] startSolution, int startRep, int maxRep, double incrRep, int maxCPUSec)
startRep
replications.
The solution is tested with a simulator with length maxRep
replications.
If the solution is not feasible,
then the simulation length is increased by a amount of incrRep
times startRep
,
and the local search repeats with longer simulations.
The local search will stop after optimizing with maxRep
replication length
or if the execution time exceeds maxCPUsec
.startSolution
- the starting scheduling solution, if null
the algorithm will start with the current
scheduling solution (which can be set with setSchedules(int[][])
)startRep
- the starting simulation replication lengthmaxRep
- the maximum simulation replication length. Feasibility of
final solution is also evaluated with this simulation length.incrRep
- the percentage increase relative to the value of startRep
after each full iteration
of the local searchmaxCPUSec
- maximum allocated time in seconds for the entire local searchpublic double getCost(int[][] scheduling)
scheduling
- the scheduling matrix, with indices [group][shift]
public boolean isFeasible(DoubleMatrix2D sl)
sl
- the service level PerformanceMeasureType.SERVICELEVEL
public boolean isFeasible(DoubleMatrix2D sl, double slack)
slack
to 0 to use the original targets.
Service level target with value 0 are omitted (they are not affected by the slack parameter).sl
- the service level PerformanceMeasureType.SERVICELEVEL
slack
- the value to add to the SL target when testing the feasibility of the solutionpublic int[][] getStaffing(int[][] scheduling)
scheduling
- the schedules matrix with indices [group][shift]
[group][period]
, and
skill transfers are applied if usedpublic int[][] getStaffing(int[][] scheduling, boolean applySkillTransfer)
scheduling
- the schedules matrix with indices [group][shift]
applySkillTransfer
- to apply the skill transfers or not[group][period]
public int[][][] getEffectiveSkillTransfers(int[][] scheduling)
setSkillTransferVariables(int[][][])
because of the local search.scheduling
- the scheduling solution to compute the effective number of skill transfers, with
indices [group][shift]
[period][orig group][dest group]
or null
if skill transfers are not allowedpublic int[][] getSchedules()
[group][shift]
public void setSchedules(int[][] s)
s
- the new current scheduling solution, with indices [group][shift]
public int[][][] getSkillTransferVariable()
[p][i][j]
represents the number of agents from group i
that are transfered to group j
in period p
.
There are no negative transfer values, for example if z[p][1][2] = 1
, then
z[p][2][1] = 0
and not -1.[period][orig group][dest group]
public void setSkillTransferVariables(int[][][] z)
[p][i][j]
represents the number of agents from group i
that are transfered to group j
in period p
.
There are no negative transfer values, for example if z[p][1][2] = 1
, then
z[p][2][1] = 0
and not -1.z
- the skill transfer variables with indices [period][orig group][dest group]
public void printViolatedSLConstraints(DoubleMatrix2D sl)
printViolatedSLConstraints(DoubleMatrix2D,boolean)
with argument true
to printAll
.sl
- the service level PerformanceMeasureType.SERVICELEVEL
public void printViolatedSLConstraints(DoubleMatrix2D sl, boolean printAll)
printAll
is false
, then the method only prints
the violated constraints. If that parameter is true
, then it prints also all the
service levels and their targets.sl
- the service target matrixpublic int[][] getBestSchedules()
[group][shift]
public double getBestObjective()
protected void printSolution()
boolean)
.protected void printSchedule()
boolean)
.protected void printStaffing()
boolean)
.public void printSolution(boolean printSchedule, boolean printStaffing)
OUTPUT.txt
file created in the folder passed to the
SchedLocalSearch(umontreal.iro.lecuyer.contactcenters.msk.params.CallCenterParams, umontreal.iro.lecuyer.contactcenters.msk.CallCenterSim, java.io.PrintWriter, umontreal.iro.lecuyer.contactcenters.app.params.RepSimParams, umontreal.iro.lecuyer.rng.RandomStream)
.printSchedule
- print the current scheduling solutionprintStaffing
- print the current staffing solutionpublic boolean getVerbose()
public void setVerbose(boolean v)
true
, then the algorithm
will print in some optimization information to the screen during its execution.v
- the verbose valuepublic boolean getAllowSkillTransfer()
public void setAllowSkillTransfer(boolean s)
true
) or disables (code false) the skill transfer mechanism.s
- to allow or disallow skill transferspublic double getSkillCost()
public void setSkillCost(double c)
c
negative to use the busy cost defined by
AgentGroupManager.getBusyCost()
.
Note that the real cost per agent is multiplied by its shift length, obtained with
boolean)
.
c
- the premium cost for each additional skill for each agentpublic int getNumSimCall()
public double getSimTimeSec()
public double getTotalTimeSec()
public static void main(String[] args) throws Exception
The required arguments are:
RepSimParams
: simulation parameters
setSkillCost(double)
.
In particular, if this value is negative, then it will use the busy cost parameter of the agent group;
see AgentGroupManager.getBusyCost()
.
int, int, double, int)
.
We set the starting replication length to 1/4 of this value.
Note: We do not recommend to use this local search as a stand-alone optimization, although we allow it. This is because the local search relies much on the simulated performance of the scheduling vector. Since the stand-alone optimization usually starts with a 0 scheduling solution, the lack of simulated data may decrease the efficacy of the local search procedure.
args
- see the descriptionException