public class WhittWallaceStaffing extends WhittWallaceRoutingStaffing
WhittWallaceRoutingStaffing
,
the groups (skill sets) and routing are already defined and are invariable.
Groups can have one or multiple skills (instead of exactly 2 as with WhittWallaceRoutingStaffing
).
Another difference is that agents can have different staffing costs, and
the optimization moves depend on the agent costs.
Whenever the optimization removes an agent and there are multiple group candidates, it will
choose the most expensive agent.
Whenever the optimization needs to add an agent and there are multiple group candidates,
it will select the least expensive agent.
Similarly to WhittWallaceRoutingStaffing
, this algorithm requires a
simulator that uses BatchSimParams
.
The user may control the current period to optimize by changing BatchSimParams.setCurrentPeriod(int)
.
This implementation assumes a infinite trunk size, thus K = ∞.
WhittWallaceRoutingStaffing.MatrixRow, WhittWallaceRoutingStaffing.RoutingMatrix
Modifier and Type | Field and Description |
---|---|
protected double |
costPremium
The premium cost (per agent) for each additional skills above 1.
|
protected int |
I
The number of agent groups.
|
Constructor and Description |
---|
WhittWallaceStaffing(CallCenterParams ccParams,
BatchSimParams simParams,
double costPremium)
Constructs a new staffing optimizer for the given call center.
|
Modifier and Type | Method and Description |
---|---|
protected void |
constructInitialStaffing1Skill()
Constructs the initial staffing based on only the 1 skill.
|
protected void |
constructInitialStaffing2Skills()
Constructs the initial solution based on 2 skills, as described in Wallace and Whitt (2005).
|
protected int |
findBestRowToAdd()
Returns the best group to increment.
|
protected int |
findBestRowToRemove()
Finds the best group to decrement its staffing.
|
protected void |
findInitialFeasibleSolution()
Finds a feasible solution that satisfies all service level targets, based
on simulation.
|
double |
getStaffingCost()
Returns the total cost of the staffing solution.
|
double |
getStaffingCost(int[] staffing)
Returns the total cost of the given solution.
|
void |
improveSolution(int maxSwaps)
Improves the solution by removing agents, or by moving agents to different groups.
|
static void |
main(String[] args)
Executes the optimization.
|
void |
optimize(int maxSwaps)
Executes the optimization.
|
void |
optimize(int maxSwaps,
String outputFn)
Executes
WhittWallaceRoutingStaffing.optimize(int) , then WhittWallaceRoutingStaffing.writeResult(java.lang.String) to export
the solution to a new call center parameter file. |
void |
writeResult(String outputFileName)
Exports the optimization result to a new call center parameter file.
|
cleanGroupToTypeMap, constructInitialRoutingMatrix, findBestRowToAdd, getStaffingByErlang, isValidRow, roundValues, setGroupToTypeMap
protected double costPremium
protected int I
public WhittWallaceStaffing(CallCenterParams ccParams, BatchSimParams simParams, double costPremium)
ccParams
- the call center parameterssimParams
- the simulator parameterscostPremium
- the cost premium per agent for each skill above 1. If this
parameter is negative, then the cost per agent is taken from
AgentGroupManager.getBusyCost()
.protected void constructInitialStaffing2Skills()
protected void constructInitialStaffing1Skill()
protected int findBestRowToAdd()
-1
if feasibleprotected void findInitialFeasibleSolution()
findInitialFeasibleSolution
in class WhittWallaceRoutingStaffing
protected int findBestRowToRemove()
WhittWallaceRoutingStaffing.findBestRowToRemove()
,
but if there are multiple group candidates
it will choose the group that is the most expensive.findBestRowToRemove
in class WhittWallaceRoutingStaffing
-1
if no agent can be removedpublic void improveSolution(int maxSwaps)
WhittWallaceRoutingStaffing.improveSolution(int)
, but
whenever there are multiple group candidates, it will choose the most expensive agent
when removing an agent, and it will choose the least expensive agent when adding
a new agent. Remark that a swap operation is equivalent to removing an agent
and adding a new agent.improveSolution
in class WhittWallaceRoutingStaffing
maxSwaps
- the maximum number of skill set switches, at each iterationpublic double getStaffingCost()
public double getStaffingCost(int[] staffing)
staffing
- the staffing vectorpublic void writeResult(String outputFileName)
WhittWallaceRoutingStaffing
WhittWallaceRoutingStaffing.optimize(int)
should be called first.writeResult
in class WhittWallaceRoutingStaffing
outputFileName
- the filename of the output filepublic void optimize(int maxSwaps)
WhittWallaceRoutingStaffing
WhittWallaceRoutingStaffing.writeResult(java.lang.String)
to export the solution
after this method is finished.optimize
in class WhittWallaceRoutingStaffing
maxSwaps
- the maximum number of skill set swaps to make a solution
feasible, at each iteration of the optimization. See method WhittWallaceRoutingStaffing.improveSolution(int)
.public void optimize(int maxSwaps, String outputFn)
WhittWallaceRoutingStaffing
WhittWallaceRoutingStaffing.optimize(int)
, then WhittWallaceRoutingStaffing.writeResult(java.lang.String)
to export
the solution to a new call center parameter file.optimize
in class WhittWallaceRoutingStaffing
maxSwaps
- see the parameter of WhittWallaceRoutingStaffing.optimize(int)
outputFn
- the filename of the output file that will contain the solutionpublic static void main(String[] args) throws Exception
AgentGroupManager.getBusyCost()
.
args
- see descriptionException