ContactCenters
V. 0.9.9.

umontreal.iro.lecuyer.contactcenters.router
Class QueueRatioOverflowRouter

java.lang.Object
  extended by umontreal.iro.lecuyer.contactcenters.router.Router
      extended by umontreal.iro.lecuyer.contactcenters.router.QueueRatioOverflowRouter
All Implemented Interfaces:
NewContactListener

public class QueueRatioOverflowRouter
extends Router

This router sends new contacts to agent groups using a fixed list, but for each agent group, routing occurs conditional on the expected waiting time. More specifically, the router uses a K×I ranks matrix giving a rank $ \rTG$(k, i) for each contact type k and agent group i. The lower is this rank, the higher is the priority of assigning contacts of type k to agents in group i. If a rank is , the corresponding assignment is not allowed. The ranks matrix giving $ \rTG$(k, i) for all k and i is used to generate overflow lists defined as follows. For each contact type k, the router creates a list of agent groupsets sharing the same priority. The jth groupset for contact type k is denoted i(k, j) = {i = 0,…, I - 1 | $ \rTG$(k, i) = rk, j}. Here, rk, j1 < rk, j2 < ∞ for any j1 < j2. The overflow list for contact of type k is then i(k, 0), i(k, 1),… For example, suppose we have the following ranks matrix:

($\displaystyle \begin{array}{ccc}
1 & 1 & 2 \\
1 & \infty & 2 \\
\infty & 1 & \infty
\end{array}$)

The overflow list for contact type 0 is ((0, 1),(2)), while the overflow list for contact type 1 is ((0),(2)).

When a new contact of type k arrives, the router performs two phases to assign an agent group or waiting queues to the contact. Here, each waiting queue corresponds to a single agent group. The first phase tries to associate an agent groupset with the contact while the second phase, which occurs when the first phase fails, associates a waiting queue to the contact. The first phase checks every agent groupset i(k, j) sequentially, and stops as soon as a groupset containing a free agent is found. For each considered groupset, the router tests every agent group to determine if at least one agent is free. If a single agent is free, the contact is routed to that agent. If several agents of that groupset are free, the contact is routed to the agent with the longest idle time.

If no agent is available in the tested groupset, one or more waiting queues must be selected to add the contact to. A waiting queue i with size Qi(t) is associated with a single agent group, which has Ni(t) agents, where t is the current simulation time. The router considers waiting queues in the current groupset only, and selects a queue only if the queue ratio (Si(t) + 1)/Ni(t) is greater than the agent-group specific target. This queue ratio gives an estimate of the expected waiting time of the contact. Note that this estimate assumes that service times are exponential, and no abandonment is allowed. If no candidate waiting queue is available, e.g., all waiting queues in the groupset have a queue ratio greater than the target queue ratio, the router checks the next agent groupset.

If there are no more groupset, the router performs the second phase as follows. Since no groupset contains a free agent or waiting queue with a small enough queue ratio, the router checks every authorized waiting queue, i.e., each queue i for which $ \rTG$(k, i) < ∞, and selects the waiting queue with the smallest queue ratio. In this phase, the queue ratio is allowed to be greater than the target.

The queues the contact is sent to depend on two flags associated with this router: the copy and overflow modes. The copy mode determines if contacts can be queued to multiple agent groups. The overflow mode, which is used only when contacts can be added into multiple queues, can be set to transfer or promotion. In transfer mode, the contact moves from groupsets to groupsets. In promotion mode, a copy of the contact is left in every considered groupset.

More specifically, if queueing to multiple targets is disabled, the router always sends the contact to the queue with the smallest queue ratio among the considered candidates. In the first phase, these candidates are the queues in the current groupset with a queue ratio smaller than the target. In the second phase, this corresponds to all queues the contact is authorized in.

If contacts can be added to multiple queues, the overflow mode has the following effect. If candidates were found during the first phase, when checking agent groupset i(k, j), the contact is queued to all queues in that groupset when the overflow mode is transfer. However, if the overflow mode is promotion, the contact is also added to all queues in the preceding groupsets, i.e., groupsets i(k, j') for j' = 0,…, j. If the router reaches the second phase, the contact is always sent to the queue with the smallest queue ratio. In promotion mode, it is also queued to all other authorized waiting queues.

This router needs agent groups taking individual agents into account to select agents based on their longest idle times.


Field Summary
 
Fields inherited from class umontreal.iro.lecuyer.contactcenters.router.Router
BLOCKTYPE_CANTQUEUE, BLOCKTYPE_NOLINE, BLOCKTYPE_QUEUEFULL, DEQUEUETYPE_BEGINSERVICE, DEQUEUETYPE_FANTOM, DEQUEUETYPE_NOAGENT, DEQUEUETYPE_TRANSFER, dqTypeRet
 
Constructor Summary
QueueRatioOverflowRouter(int numGroups, double[][] ranksTG, double[] targetQueueRatio, boolean allowCopies, boolean overflowTransfer)
          Constructs a new queue-ratio overflow router with ranks matrix ranksTG, numGroups agent groups, and target queue ratio for contact type k set to targetQueueRatio[k].
 
Method Summary
 boolean canServe(int i, int k)
          Returns true if and only if some agents in group i are authorized to serve contacts of type k by this router.
protected  void checkWaitingQueues(AgentGroup group)
          This method is called when the agent group group contains no more online agents, i.e., AgentGroup.getNumAgents() returns 0.
protected  void dequeued(DequeueEvent ev)
          This method is called when a contact leaves a waiting queue, ev representing the corresponding dequeue event.
 String getDescription()
           
 double[][] getRanksTG()
          Returns the ranks matrix defining how contacts prefer agents, used for agent selection.
 double[] getTargetQueueRatio()
          Gets the target queue ratio for each contact type.
 WaitingQueueType getWaitingQueueType()
          Returns an indicator describing how the implemented routing policies organizes waiting queues.
 boolean isAllowCopies()
          Determines if contacts can be added to multiple queues.
 boolean isOverflowTransfer()
          Determines if the overflow mode is transfer.
protected  EndServiceEvent selectAgent(Contact contact)
          Begins the service of the contact contact by trying to assign it a free agent.
protected  DequeueEvent selectContact(AgentGroup group, Agent agent)
          Returns a dequeue event representing a queued contact to be served by the agent agent in agent group group.
protected  DequeueEvent selectWaitingQueue(Contact contact)
          Selects a waiting queue and puts the contact contact into it.
 void setAllowCopies(boolean allowCopies)
          Sets the allow-copies flag to allowCopies.
 void setOverflowTransfer(boolean overflowTransfer)
          Sets the overflow mode to overflowTransfer.
 void setRanksTG(double[][] ranksTG)
          Sets the ranks matrix defining how contacts prefer agents to ranksTG.
 void setTargetQueueRatio(double[] targetQueueRatio)
          Sets the target queue ratio for each contact type to targetQueueRAtio.
 String toLongString()
          Returns a string representation of detailed information about the router.
 
Methods inherited from class umontreal.iro.lecuyer.contactcenters.router.Router
addExitedContactListener, agentReroutingEventsIterator, beginService, checkFreeAgents, clearExitedContactListeners, contactReroutingEventsIterator, endContact, endService, enqueued, exitBlocked, exitDequeued, exitServed, formatAgentGroups, formatWaitingQueues, getAgentGroup, getAgentGroupListener, getAgentGroups, getAgentReroutingEvents, getContactFactory, getContactReroutingEvents, getCurrentQueueSize, getDialers, getExitedContactListeners, getNeededWaitingQueueComparator, getNeededWaitingQueueStructure, getNumAgentGroups, getNumContactTypes, getNumWaitingQueues, getReroutingDelay, getReroutingDelay, getTotalQueueCapacity, getWaitingQueue, getWaitingQueueListener, getWaitingQueues, init, isKeepingReroutingEvents, mustClearWaitingQueue, needsDetailedAgentGroup, newContact, notifyBlocked, notifyDequeued, notifyServed, removeExitedContactListener, restore, save, selectAgent, selectContact, selectWaitingQueue, setAgentGroup, setClearWaitingQueue, setClearWaitingQueues, setContactFactory, setKeepingReroutingEvents, setTotalQueueCapacity, setWaitingQueue, startDialers, toString
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

QueueRatioOverflowRouter

public QueueRatioOverflowRouter(int numGroups,
                                double[][] ranksTG,
                                double[] targetQueueRatio,
                                boolean allowCopies,
                                boolean overflowTransfer)
Constructs a new queue-ratio overflow router with ranks matrix ranksTG, numGroups agent groups, and target queue ratio for contact type k set to targetQueueRatio[k]. The allowCopies flag determines if contacts can be added to multiple waiting queues, while the overflowTransfer flag determines if the transfer overflow mode is active. If this latter flag is false, overflow mode is set to promotion. The second flag has no effect if the first flag is false.

Parameters:
numGroups - the number of agent groups.
ranksTG - the ranks matrix.
targetQueueRatio - the target queue ratio for each contact type.
allowCopies - the allow-copies flag.
overflowTransfer - the overflow-transfer flag.
Throws:
NullPointerException - if any argument is null.
IllegalArgumentException - if the length of targetQueueRatio does not correspond to the number of rows in the ranks matrix.
Method Detail

getRanksTG

public double[][] getRanksTG()
Returns the ranks matrix defining how contacts prefer agents, used for agent selection.

Returns:
the ranks matrix defining how contacts prefer agents.

setRanksTG

public void setRanksTG(double[][] ranksTG)
Sets the ranks matrix defining how contacts prefer agents to ranksTG.

Parameters:
ranksTG - the new agent selection ranks matrix.
Throws:
NullPointerException - if ranksTG is null.
IllegalArgumentException - if ranksTG is not rectangular or has wrong dimensions.

isAllowCopies

public boolean isAllowCopies()
Determines if contacts can be added to multiple queues.

Returns:
true if and only if contacts can be added to multiple queues.

setAllowCopies

public void setAllowCopies(boolean allowCopies)
Sets the allow-copies flag to allowCopies.

Parameters:
allowCopies - the new value of the flag.
See Also:
isAllowCopies()

isOverflowTransfer

public boolean isOverflowTransfer()
Determines if the overflow mode is transfer.

Returns:
true if the overflow mode is transfer.

setOverflowTransfer

public void setOverflowTransfer(boolean overflowTransfer)
Sets the overflow mode to overflowTransfer.

Parameters:
overflowTransfer - the new overflow mode.
See Also:
isOverflowTransfer()

getTargetQueueRatio

public double[] getTargetQueueRatio()
Gets the target queue ratio for each contact type.

Returns:
the target queue ratios.

setTargetQueueRatio

public void setTargetQueueRatio(double[] targetQueueRatio)
Sets the target queue ratio for each contact type to targetQueueRAtio.

Parameters:
targetQueueRatio - the new target queue ratios.
Throws:
IllegalArgumentException - if the length of targetQueueRatio does not correspond to the number of rows in the ranks matrix.

getWaitingQueueType

public WaitingQueueType getWaitingQueueType()
Description copied from class: Router
Returns an indicator describing how the implemented routing policies organizes waiting queues. The supported modes of organization cover the most common cases only: waiting queues corresponding to contact types or agent groups. For any other modes, the WaitingQueueType.GENERAL must be used.

By default, this method returns WaitingQueueType.GENERAL.

Overrides:
getWaitingQueueType in class Router
Returns:
the organization mode of waiting queues.

checkWaitingQueues

protected void checkWaitingQueues(AgentGroup group)
Description copied from class: Router
This method is called when the agent group group contains no more online agents, i.e., AgentGroup.getNumAgents() returns 0. It must check each waiting queue accessible for agents in this group to determine if they need to be cleared. A queue is cleared if no agent, whether free or busy, is available to serve any contact in it.

Specified by:
checkWaitingQueues in class Router
Parameters:
group - the agent group with no more agents.

canServe

public boolean canServe(int i,
                        int k)
Description copied from class: Router
Returns true if and only if some agents in group i are authorized to serve contacts of type k by this router.

Specified by:
canServe in class Router
Parameters:
i - the agent group index.
k - the contact type index.
Returns:
determines if contacts can be served.

selectAgent

protected EndServiceEvent selectAgent(Contact contact)
Description copied from class: Router
Begins the service of the contact contact by trying to assign it a free agent. The method must select an agent group with a free agent (or a specific free agent), start the service, and return the end-service event if the service was started, or null otherwise.

Specified by:
selectAgent in class Router
Parameters:
contact - the contact being routed to an agent.
Returns:
the end-service event representing the started service, or null if the contact could not be served immediately.

selectWaitingQueue

protected DequeueEvent selectWaitingQueue(Contact contact)
Description copied from class: Router
Selects a waiting queue and puts the contact contact into it. Returns the dequeue event if the contact could be queued, or null otherwise.

Specified by:
selectWaitingQueue in class Router
Parameters:
contact - the contact being queued.
Returns:
the dequeue event representing the queued contact, or null if the contact could not be queued.

dequeued

protected void dequeued(DequeueEvent ev)
Description copied from class: Router
This method is called when a contact leaves a waiting queue, ev representing the corresponding dequeue event. By default, for any effective dequeue type other than 0, this calls Router.exitDequeued(DequeueEvent). This method should not notify an exiting contact for a 0 dequeue type since it is reserved for queued and served contacts.

Overrides:
dequeued in class Router
Parameters:
ev - the dequeue event.

selectContact

protected DequeueEvent selectContact(AgentGroup group,
                                     Agent agent)
Description copied from class: Router
Returns a dequeue event representing a queued contact to be served by the agent agent in agent group group. If agent is null, the method must return a contact that can be served by any agent in the group. If no contact is available, this method returns null. The selected contacts come from waiting queues attached to the router. Before the selected contact is returned, it must be removed from its queue with dequeue type Router.DEQUEUETYPE_BEGINSERVICE, e.g., by using queue.removeFirst (DEQUEUETYPE_BEGINSERVICE), or queue.remove (ev, DEQUEUETYPE_BEGINSERVICE), etc.

Generally, it is sufficient to override this method instead of Router.checkFreeAgents(AgentGroup,Agent). One can override Router.checkFreeAgents(AgentGroup,Agent) to improve efficiency when looking for contacts in the same waiting queue. This method is not abstract and returns null by default in order to allow Router.checkFreeAgents(AgentGroup,Agent) to be overridden without implementing this method.

Overrides:
selectContact in class Router
Parameters:
group - the affected agent group.
agent - the agent having ended its service.
Returns:
the dequeue event representing the contact being selected.

getDescription

public String getDescription()
Overrides:
getDescription in class Router

toLongString

public String toLongString()
Description copied from class: Router
Returns a string representation of detailed information about the router. This returns a string representation of each associated waiting queue and agent group and routing policies. For a short, one-line description, Router.toString() should be used.

Overrides:
toLongString in class Router
Returns:
a string representation of detailed information about the router.

ContactCenters
V. 0.9.9.

To submit a bug or ask questions, send an e-mail to Richard Simard.