ContactCenters
V. 0.9.9.

umontreal.iro.lecuyer.contactcenters.router
Class AgentsPrefRouter

java.lang.Object
  extended by umontreal.iro.lecuyer.contactcenters.router.Router
      extended by umontreal.iro.lecuyer.contactcenters.router.AgentsPrefRouter
All Implemented Interfaces:
NewContactListener
Direct Known Subclasses:
AgentsPrefRouterWithDelays, LocalSpecRouter

public class AgentsPrefRouter
extends Router

Performs agent and contact selection based on user-defined priorities. By default, this router selects the agent with the longest idle time when several agents share the same priority, and the longest waiting time to perform a selection among contacts sharing the same priority. The agents' preference-based router is a generalization of the router taken from [20], using matrices of ranks to take its decisions. The router applies static routing when the ranks are different and uses a dynamic policy when they are equal. This permits the user to partially define the priorities instead of assigning all of them as with the queue priority routing. For example, the user can set the router for the first waiting queue to have precedence over the others while the other queues share the same priority.

Data structures.

Two matrices of ranks can be defined, one specifying how contacts prefer agents, and a second one defining how agents prefer contacts. The former matrix, used for agent selection, defines a function $ \rTG$(k, i) giving the rank for contacts of type k served by agents in group i. The latter matrix, used for contact selection, defines a function $ \rGT$(i, k) giving the rank of contacts of type k when agents in group i perform contact selection. In many cases, one can specify $ \rGT$(i, k) only, and have $ \rTG$(k, i) = $ \rGT$(i, k).

Additionally, the router uses matrices of weights to adjust the priority for candidates with the same rank. These matrices define functions $ \wTG$(k, i) and $ \wGT$(i, k) which are similar to the ranks functions, except they can take any real number. These matrices are optional and default to matrices of 1's if they are not specified.

Basic routing schemes.

The priorities defined by matrices of ranks are used to assign agents to incoming contacts, and contacts to free agents by performing several linear searches over the space of agent groups or waiting queues. Each search constructs or narrows a list of candidates until zero or one candidate is retained. The general algorithm can be summarized as follows.
  1. Find a list of candidates sharing the lowest possible rank, or equivalently the highest possible priority;
  2. Assign a score to each selected candidate;
  3. Select the candidate with the best score.

Agent selection.

More specifically, when a new contact of type k arrives, the router constructs an initial list of agent groups for which $ \Nf$[i](t) > 0, and $ \rTG$(k, i) < ∞. If this list of candidates contains several agent groups, the router compares their ranks $ \rTG$(k, i), and retains the agent groups with the minimal rank. If more than one candidates share the same minimal rank, a score is assigned to each of them and the candidate with the best score is taken. The default score of an agent group i is the longest idle time of the agents in that group multiplied by the weight $ \wTG$(k, i) (which is 1 by default), also called the longest weighted idle time. For this reason, agent groups linked to this router must be able to take individual agents into account. In the rare event where two candidates share the best score, i.e., two agent groups have the same weighted longest idle time, the candidate with the smallest index i is retained. If, during the algorithm, the list of candidates happens to be empty, the routed contact is put into a waiting queue corresponding to its type, or blocked if the queue capacity is exceeded. If the list of candidates contains a single agent group, this agent group is selected and service starts.

Note that for a fixed contact type k, if $ \rTG$(k, i) is different for all i such that $ \rTG$(k, i) < ∞, the scheme for agent selection is equivalent to a pure overflow router: each agent group is tested in a fixed order for a free agent. In that setting, the weights $ \wTG$(k,⋅) have no effect. On the other hand, if all finite values of $ \rTG$(k, i) for a fixed k are equal, the routing is completely based on the longest-weighted-idle-time selection policy. Any intermediate combination of these two extremes can be achieved by adjusting the ranks appropriately.

Contact selection.

Since one waiting queue contains contacts of a single type, we define waiting queue k as the queue containing only contacts of type k. The router assumes that every waiting queue uses a FIFO discipline. When an agent in group i becomes free, an initial list of waiting queues containing at least one contact, and for which $ \rGT$(i, k) < ∞. If the list of candidates contains several waiting queues, the waiting queues k with the minimal rank are retained. If several waiting queues share this minimal rank, a score is assigned to each candidate, and the waiting queue with the best score is chosen. The default score of a waiting queue k is the weighted waiting time of the first queued contact, i.e., the waiting time multiplied by $ \wGT$(i, k). In the rare event where several waiting queues have the same minimal rank, and the same best score, i.e., several queued contacts have the exact same weighted waiting time, the waiting queue with the smallest index k is chosen. If, at any time during the algorithm, the list of candidates becomes empty, the tested agent remains free. When the list of candidates contains a single waiting queue, the first contact in that waiting queue is assigned to the free agent.

Note that for a fixed agent group i, if $ \rGT$(i, k) is different for all k such that $ \rGT$(i, k) < ∞, this policy is equivalent to the queue priority router's contact selection: the waiting queues are queried in a fixed order for contacts. In that particular setting, the weights $ \wGT$(i,⋅) have no effect. On the other hand, if, for a fixed i, all finite $ \rGT$(i, k) are equal for all k, the router uses the longest weighted waiting time policy for agent group i. As with agent selection, any combination of these two extremes can be achieved by adjusting the ranks.

Randomized selection.

By default, if several agent groups or waiting queues share the same minimal rank, a score is assigned to each of them, and the agent group or queue with the minimal score is chosen. However, this selection can be randomized as follows. Let Ci be the score given to agent group i during agent selection, any negative score excluding the concerned group being replaced with 0. When randomized agent selection is used, the agent group i is selected with probability pi = Ci/$ \htsum_{{i=0}}^{{I-1}}$Ci. In other words, the highest score an agent group obtains, the greatest is its probability of selection. A similar logic applies for contact selection, with Ci replaced by Ck, the score assigned to contact type k.


Field Summary
protected  Agent bestAgent
          Best agent selected by selectAgent(Contact,double,boolean[],int), or null if the best agent group does not take account of individual agents.
protected  AgentGroup bestGroup
          Best agent group selected by selectAgent(Contact,double,boolean[],int).
protected  WaitingQueue bestQueue
          Contains the best waiting queue selected by selectWaitingQueue(AgentGroup,Agent,double,boolean[],int).
protected  DequeueEvent bestQueuedContact
          Contains the best queued contact selected by selectWaitingQueue(AgentGroup,Agent,double,boolean[],int), or null if the first contact in the best queue is taken.
protected  double[][] ranksGT
           
protected  double[][] ranksTG
           
protected  double[][] weightsGT
           
protected  double[][] weightsTG
           
 
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
AgentsPrefRouter(double[][] ranksGT)
          Constructs a new agents' preference-based router with matrix of ranks ranksGT defining how agents prefer contacts.
AgentsPrefRouter(double[][] ranksTG, double[][] ranksGT)
          Constructs a new agents' preference-based router with matrix of ranks ranksTG defining how contacts prefer agents, and ranksGT defining how agents prefer contacts.
AgentsPrefRouter(double[][] ranksTG, double[][] ranksGT, double[][] weightsTG, double[][] weightsGT)
          Constructs a new agents' preference-based router with matrix of ranks ranksTG defining how contacts prefer agents, and ranksGT defining how agents prefer contacts.
AgentsPrefRouter(int numTypes, int[][] groupToTypeMap)
          Constructs a new agents' preference-based router with a group-to-type map groupToTypeMap and numTypes contact types.
 
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.
 AgentSelectionScore getAgentSelectionScore()
          Returns the current mode of computation for the agent selection score.
 ContactSelectionScore getContactSelectionScore()
          Returns the current mode of computation for the contact selection score.
 String getDescription()
           
 int[][] getGroupToTypeMap()
          Computes a group-to-type map from the contact selection matrix of ranks by calling RoutingTableUtils.getGroupToTypeMap(double[][]), and returns the result.
protected  double getRankForAgentSelection(int k, int i)
          Determines the rank to be used for agent selection for contact type k, and agent in group i.
protected  double getRankForContactSelection(int i, int k)
          Determines the rank to be used for contact selection for contact type k, when an agent in group i becomes free.
 double getRankGT(int i, int k)
          Returns the rank of contact type k = k for agent group i = i, used for contact selection.
 double[][] getRanksGT()
          Returns the matrix of ranks defining how agents prefer contacts, used for contact selection.
 double[][] getRanksTG()
          Returns the matrix of ranks defining how contacts prefer agents, used for agent selection.
 double getRankTG(int k, int i)
          Returns the rank of contact type k = k for agent group i = i, used for agent selection.
protected  double getScoreForAgentSelection(Contact ct, AgentGroup testGroup, Agent testAgent)
          Returns the score for contact ct associated with agent group testGroup and agent testAgent.
protected  double getScoreForContactSelection(AgentGroup group, DequeueEvent ev)
          Returns the score for the association between the agent group group and the queued contact represented by ev.
 RandomStream getStreamAgentSelection()
          Returns the random stream used for agent selection.
 RandomStream getStreamContactSelection()
          Returns the random stream used for contact selection.
 int[][] getTypeToGroupMap()
          Computes a type-to-group map from the agent selection matrix of ranks by calling RoutingTableUtils.getTypeToGroupMap(double[][]) on the transpose of the matrix of ranks, and returns the result.
 WaitingQueueType getWaitingQueueType()
          Returns an indicator describing how the implemented routing policies organizes waiting queues.
 double getWeightGT(int i, int k)
          Returns the weight of contact type k = k for agent group i = i, used for contact selection.
 double[][] getWeightsGT()
          Returns the matrix of weights defining $ \wGT$(i, k).
 double[][] getWeightsTG()
          Returns the matrix of weights defining $ \wTG$(k, i).
 double getWeightTG(int k, int i)
          Returns the weight of contact type k = k for agent group i = i, used for agent selection.
 boolean needsDetailedAgentGroup(int i)
          Determines if the agent group i should consider individual agents.
protected  EndServiceEvent selectAgent(Contact ct)
          Begins the service of the contact contact by trying to assign it a free agent.
protected  void selectAgent(Contact ct, double bestRank, boolean[] candidates1, int numCandidates)
          This method is called by selectAgent(Contact) to perform the selection of an agent among the numCandidates agent groups sharing the same minimal finite rank and containing at least one 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  void selectWaitingQueue(AgentGroup group, Agent agent, double bestRank, boolean[] qCandidates1, int numCandidates)
          Selects the queued contact for an agent agent in group group, with waiting queue candidates qCandidates.
protected  DequeueEvent selectWaitingQueue(Contact ct)
          Selects a waiting queue and puts the contact contact into it.
 void setAgentSelectionScore(AgentSelectionScore agentSelectionScore)
          Sets the way scores for agent selection are computed to agentSelectionScore.
 void setContactSelectionScore(ContactSelectionScore contactSelectionScore)
          Sets the way scores for contact selection are computed to contactSelectionScore.
 void setRanksGT(double[][] ranksGT)
          Sets the matrix of ranks defining how agents prefer contacts to ranksGT.
 void setRanksTG(double[][] ranksTG)
          Sets the matrix of ranks defining how contacts prefer agents to ranksTG.
 void setStreamAgentSelection(RandomStream streamAgentSelection)
          Sets the random stream for agent selection to streamAgentSelection.
 void setStreamContactSelection(RandomStream streamContactSelection)
          Sets the random stream for contact selection to streamContactSelection.
 void setWeightsGT(double[][] weightsGT)
          Sets the matrix of weights defining $ \wGT$(i, k) to weightsGT.
 void setWeightsTG(double[][] weightsTG)
          Sets the matrix of weights defining $ \wTG$(k, i) to weightsTG.
 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, dequeued, 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, 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
 

Field Detail

ranksTG

protected double[][] ranksTG

ranksGT

protected double[][] ranksGT

weightsTG

protected double[][] weightsTG

weightsGT

protected double[][] weightsGT

bestGroup

protected AgentGroup bestGroup
Best agent group selected by selectAgent(Contact,double,boolean[],int).


bestAgent

protected Agent bestAgent
Best agent selected by selectAgent(Contact,double,boolean[],int), or null if the best agent group does not take account of individual agents.


bestQueue

protected WaitingQueue bestQueue
Contains the best waiting queue selected by selectWaitingQueue(AgentGroup,Agent,double,boolean[],int).


bestQueuedContact

protected DequeueEvent bestQueuedContact
Contains the best queued contact selected by selectWaitingQueue(AgentGroup,Agent,double,boolean[],int), or null if the first contact in the best queue is taken.

Constructor Detail

AgentsPrefRouter

public AgentsPrefRouter(int numTypes,
                        int[][] groupToTypeMap)
Constructs a new agents' preference-based router with a group-to-type map groupToTypeMap and numTypes contact types. This router always uses queue priority for contact selection. The rank $ \rGT$(i, k) is the value j for which ki, j = k in the group-to-type map, and $ \rTG$(k, i) = $ \rGT$(i, k). The matrices of weights are initialized with 1's.

Parameters:
numTypes - the number of contact types.
groupToTypeMap - the group-to-type map.

AgentsPrefRouter

public AgentsPrefRouter(double[][] ranksGT)
Constructs a new agents' preference-based router with matrix of ranks ranksGT defining how agents prefer contacts. The given matrix must be rectangular with one row per agent group, and one column per contact type. It defines the function $ \rGT$(i, k) while $ \rTG$(k, i) = $ \rGT$(i, k). The matrices of weights are initialized with 1's.

Parameters:
ranksGT - the contact selection matrix of ranks being used.
Throws:
NullPointerException - if ranksGT is null.
IllegalArgumentException - if the ranks 2D array is not rectangular.

AgentsPrefRouter

public AgentsPrefRouter(double[][] ranksTG,
                        double[][] ranksGT)
Constructs a new agents' preference-based router with matrix of ranks ranksTG defining how contacts prefer agents, and ranksGT defining how agents prefer contacts. The given matrices must be rectangular. The matrices of weights are initialized with 1's.

Parameters:
ranksTG - the matrix of ranks defining how contacts prefer agents.
ranksGT - the matrix of ranks defining how agents prefer contacts.
Throws:
NullPointerException - if ranksGT or ranksTG are null.
IllegalArgumentException - if the ranks 2D arrays are not rectangular.

AgentsPrefRouter

public AgentsPrefRouter(double[][] ranksTG,
                        double[][] ranksGT,
                        double[][] weightsTG,
                        double[][] weightsGT)
Constructs a new agents' preference-based router with matrix of ranks ranksTG defining how contacts prefer agents, and ranksGT defining how agents prefer contacts. The matrices of weights are set to weightsTG, and weightsGT. The given matrices must be rectangular.

Parameters:
ranksTG - the matrix of ranks defining how contacts prefer agents.
ranksGT - the matrix of ranks defining how agents prefer contacts.
weightsTG - the matrix of weights defining $ \wTG$(k, i).
weightsGT - the matrix of weights defining $ \wGT$(i, k).
Throws:
NullPointerException - if ranksGT, ranksTG, weightsTG, or weightsGT are null.
IllegalArgumentException - if the 2D arrays are not rectangular.
Method Detail

getRanksTG

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

Returns:
the matrix of ranks defining how contacts prefer agents.

setRanksTG

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

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

getRanksGT

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

Returns:
the matrix of ranks defining how agents prefer contacts.

setRanksGT

public void setRanksGT(double[][] ranksGT)
Sets the matrix of ranks defining how agents prefer contacts to ranksGT.

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

getWeightsTG

public double[][] getWeightsTG()
Returns the matrix of weights defining $ \wTG$(k, i).

Returns:
the matrix of weights defining $ \wTG$(k, i).

setWeightsTG

public void setWeightsTG(double[][] weightsTG)
Sets the matrix of weights defining $ \wTG$(k, i) to weightsTG.

Parameters:
weightsTG - the new matrix of weights defining $ \wTG$(k, i).
Throws:
NullPointerException - if weightsTG is null.
IllegalArgumentException - if weightsTG is not rectangular or has wrong dimensions.

getWeightsGT

public double[][] getWeightsGT()
Returns the matrix of weights defining $ \wGT$(i, k).

Returns:
the matrix of weights defining $ \wGT$(i, k).

setWeightsGT

public void setWeightsGT(double[][] weightsGT)
Sets the matrix of weights defining $ \wGT$(i, k) to weightsGT.

Parameters:
weightsGT - the new matrix of weights defining $ \wGT$(i, k).
Throws:
NullPointerException - if weightsGT is null.
IllegalArgumentException - if weightsGT is not rectangular or has wrong dimensions.

getRankTG

public double getRankTG(int k,
                        int i)
Returns the rank of contact type k = k for agent group i = i, used for agent selection.

Parameters:
k - the contact type identifier.
i - the agent group identifier.
Returns:
the rank of the contact type for the agent group.
Throws:
ArrayIndexOutOfBoundsException - if i or k are negative, i is greater than or equal to Router.getNumAgentGroups(), or k is greater than or equal to Router.getNumContactTypes().

getRankGT

public double getRankGT(int i,
                        int k)
Returns the rank of contact type k = k for agent group i = i, used for contact selection.

Parameters:
i - the agent group identifier.
k - the contact type identifier.
Returns:
the rank of the contact type for the agent group.
Throws:
ArrayIndexOutOfBoundsException - if i or k are negative, i is greater than or equal to Router.getNumAgentGroups(), or k is greater than or equal to Router.getNumContactTypes().

getWeightTG

public double getWeightTG(int k,
                          int i)
Returns the weight of contact type k = k for agent group i = i, used for agent selection.

Parameters:
k - the contact type identifier.
i - the agent group identifier.
Returns:
the weight of the contact type for the agent group.
Throws:
ArrayIndexOutOfBoundsException - if i or k are negative, i is greater than or equal to Router.getNumAgentGroups(), or k is greater than or equal to Router.getNumContactTypes().

getWeightGT

public double getWeightGT(int i,
                          int k)
Returns the weight of contact type k = k for agent group i = i, used for contact selection.

Parameters:
i - the agent group identifier.
k - the contact type identifier.
Returns:
the weight of the contact type for the agent group.
Throws:
ArrayIndexOutOfBoundsException - if i or k are negative, i is greater than or equal to Router.getNumAgentGroups(), or k is greater than or equal to Router.getNumContactTypes().

getTypeToGroupMap

public int[][] getTypeToGroupMap()
Computes a type-to-group map from the agent selection matrix of ranks by calling RoutingTableUtils.getTypeToGroupMap(double[][]) on the transpose of the matrix of ranks, and returns the result.

Returns:
the computed type-to-group map.

getGroupToTypeMap

public int[][] getGroupToTypeMap()
Computes a group-to-type map from the contact selection matrix of ranks by calling RoutingTableUtils.getGroupToTypeMap(double[][]), and returns the result.

Returns:
the computed group-to-type map.

getStreamAgentSelection

public RandomStream getStreamAgentSelection()
Returns the random stream used for agent selection. If the agent selection is not randomized (the default), this returns null.

Returns:
the random stream for agent selection.

setStreamAgentSelection

public void setStreamAgentSelection(RandomStream streamAgentSelection)
Sets the random stream for agent selection to streamAgentSelection. Setting the stream to null disables randomized agent selection.

Parameters:
streamAgentSelection - the new random stream for agent selection.

getStreamContactSelection

public RandomStream getStreamContactSelection()
Returns the random stream used for contact selection. If the contact selection is not randomized (the default), this returns null.

Returns:
the random stream for contact selection.

setStreamContactSelection

public void setStreamContactSelection(RandomStream streamContactSelection)
Sets the random stream for contact selection to streamContactSelection. Setting the stream to null disables randomized contact selection.

Parameters:
streamContactSelection - the new random stream for contact selection.

getAgentSelectionScore

public AgentSelectionScore getAgentSelectionScore()
Returns the current mode of computation for the agent selection score. The default value is AgentSelectionScore.LONGESTIDLETIME.

Returns:
the way the score is computed for agent selection.

setAgentSelectionScore

public void setAgentSelectionScore(AgentSelectionScore agentSelectionScore)
Sets the way scores for agent selection are computed to agentSelectionScore.

Parameters:
agentSelectionScore - the way scores for agent selection are computed.
Throws:
NullPointerException - if agentSelectionScore is null.

getContactSelectionScore

public ContactSelectionScore getContactSelectionScore()
Returns the current mode of computation for the contact selection score. The default value is ContactSelectionScore.LONGESTWAITINGTIME.

Returns:
the way the score is computed for contact selection.

setContactSelectionScore

public void setContactSelectionScore(ContactSelectionScore contactSelectionScore)
Sets the way scores for contact selection are computed to contactSelectionScore.

Parameters:
contactSelectionScore - the way scores for contact selection are computed.
Throws:
NullPointerException - if contactSelectionScore is null.

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.

needsDetailedAgentGroup

public boolean needsDetailedAgentGroup(int i)
Description copied from class: Router
Determines if the agent group i should consider individual agents. This does not determine directly how the agent group returned by Router.getAgentGroup(int) is implemented. This method only gives clues to a simulator on how to construct the concerned agent group.

Overrides:
needsDetailedAgentGroup in class Router
Parameters:
i - the index of the agent group.
Returns:
the detailed status of the agent group.

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.

getRankForAgentSelection

protected double getRankForAgentSelection(int k,
                                          int i)
Determines the rank to be used for agent selection for contact type k, and agent in group i. By default, this returns $ \rTG$(k, i), but subclasses may override this method for the rank to depend on some state of the system.

Parameters:
k - the contact type index.
i - the agent group index.
Returns:
the rank associated with (k, i).

selectAgent

protected EndServiceEvent selectAgent(Contact ct)
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:
ct - 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.

selectAgent

protected void selectAgent(Contact ct,
                           double bestRank,
                           boolean[] candidates1,
                           int numCandidates)
This method is called by selectAgent(Contact) to perform the selection of an agent among the numCandidates agent groups sharing the same minimal finite rank and containing at least one free agent. The method must select an agent group i among the agent groups for which candidates[i] is true and store the reference to this group in the protected field bestGroup. The field bestAgent can be used to hold the selected agent if the agent group takes account of individual agents. If no candidate is satisfactory, the method must set bestGroup and bestAgent to null before returning; the incoming contact will be queued or blocked as appropriate.

The default implementation computes a score for each candidate using getScoreForAgentSelection(Contact,AgentGroup,Agent) and takes the candidate with the best score. This method can be overridden to implement a different selection scheme, e.g., randomly selecting a free agent.

Parameters:
ct - the contact being processed.
bestRank - the best rank found when looking for a candidate agent.
candidates1 - the agent group that could serve the contact.
numCandidates - the number of true values in candidates.

getScoreForAgentSelection

protected double getScoreForAgentSelection(Contact ct,
                                           AgentGroup testGroup,
                                           Agent testAgent)
Returns the score for contact ct associated with agent group testGroup and agent testAgent. When selecting an agent for contact ct, if there are several agent groups with the same minimal rank, the agent group with the greatest score is selected. Returning a negative infinite score prevents an agent group from being selected. The default selectAgent(Contact,double,boolean[],int) method calls this method with testAgent = null if testGroup is not an instance of DetailedAgentGroup, otherwise the method is called with testAgent = testGroup.getLongestIdleAgent().

By default, this returns a score depending on the return value of getAgentSelectionScore(). This can return the longest weighted idle time (the default), the weighted number of free agents, or the weight only. See AgentSelectionScore for more information.

Parameters:
ct - the contact being assigned an agent.
testGroup - the tested agent group.
testAgent - the tested agent, can be null.
Returns:
the score given to the association between the contact and the agent.

selectWaitingQueue

protected DequeueEvent selectWaitingQueue(Contact ct)
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:
ct - the contact being queued.
Returns:
the dequeue event representing the queued contact, or null if the contact could not be queued.

getRankForContactSelection

protected double getRankForContactSelection(int i,
                                            int k)
Determines the rank to be used for contact selection for contact type k, when an agent in group i becomes free. By default, this returns $ \rGT$(i, k), but subclasses may override this method for the rank to depend on some state of the system.

Parameters:
i - the agent group index.
k - the contact type index.
Returns:
the rank associated with (i, k).

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.

selectWaitingQueue

protected void selectWaitingQueue(AgentGroup group,
                                  Agent agent,
                                  double bestRank,
                                  boolean[] qCandidates1,
                                  int numCandidates)
Selects the queued contact for an agent agent in group group, with waiting queue candidates qCandidates. The waiting queues k for which qCandidates[k] is true share the same minimal rank and contain at least one contact. The method must store the selected waiting queue in the field bestQueue and possibly the contact to be removed in the bestQueuedContact. If bestQueuedContact is null, the first contact in the best queue will be used. If no waiting queue can be selected, bestQueue must be set to null.

The default implementation selects the waiting queue with the greatest score as computed by getScoreForContactSelection(AgentGroup,DequeueEvent), and the best queued contact is always null. This method can be overridden to use an alternate selection scheme, e.g., randomly selecting a queued contact.

Parameters:
group - the agent group containing the free agent.
agent - the free agent.
bestRank - the best rank found when searching for candidates.
qCandidates1 - the waiting queue candidates contacts can be pulled from.

getScoreForContactSelection

protected double getScoreForContactSelection(AgentGroup group,
                                             DequeueEvent ev)
Returns the score for the association between the agent group group and the queued contact represented by ev. If contacts can be pulled from several waiting queues with the same minimal rank, the router takes the contact with the greatest score. A negative infinite score prevents a contact from being dequeued.

By default, this returns a score depending on the return value of getContactSelectionScore(). This can return the weighted waiting time (the default), the weighted number of queued agents, or the weight only. See ContactSelectionScore for more information.

Parameters:
group - the agent group to which pulled contacts would be assigned.
ev - the dequeue event.
Returns:
the assigned score.

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.

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.